]>
git.proxmox.com Git - libgit2.git/blob - src/reflog.c
2 * Copyright (C) the libgit2 contributors. All rights reserved.
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.
9 #include "repository.h"
11 #include "signature.h"
14 #include <git2/sys/refdb_backend.h>
16 git_reflog_entry
*git_reflog_entry__alloc(void)
18 return git__calloc(1, sizeof(git_reflog_entry
));
21 void git_reflog_entry__free(git_reflog_entry
*entry
)
23 git_signature_free(entry
->committer
);
25 git__free(entry
->msg
);
29 void git_reflog_free(git_reflog
*reflog
)
32 git_reflog_entry
*entry
;
38 GIT_REFCOUNT_DEC(reflog
->db
, git_refdb__free
);
40 for (i
=0; i
< reflog
->entries
.length
; i
++) {
41 entry
= git_vector_get(&reflog
->entries
, i
);
43 git_reflog_entry__free(entry
);
46 git_vector_free(&reflog
->entries
);
47 git__free(reflog
->ref_name
);
51 int git_reflog_read(git_reflog
**reflog
, git_repository
*repo
, const char *name
)
56 assert(reflog
&& repo
&& name
);
58 if ((error
= git_repository_refdb__weakptr(&refdb
, repo
)) < 0)
61 return git_refdb_reflog_read(reflog
, refdb
, name
);
64 int git_reflog_write(git_reflog
*reflog
)
68 assert(reflog
&& reflog
->db
);
71 return db
->backend
->reflog_write(db
->backend
, reflog
);
74 int git_reflog_append(git_reflog
*reflog
, const git_oid
*new_oid
, const git_signature
*committer
, const char *msg
)
76 git_reflog_entry
*entry
;
77 const git_reflog_entry
*previous
;
80 assert(reflog
&& new_oid
&& committer
);
82 entry
= git__calloc(1, sizeof(git_reflog_entry
));
83 GITERR_CHECK_ALLOC(entry
);
85 if ((git_signature_dup(&entry
->committer
, committer
)) < 0)
89 if ((entry
->msg
= git__strdup(msg
)) == NULL
)
92 newline
= strchr(msg
, '\n');
95 if (newline
[1] != '\0') {
96 giterr_set(GITERR_INVALID
, "Reflog message cannot contain newline");
100 entry
->msg
[newline
- msg
] = '\0';
104 previous
= git_reflog_entry_byindex(reflog
, 0);
106 if (previous
== NULL
)
107 git_oid_fromstr(&entry
->oid_old
, GIT_OID_HEX_ZERO
);
109 git_oid_cpy(&entry
->oid_old
, &previous
->oid_cur
);
111 git_oid_cpy(&entry
->oid_cur
, new_oid
);
113 if (git_vector_insert(&reflog
->entries
, entry
) < 0)
119 git_reflog_entry__free(entry
);
123 int git_reflog_rename(git_repository
*repo
, const char *old_name
, const char *new_name
)
128 if ((error
= git_repository_refdb__weakptr(&refdb
, repo
)) < 0)
131 return refdb
->backend
->reflog_rename(refdb
->backend
, old_name
, new_name
);
134 int git_reflog_delete(git_repository
*repo
, const char *name
)
139 if ((error
= git_repository_refdb__weakptr(&refdb
, repo
)) < 0)
142 return refdb
->backend
->reflog_delete(refdb
->backend
, name
);
145 size_t git_reflog_entrycount(git_reflog
*reflog
)
148 return reflog
->entries
.length
;
151 const git_reflog_entry
* git_reflog_entry_byindex(const git_reflog
*reflog
, size_t idx
)
155 if (idx
>= reflog
->entries
.length
)
158 return git_vector_get(
159 &reflog
->entries
, reflog_inverse_index(idx
, reflog
->entries
.length
));
162 const git_oid
* git_reflog_entry_id_old(const git_reflog_entry
*entry
)
165 return &entry
->oid_old
;
168 const git_oid
* git_reflog_entry_id_new(const git_reflog_entry
*entry
)
171 return &entry
->oid_cur
;
174 const git_signature
* git_reflog_entry_committer(const git_reflog_entry
*entry
)
177 return entry
->committer
;
180 const char * git_reflog_entry_message(const git_reflog_entry
*entry
)
186 int git_reflog_drop(git_reflog
*reflog
, size_t idx
, int rewrite_previous_entry
)
189 git_reflog_entry
*entry
, *previous
;
191 entrycount
= git_reflog_entrycount(reflog
);
193 entry
= (git_reflog_entry
*)git_reflog_entry_byindex(reflog
, idx
);
196 giterr_set(GITERR_REFERENCE
, "No reflog entry at index %"PRIuZ
, idx
);
197 return GIT_ENOTFOUND
;
200 git_reflog_entry__free(entry
);
202 if (git_vector_remove(
203 &reflog
->entries
, reflog_inverse_index(idx
, entrycount
)) < 0)
206 if (!rewrite_previous_entry
)
209 /* No need to rewrite anything when removing the most recent entry */
213 /* Have the latest entry just been dropped? */
217 entry
= (git_reflog_entry
*)git_reflog_entry_byindex(reflog
, idx
- 1);
219 /* If the oldest entry has just been removed... */
220 if (idx
== entrycount
- 1) {
221 /* ...clear the oid_old member of the "new" oldest entry */
222 if (git_oid_fromstr(&entry
->oid_old
, GIT_OID_HEX_ZERO
) < 0)
228 previous
= (git_reflog_entry
*)git_reflog_entry_byindex(reflog
, idx
);
229 git_oid_cpy(&entry
->oid_old
, &previous
->oid_cur
);