File Coverage

deps/libgit2/src/reflog.c
Criterion Covered Total %
statement 78 99 78.7
branch 40 76 52.6
condition n/a
subroutine n/a
pod n/a
total 118 175 67.4


line stmt bran cond sub pod time code
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 42           void git_reflog_entry__free(git_reflog_entry *entry)
19             {
20 42           git_signature_free(entry->committer);
21              
22 42           git__free(entry->msg);
23 42           git__free(entry);
24 42           }
25              
26 20           void git_reflog_free(git_reflog *reflog)
27             {
28             size_t i;
29             git_reflog_entry *entry;
30              
31 20 50         if (reflog == NULL)
32 0           return;
33              
34 20 50         if (reflog->db)
35 20 50         GIT_REFCOUNT_DEC(reflog->db, git_refdb__free);
    0          
36              
37 58 100         for (i=0; i < reflog->entries.length; i++) {
38 38           entry = git_vector_get(&reflog->entries, i);
39              
40 38           git_reflog_entry__free(entry);
41             }
42              
43 20           git_vector_free(&reflog->entries);
44 20           git__free(reflog->ref_name);
45 20           git__free(reflog);
46             }
47              
48 20           int git_reflog_read(git_reflog **reflog, git_repository *repo, const char *name)
49             {
50             git_refdb *refdb;
51             int error;
52              
53 20 50         assert(reflog && repo && name);
    50          
    50          
54              
55 20 50         if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
56 0           return error;
57              
58 20           return git_refdb_reflog_read(reflog, refdb, name);
59             }
60              
61 4           int git_reflog_write(git_reflog *reflog)
62             {
63             git_refdb *db;
64              
65 4 50         assert(reflog && reflog->db);
    50          
66              
67 4           db = reflog->db;
68 4           return db->backend->reflog_write(db->backend, reflog);
69             }
70              
71 3           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 3 50         assert(reflog && new_oid && committer);
    50          
    50          
77              
78 3           entry = git__calloc(1, sizeof(git_reflog_entry));
79 3 50         GIT_ERROR_CHECK_ALLOC(entry);
80              
81 3 50         if ((git_signature_dup(&entry->committer, committer)) < 0)
82 0           goto cleanup;
83              
84 3 50         if (msg != NULL) {
85 3           size_t i, msglen = strlen(msg);
86              
87 3 50         if ((entry->msg = git__strndup(msg, msglen)) == NULL)
88 0           goto cleanup;
89              
90             /*
91             * Replace all newlines with spaces, except for
92             * the final trailing newline.
93             */
94 27 100         for (i = 0; i < msglen; i++)
95 24 50         if (entry->msg[i] == '\n')
96 0           entry->msg[i] = ' ';
97             }
98              
99 3           previous = git_reflog_entry_byindex(reflog, 0);
100              
101 3 100         if (previous == NULL)
102 1           git_oid_fromstr(&entry->oid_old, GIT_OID_HEX_ZERO);
103             else
104 2           git_oid_cpy(&entry->oid_old, &previous->oid_cur);
105              
106 3           git_oid_cpy(&entry->oid_cur, new_oid);
107              
108 3 50         if (git_vector_insert(&reflog->entries, entry) < 0)
109 0           goto cleanup;
110              
111 3           return 0;
112              
113             cleanup:
114 0           git_reflog_entry__free(entry);
115 0           return -1;
116             }
117              
118 0           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 0 0         if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
124 0           return -1;
125              
126 0           return refdb->backend->reflog_rename(refdb->backend, old_name, new_name);
127             }
128              
129 1           int git_reflog_delete(git_repository *repo, const char *name)
130             {
131             git_refdb *refdb;
132             int error;
133              
134 1 50         if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
135 0           return -1;
136              
137 1           return refdb->backend->reflog_delete(refdb->backend, name);
138             }
139              
140 39           size_t git_reflog_entrycount(git_reflog *reflog)
141             {
142 39 50         assert(reflog);
143 39           return reflog->entries.length;
144             }
145              
146 46           const git_reflog_entry * git_reflog_entry_byindex(const git_reflog *reflog, size_t idx)
147             {
148 46 50         assert(reflog);
149              
150 46 100         if (idx >= reflog->entries.length)
151 1           return NULL;
152              
153 45           return git_vector_get(
154             &reflog->entries, reflog_inverse_index(idx, reflog->entries.length));
155             }
156              
157 3           const git_oid * git_reflog_entry_id_old(const git_reflog_entry *entry)
158             {
159 3 50         assert(entry);
160 3           return &entry->oid_old;
161             }
162              
163 19           const git_oid * git_reflog_entry_id_new(const git_reflog_entry *entry)
164             {
165 19 50         assert(entry);
166 19           return &entry->oid_cur;
167             }
168              
169 16           const git_signature * git_reflog_entry_committer(const git_reflog_entry *entry)
170             {
171 16 50         assert(entry);
172 16           return entry->committer;
173             }
174              
175 25           const char * git_reflog_entry_message(const git_reflog_entry *entry)
176             {
177 25 50         assert(entry);
178 25           return entry->msg;
179             }
180              
181 4           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 4           entrycount = git_reflog_entrycount(reflog);
187              
188 4           entry = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx);
189              
190 4 50         if (entry == NULL) {
191 0           git_error_set(GIT_ERROR_REFERENCE, "no reflog entry at index %"PRIuZ, idx);
192 0           return GIT_ENOTFOUND;
193             }
194              
195 4           git_reflog_entry__free(entry);
196              
197 4 50         if (git_vector_remove(
198             &reflog->entries, reflog_inverse_index(idx, entrycount)) < 0)
199 0           return -1;
200              
201 4 50         if (!rewrite_previous_entry)
202 0           return 0;
203              
204             /* No need to rewrite anything when removing the most recent entry */
205 4 100         if (idx == 0)
206 3           return 0;
207              
208             /* Have the latest entry just been dropped? */
209 1 50         if (entrycount == 1)
210 0           return 0;
211              
212 1           entry = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx - 1);
213              
214             /* If the oldest entry has just been removed... */
215 1 50         if (idx == entrycount - 1) {
216             /* ...clear the oid_old member of the "new" oldest entry */
217 0 0         if (git_oid_fromstr(&entry->oid_old, GIT_OID_HEX_ZERO) < 0)
218 0           return -1;
219              
220 0           return 0;
221             }
222              
223 1           previous = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx);
224 1           git_oid_cpy(&entry->oid_old, &previous->oid_cur);
225              
226 1           return 0;
227             }