]>
git.proxmox.com Git - libgit2.git/blob - src/reflog.c
1834a27362080052078b6fe86acfd9c052c42fc1
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.
10 #include "repository.h"
12 #include "signature.h"
15 #include <git2/sys/refdb_backend.h>
17 git_reflog_entry
*git_reflog_entry__alloc(void)
19 return git__calloc(1, sizeof(git_reflog_entry
));
22 void git_reflog_entry__free(git_reflog_entry
*entry
)
24 git_signature_free(entry
->committer
);
26 git__free(entry
->msg
);
30 void git_reflog_free(git_reflog
*reflog
)
33 git_reflog_entry
*entry
;
39 GIT_REFCOUNT_DEC(reflog
->db
, git_refdb__free
);
41 for (i
=0; i
< reflog
->entries
.length
; i
++) {
42 entry
= git_vector_get(&reflog
->entries
, i
);
44 git_reflog_entry__free(entry
);
47 git_vector_free(&reflog
->entries
);
48 git__free(reflog
->ref_name
);
52 int git_reflog_read(git_reflog
**reflog
, git_repository
*repo
, const char *name
)
57 assert(reflog
&& repo
&& name
);
59 if ((error
= git_repository_refdb__weakptr(&refdb
, repo
)) < 0)
62 return git_refdb_reflog_read(reflog
, refdb
, name
);
65 int git_reflog_write(git_reflog
*reflog
)
69 assert(reflog
&& reflog
->db
);
72 return db
->backend
->reflog_write(db
->backend
, reflog
);
75 int git_reflog_append(git_reflog
*reflog
, const git_oid
*new_oid
, const git_signature
*committer
, const char *msg
)
77 git_reflog_entry
*entry
;
78 const git_reflog_entry
*previous
;
81 assert(reflog
&& new_oid
&& committer
);
83 entry
= git__calloc(1, sizeof(git_reflog_entry
));
84 GIT_ERROR_CHECK_ALLOC(entry
);
86 if ((git_signature_dup(&entry
->committer
, committer
)) < 0)
90 if ((entry
->msg
= git__strdup(msg
)) == NULL
)
93 newline
= strchr(msg
, '\n');
96 if (newline
[1] != '\0') {
97 git_error_set(GIT_ERROR_INVALID
, "reflog message cannot contain newline");
101 entry
->msg
[newline
- msg
] = '\0';
105 previous
= git_reflog_entry_byindex(reflog
, 0);
107 if (previous
== NULL
)
108 git_oid_fromstr(&entry
->oid_old
, GIT_OID_HEX_ZERO
);
110 git_oid_cpy(&entry
->oid_old
, &previous
->oid_cur
);
112 git_oid_cpy(&entry
->oid_cur
, new_oid
);
114 if (git_vector_insert(&reflog
->entries
, entry
) < 0)
120 git_reflog_entry__free(entry
);
124 int git_reflog_rename(git_repository
*repo
, const char *old_name
, const char *new_name
)
129 if ((error
= git_repository_refdb__weakptr(&refdb
, repo
)) < 0)
132 return refdb
->backend
->reflog_rename(refdb
->backend
, old_name
, new_name
);
135 int git_reflog_delete(git_repository
*repo
, const char *name
)
140 if ((error
= git_repository_refdb__weakptr(&refdb
, repo
)) < 0)
143 return refdb
->backend
->reflog_delete(refdb
->backend
, name
);
146 size_t git_reflog_entrycount(git_reflog
*reflog
)
149 return reflog
->entries
.length
;
152 const git_reflog_entry
* git_reflog_entry_byindex(const git_reflog
*reflog
, size_t idx
)
156 if (idx
>= reflog
->entries
.length
)
159 return git_vector_get(
160 &reflog
->entries
, reflog_inverse_index(idx
, reflog
->entries
.length
));
163 const git_oid
* git_reflog_entry_id_old(const git_reflog_entry
*entry
)
166 return &entry
->oid_old
;
169 const git_oid
* git_reflog_entry_id_new(const git_reflog_entry
*entry
)
172 return &entry
->oid_cur
;
175 const git_signature
* git_reflog_entry_committer(const git_reflog_entry
*entry
)
178 return entry
->committer
;
181 const char * git_reflog_entry_message(const git_reflog_entry
*entry
)
187 int git_reflog_drop(git_reflog
*reflog
, size_t idx
, int rewrite_previous_entry
)
190 git_reflog_entry
*entry
, *previous
;
192 entrycount
= git_reflog_entrycount(reflog
);
194 entry
= (git_reflog_entry
*)git_reflog_entry_byindex(reflog
, idx
);
197 git_error_set(GIT_ERROR_REFERENCE
, "no reflog entry at index %"PRIuZ
, idx
);
198 return GIT_ENOTFOUND
;
201 git_reflog_entry__free(entry
);
203 if (git_vector_remove(
204 &reflog
->entries
, reflog_inverse_index(idx
, entrycount
)) < 0)
207 if (!rewrite_previous_entry
)
210 /* No need to rewrite anything when removing the most recent entry */
214 /* Have the latest entry just been dropped? */
218 entry
= (git_reflog_entry
*)git_reflog_entry_byindex(reflog
, idx
- 1);
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)
229 previous
= (git_reflog_entry
*)git_reflog_entry_byindex(reflog
, idx
);
230 git_oid_cpy(&entry
->oid_old
, &previous
->oid_cur
);