]>
Commit | Line | Data |
---|---|---|
27df4275 | 1 | /* |
359fc2d2 | 2 | * Copyright (C) the libgit2 contributors. All rights reserved. |
27df4275 | 3 | * |
bb742ede VM |
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. | |
27df4275 MS |
6 | */ |
7 | ||
8 | #include "reflog.h" | |
eae0bfdc | 9 | |
27df4275 MS |
10 | #include "repository.h" |
11 | #include "filebuf.h" | |
12 | #include "signature.h" | |
b976f3c2 | 13 | #include "refdb.h" |
27df4275 | 14 | |
b976f3c2 | 15 | #include <git2/sys/refdb_backend.h> |
27df4275 | 16 | |
b976f3c2 | 17 | git_reflog_entry *git_reflog_entry__alloc(void) |
27df4275 | 18 | { |
b976f3c2 | 19 | return git__calloc(1, sizeof(git_reflog_entry)); |
bd72425d | 20 | } |
27df4275 | 21 | |
b976f3c2 | 22 | void git_reflog_entry__free(git_reflog_entry *entry) |
40c75652 | 23 | { |
24 | git_signature_free(entry->committer); | |
97769280 | 25 | |
40c75652 | 26 | git__free(entry->msg); |
27 | git__free(entry); | |
27df4275 MS |
28 | } |
29 | ||
27df4275 MS |
30 | void git_reflog_free(git_reflog *reflog) |
31 | { | |
10c06114 | 32 | size_t i; |
27df4275 MS |
33 | git_reflog_entry *entry; |
34 | ||
d2aa6de7 | 35 | if (reflog == NULL) |
36 | return; | |
37 | ||
b976f3c2 CMN |
38 | if (reflog->db) |
39 | GIT_REFCOUNT_DEC(reflog->db, git_refdb__free); | |
40 | ||
27df4275 MS |
41 | for (i=0; i < reflog->entries.length; i++) { |
42 | entry = git_vector_get(&reflog->entries, i); | |
43 | ||
b976f3c2 | 44 | git_reflog_entry__free(entry); |
27df4275 MS |
45 | } |
46 | ||
47 | git_vector_free(&reflog->entries); | |
3286c408 VM |
48 | git__free(reflog->ref_name); |
49 | git__free(reflog); | |
27df4275 MS |
50 | } |
51 | ||
b976f3c2 | 52 | int git_reflog_read(git_reflog **reflog, git_repository *repo, const char *name) |
bd72425d | 53 | { |
b976f3c2 CMN |
54 | git_refdb *refdb; |
55 | int error; | |
bd72425d | 56 | |
b976f3c2 | 57 | assert(reflog && repo && name); |
27e3c583 | 58 | |
b976f3c2 | 59 | if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0) |
27e3c583 | 60 | return error; |
c3be5c5a | 61 | |
b976f3c2 | 62 | return git_refdb_reflog_read(reflog, refdb, name); |
27df4275 MS |
63 | } |
64 | ||
bd72425d | 65 | int git_reflog_write(git_reflog *reflog) |
66 | { | |
b976f3c2 | 67 | git_refdb *db; |
bd72425d | 68 | |
b976f3c2 | 69 | assert(reflog && reflog->db); |
bd72425d | 70 | |
b976f3c2 CMN |
71 | db = reflog->db; |
72 | return db->backend->reflog_write(db->backend, reflog); | |
bd72425d | 73 | } |
74 | ||
0174794a | 75 | int git_reflog_append(git_reflog *reflog, const git_oid *new_oid, const git_signature *committer, const char *msg) |
27df4275 | 76 | { |
0174794a CMN |
77 | git_reflog_entry *entry; |
78 | const git_reflog_entry *previous; | |
79 | const char *newline; | |
62dd6d16 | 80 | |
0174794a | 81 | assert(reflog && new_oid && committer); |
40c75652 | 82 | |
0174794a CMN |
83 | entry = git__calloc(1, sizeof(git_reflog_entry)); |
84 | GITERR_CHECK_ALLOC(entry); | |
85 | ||
29be3a6d | 86 | if ((git_signature_dup(&entry->committer, committer)) < 0) |
0174794a | 87 | goto cleanup; |
40c75652 | 88 | |
0174794a CMN |
89 | if (msg != NULL) { |
90 | if ((entry->msg = git__strdup(msg)) == NULL) | |
91 | goto cleanup; | |
92 | ||
93 | newline = strchr(msg, '\n'); | |
94 | ||
95 | if (newline) { | |
96 | if (newline[1] != '\0') { | |
909d5494 | 97 | giterr_set(GITERR_INVALID, "reflog message cannot contain newline"); |
0174794a CMN |
98 | goto cleanup; |
99 | } | |
100 | ||
101 | entry->msg[newline - msg] = '\0'; | |
102 | } | |
103 | } | |
104 | ||
105 | previous = git_reflog_entry_byindex(reflog, 0); | |
106 | ||
107 | if (previous == NULL) | |
108 | git_oid_fromstr(&entry->oid_old, GIT_OID_HEX_ZERO); | |
109 | else | |
110 | git_oid_cpy(&entry->oid_old, &previous->oid_cur); | |
111 | ||
112 | git_oid_cpy(&entry->oid_cur, new_oid); | |
113 | ||
114 | if (git_vector_insert(&reflog->entries, entry) < 0) | |
115 | goto cleanup; | |
116 | ||
117 | return 0; | |
118 | ||
119 | cleanup: | |
120 | git_reflog_entry__free(entry); | |
121 | return -1; | |
27df4275 MS |
122 | } |
123 | ||
b976f3c2 | 124 | int git_reflog_rename(git_repository *repo, const char *old_name, const char *new_name) |
b7c93a66 | 125 | { |
b976f3c2 CMN |
126 | git_refdb *refdb; |
127 | int error; | |
b6bfd96f | 128 | |
b976f3c2 | 129 | if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0) |
8a810441 | 130 | return -1; |
b7c93a66 | 131 | |
b976f3c2 | 132 | return refdb->backend->reflog_rename(refdb->backend, old_name, new_name); |
b7c93a66 MS |
133 | } |
134 | ||
b976f3c2 | 135 | int git_reflog_delete(git_repository *repo, const char *name) |
b7c93a66 | 136 | { |
b976f3c2 | 137 | git_refdb *refdb; |
a4c291ef | 138 | int error; |
b7c93a66 | 139 | |
b976f3c2 CMN |
140 | if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0) |
141 | return -1; | |
b7c93a66 | 142 | |
b976f3c2 | 143 | return refdb->backend->reflog_delete(refdb->backend, name); |
b7c93a66 MS |
144 | } |
145 | ||
2508cc66 | 146 | size_t git_reflog_entrycount(git_reflog *reflog) |
27df4275 MS |
147 | { |
148 | assert(reflog); | |
2508cc66 | 149 | return reflog->entries.length; |
27df4275 MS |
150 | } |
151 | ||
20363d58 | 152 | const git_reflog_entry * git_reflog_entry_byindex(const git_reflog *reflog, size_t idx) |
a8122b5d | 153 | { |
27df4275 | 154 | assert(reflog); |
b15df1d9 | 155 | |
a8122b5d | 156 | if (idx >= reflog->entries.length) |
b15df1d9 | 157 | return NULL; |
158 | ||
a8122b5d RB |
159 | return git_vector_get( |
160 | &reflog->entries, reflog_inverse_index(idx, reflog->entries.length)); | |
27df4275 MS |
161 | } |
162 | ||
2508cc66 | 163 | const git_oid * git_reflog_entry_id_old(const git_reflog_entry *entry) |
27df4275 MS |
164 | { |
165 | assert(entry); | |
e7be57a9 | 166 | return &entry->oid_old; |
27df4275 MS |
167 | } |
168 | ||
2508cc66 | 169 | const git_oid * git_reflog_entry_id_new(const git_reflog_entry *entry) |
27df4275 MS |
170 | { |
171 | assert(entry); | |
e7be57a9 | 172 | return &entry->oid_cur; |
27df4275 MS |
173 | } |
174 | ||
2508cc66 | 175 | const git_signature * git_reflog_entry_committer(const git_reflog_entry *entry) |
27df4275 MS |
176 | { |
177 | assert(entry); | |
178 | return entry->committer; | |
179 | } | |
180 | ||
2508cc66 | 181 | const char * git_reflog_entry_message(const git_reflog_entry *entry) |
27df4275 MS |
182 | { |
183 | assert(entry); | |
184 | return entry->msg; | |
185 | } | |
59341a5d | 186 | |
0174794a | 187 | int git_reflog_drop(git_reflog *reflog, size_t idx, int rewrite_previous_entry) |
59341a5d | 188 | { |
0174794a CMN |
189 | size_t entrycount; |
190 | git_reflog_entry *entry, *previous; | |
59341a5d | 191 | |
0174794a | 192 | entrycount = git_reflog_entrycount(reflog); |
59341a5d | 193 | |
0174794a CMN |
194 | entry = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx); |
195 | ||
196 | if (entry == NULL) { | |
909d5494 | 197 | giterr_set(GITERR_REFERENCE, "no reflog entry at index %"PRIuZ, idx); |
0174794a CMN |
198 | return GIT_ENOTFOUND; |
199 | } | |
200 | ||
201 | git_reflog_entry__free(entry); | |
202 | ||
203 | if (git_vector_remove( | |
204 | &reflog->entries, reflog_inverse_index(idx, entrycount)) < 0) | |
205 | return -1; | |
206 | ||
207 | if (!rewrite_previous_entry) | |
208 | return 0; | |
209 | ||
210 | /* No need to rewrite anything when removing the most recent entry */ | |
211 | if (idx == 0) | |
212 | return 0; | |
213 | ||
214 | /* Have the latest entry just been dropped? */ | |
215 | if (entrycount == 1) | |
216 | return 0; | |
217 | ||
218 | entry = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx - 1); | |
219 | ||
220 | /* If the oldest entry has just been removed... */ | |
221 | if (idx == entrycount - 1) { | |
222 | /* ...clear the oid_old member of the "new" oldest entry */ | |
223 | if (git_oid_fromstr(&entry->oid_old, GIT_OID_HEX_ZERO) < 0) | |
224 | return -1; | |
225 | ||
226 | return 0; | |
227 | } | |
228 | ||
229 | previous = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx); | |
230 | git_oid_cpy(&entry->oid_old, &previous->oid_cur); | |
231 | ||
232 | return 0; | |
59341a5d | 233 | } |