File Coverage

deps/libgit2/src/libgit2/reflog.c
Criterion Covered Total %
statement 83 104 79.8
branch 40 76 52.6
condition n/a
subroutine n/a
pod n/a
total 123 180 68.3


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