source src/reflog.c
Line | Flow | Count | Block(s) | Source |
---|---|---|---|---|
1 | - | /* | ||
2 | - | * Copyright (C) the libgit2 contributors. All rights reserved. | ||
3 | - | * | ||
4 | - | * This file is part of libgit2, distributed under the GNU GPL v2 with | ||
5 | - | * a Linking Exception. For full terms see the included COPYING file. | ||
6 | - | */ | ||
7 | - | |||
8 | - | #include "reflog.h" | ||
9 | - | |||
10 | - | #include "repository.h" | ||
11 | - | #include "filebuf.h" | ||
12 | - | #include "signature.h" | ||
13 | - | #include "refdb.h" | ||
14 | - | |||
15 | - | #include "git2/sys/refdb_backend.h" | ||
16 | - | #include "git2/sys/reflog.h" | ||
17 | - | |||
18 | 752 | 2 | void git_reflog_entry__free(git_reflog_entry *entry) | |
19 | - | { | ||
20 | 752 | 2 | git_signature_free(entry->committer); | |
21 | - | |||
22 | 752 | 3 | git__free(entry->msg); | |
23 | 752 | 4 | git__free(entry); | |
24 | 752 | 5 | } | |
25 | - | |||
26 | 201 | 2 | void git_reflog_free(git_reflog *reflog) | |
27 | - | { | ||
28 | - | size_t i; | ||
29 | - | git_reflog_entry *entry; | ||
30 | - | |||
31 | 201 | 2 | if (reflog == NULL) | |
32 | 201 | 3,17 | return; | |
33 | - | |||
34 | 197 | 4 | if (reflog->db) | |
35 | 197 | 5-8 | GIT_REFCOUNT_DEC(reflog->db, git_refdb__free); | |
36 | - | |||
37 | 924 | 9,12,13 | for (i=0; i < reflog->entries.length; i++) { | |
38 | 727 | 10 | entry = git_vector_get(&reflog->entries, i); | |
39 | - | |||
40 | 727 | 11 | git_reflog_entry__free(entry); | |
41 | - | } | ||
42 | - | |||
43 | 197 | 14 | git_vector_free(&reflog->entries); | |
44 | 197 | 15 | git__free(reflog->ref_name); | |
45 | 197 | 16 | git__free(reflog); | |
46 | - | } | ||
47 | - | |||
48 | 197 | 2 | int git_reflog_read(git_reflog **reflog, git_repository *repo, const char *name) | |
49 | - | { | ||
50 | - | git_refdb *refdb; | ||
51 | - | int error; | ||
52 | - | |||
53 | 197 | 2-5 | assert(reflog && repo && name); | |
54 | - | |||
55 | 197 | 6,7 | if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0) | |
56 | ##### | 8 | return error; | |
57 | - | |||
58 | 197 | 9 | return git_refdb_reflog_read(reflog, refdb, name); | |
59 | - | } | ||
60 | - | |||
61 | 5 | 2 | int git_reflog_write(git_reflog *reflog) | |
62 | - | { | ||
63 | - | git_refdb *db; | ||
64 | - | |||
65 | 5 | 2-4 | assert(reflog && reflog->db); | |
66 | - | |||
67 | 5 | 5 | db = reflog->db; | |
68 | 5 | 5 | return db->backend->reflog_write(db->backend, reflog); | |
69 | - | } | ||
70 | - | |||
71 | 6 | 2 | int git_reflog_append(git_reflog *reflog, const git_oid *new_oid, const git_signature *committer, const char *msg) | |
72 | - | { | ||
73 | - | const git_reflog_entry *previous; | ||
74 | - | git_reflog_entry *entry; | ||
75 | - | |||
76 | 6 | 2-5 | assert(reflog && new_oid && committer); | |
77 | - | |||
78 | 6 | 6 | entry = git__calloc(1, sizeof(git_reflog_entry)); | |
79 | 6 | 7,8 | GIT_ERROR_CHECK_ALLOC(entry); | |
80 | - | |||
81 | 6 | 9,10 | if ((git_signature_dup(&entry->committer, committer)) < 0) | |
82 | ##### | 11 | goto cleanup; | |
83 | - | |||
84 | 6 | 12 | if (msg != NULL) { | |
85 | 5 | 13 | size_t i, msglen = strlen(msg); | |
86 | - | |||
87 | 5 | 13,14 | if ((entry->msg = git__strndup(msg, msglen)) == NULL) | |
88 | ##### | 15 | goto cleanup; | |
89 | - | |||
90 | - | /* | ||
91 | - | * Replace all newlines with spaces, except for | ||
92 | - | * the final trailing newline. | ||
93 | - | */ | ||
94 | 62 | 16,19,20 | for (i = 0; i < msglen; i++) | |
95 | 57 | 17 | if (entry->msg[i] == '\n') | |
96 | 2 | 18 | entry->msg[i] = ' '; | |
97 | - | } | ||
98 | - | |||
99 | 6 | 21 | previous = git_reflog_entry_byindex(reflog, 0); | |
100 | - | |||
101 | 6 | 22 | if (previous == NULL) | |
102 | 1 | 23 | git_oid_fromstr(&entry->oid_old, GIT_OID_HEX_ZERO); | |
103 | - | else | ||
104 | 5 | 24 | git_oid_cpy(&entry->oid_old, &previous->oid_cur); | |
105 | - | |||
106 | 6 | 25 | git_oid_cpy(&entry->oid_cur, new_oid); | |
107 | - | |||
108 | 6 | 26,27 | if (git_vector_insert(&reflog->entries, entry) < 0) | |
109 | ##### | 28 | goto cleanup; | |
110 | - | |||
111 | 6 | 29 | return 0; | |
112 | - | |||
113 | - | cleanup: | ||
114 | ##### | 30 | git_reflog_entry__free(entry); | |
115 | ##### | 31 | return -1; | |
116 | - | } | ||
117 | - | |||
118 | 1 | 2 | int git_reflog_rename(git_repository *repo, const char *old_name, const char *new_name) | |
119 | - | { | ||
120 | - | git_refdb *refdb; | ||
121 | - | int error; | ||
122 | - | |||
123 | 1 | 2,3 | if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0) | |
124 | ##### | 4 | return -1; | |
125 | - | |||
126 | 1 | 5 | return refdb->backend->reflog_rename(refdb->backend, old_name, new_name); | |
127 | - | } | ||
128 | - | |||
129 | ##### | 2 | int git_reflog_delete(git_repository *repo, const char *name) | |
130 | - | { | ||
131 | - | git_refdb *refdb; | ||
132 | - | int error; | ||
133 | - | |||
134 | ##### | 2,3 | if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0) | |
135 | ##### | 4 | return -1; | |
136 | - | |||
137 | ##### | 5 | return refdb->backend->reflog_delete(refdb->backend, name); | |
138 | - | } | ||
139 | - | |||
140 | 192 | 2 | size_t git_reflog_entrycount(git_reflog *reflog) | |
141 | - | { | ||
142 | 192 | 2,3 | assert(reflog); | |
143 | 192 | 4 | return reflog->entries.length; | |
144 | - | } | ||
145 | - | |||
146 | 205 | 2 | const git_reflog_entry * git_reflog_entry_byindex(const git_reflog *reflog, size_t idx) | |
147 | - | { | ||
148 | 205 | 2,3 | assert(reflog); | |
149 | - | |||
150 | 205 | 4 | if (idx >= reflog->entries.length) | |
151 | 2 | 5 | return NULL; | |
152 | - | |||
153 | 203 | 6 | return git_vector_get( | |
154 | - | &reflog->entries, reflog_inverse_index(idx, reflog->entries.length)); | ||
155 | - | } | ||
156 | - | |||
157 | 29 | 2 | const git_oid * git_reflog_entry_id_old(const git_reflog_entry *entry) | |
158 | - | { | ||
159 | 29 | 2,3 | assert(entry); | |
160 | 29 | 4 | return &entry->oid_old; | |
161 | - | } | ||
162 | - | |||
163 | 82 | 2 | const git_oid * git_reflog_entry_id_new(const git_reflog_entry *entry) | |
164 | - | { | ||
165 | 82 | 2,3 | assert(entry); | |
166 | 82 | 4 | return &entry->oid_cur; | |
167 | - | } | ||
168 | - | |||
169 | 33 | 2 | const git_signature * git_reflog_entry_committer(const git_reflog_entry *entry) | |
170 | - | { | ||
171 | 33 | 2,3 | assert(entry); | |
172 | 33 | 4 | return entry->committer; | |
173 | - | } | ||
174 | - | |||
175 | 96 | 2 | const char * git_reflog_entry_message(const git_reflog_entry *entry) | |
176 | - | { | ||
177 | 96 | 2,3 | assert(entry); | |
178 | 96 | 4 | return entry->msg; | |
179 | - | } | ||
180 | - | |||
181 | 25 | 2 | int git_reflog_drop(git_reflog *reflog, size_t idx, int rewrite_previous_entry) | |
182 | - | { | ||
183 | - | size_t entrycount; | ||
184 | - | git_reflog_entry *entry, *previous; | ||
185 | - | |||
186 | 25 | 2 | entrycount = git_reflog_entrycount(reflog); | |
187 | - | |||
188 | 25 | 3 | entry = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx); | |
189 | - | |||
190 | 25 | 4 | if (entry == NULL) { | |
191 | 1 | 5 | git_error_set(GIT_ERROR_REFERENCE, "no reflog entry at index %"PRIuZ, idx); | |
192 | 1 | 6 | return GIT_ENOTFOUND; | |
193 | - | } | ||
194 | - | |||
195 | 24 | 7 | git_reflog_entry__free(entry); | |
196 | - | |||
197 | 24 | 8-10 | if (git_vector_remove( | |
198 | - | &reflog->entries, reflog_inverse_index(idx, entrycount)) < 0) | ||
199 | ##### | 11 | return -1; | |
200 | - | |||
201 | 24 | 12 | if (!rewrite_previous_entry) | |
202 | 2 | 13 | return 0; | |
203 | - | |||
204 | - | /* No need to rewrite anything when removing the most recent entry */ | ||
205 | 22 | 14 | if (idx == 0) | |
206 | 17 | 15 | return 0; | |
207 | - | |||
208 | - | /* Have the latest entry just been dropped? */ | ||
209 | 5 | 16 | if (entrycount == 1) | |
210 | ##### | 17 | return 0; | |
211 | - | |||
212 | 5 | 18 | entry = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx - 1); | |
213 | - | |||
214 | - | /* If the oldest entry has just been removed... */ | ||
215 | 5 | 19 | if (idx == entrycount - 1) { | |
216 | - | /* ...clear the oid_old member of the "new" oldest entry */ | ||
217 | 3 | 20,21 | if (git_oid_fromstr(&entry->oid_old, GIT_OID_HEX_ZERO) < 0) | |
218 | ##### | 22 | return -1; | |
219 | - | |||
220 | 3 | 23 | return 0; | |
221 | - | } | ||
222 | - | |||
223 | 2 | 24 | previous = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx); | |
224 | 2 | 25 | git_oid_cpy(&entry->oid_old, &previous->oid_cur); | |
225 | - | |||
226 | 2 | 26 | return 0; | |
227 | - | } |