File Coverage

deps/libgit2/src/reflog.c
Criterion Covered Total %
statement 78 101 77.2
branch 40 76 52.6
condition n/a
subroutine n/a
pod n/a
total 118 177 66.6


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