blob: 9b56fa9b819fa404bf0528aeb9d84de1cf618ec7 [file] [log] [blame]
Michael Haggerty7bd9bcf2015-11-09 14:34:01 +01001/*
2 * The backend-independent part of the reference module.
3 */
4
Daniel Barkalow95fc7512005-06-06 16:31:29 -04005#include "cache.h"
Brandon Williamsb2141fc2017-06-14 11:07:36 -07006#include "config.h"
Michael Haggerty7d4558c2017-02-10 12:16:15 +01007#include "hashmap.h"
Michael Haggerty697cc8e2014-10-01 12:28:42 +02008#include "lockfile.h"
Michael Haggertyb05855b2017-04-16 08:41:26 +02009#include "iterator.h"
Junio C Hamano85023572006-12-19 14:34:12 -080010#include "refs.h"
Michael Haggerty4cb77002015-11-10 12:42:36 +010011#include "refs/refs-internal.h"
Junio C Hamanocf0adba2006-11-19 13:22:44 -080012#include "object.h"
13#include "tag.h"
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +070014#include "submodule.h"
Nguyễn Thái Ngọc Duy17eff962017-04-24 17:01:22 +070015#include "worktree.h"
Stefan Beller23a3f0c2018-04-11 17:21:09 -070016#include "repository.h"
Stefan Beller3581d792014-12-12 09:57:02 +010017
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020018/*
Ronnie Sahlberg3dce4442016-09-04 18:08:10 +020019 * List of all available backends
20 */
21static struct ref_storage_be *refs_backends = &refs_be_files;
22
23static struct ref_storage_be *find_ref_storage_backend(const char *name)
24{
25 struct ref_storage_be *be;
26 for (be = refs_backends; be; be = be->next)
27 if (!strcmp(be->name, name))
28 return be;
29 return NULL;
30}
31
32int ref_storage_backend_exists(const char *name)
33{
34 return find_ref_storage_backend(name) != NULL;
35}
36
37/*
David Turnerdde8a902014-06-03 23:38:10 -040038 * How to handle various characters in refnames:
39 * 0: An acceptable character for refs
Junio C Hamano5e650222014-07-28 10:41:53 -070040 * 1: End-of-component
41 * 2: ., look for a preceding . to reject .. in refs
42 * 3: {, look for a preceding @ to reject @{ in refs
Jacob Keller53a85552015-07-22 14:05:32 -070043 * 4: A bad character: ASCII control characters, and
Jacob Kellercd377f42015-07-22 14:05:33 -070044 * ":", "?", "[", "\", "^", "~", SP, or TAB
45 * 5: *, reject unless REFNAME_REFSPEC_PATTERN is set
David Turnerdde8a902014-06-03 23:38:10 -040046 */
47static unsigned char refname_disposition[256] = {
Junio C Hamano5e650222014-07-28 10:41:53 -070048 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
49 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
Jacob Kellercd377f42015-07-22 14:05:33 -070050 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 1,
Junio C Hamano5e650222014-07-28 10:41:53 -070051 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4,
David Turnerdde8a902014-06-03 23:38:10 -040052 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Junio C Hamano5e650222014-07-28 10:41:53 -070053 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 0,
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4
David Turnerdde8a902014-06-03 23:38:10 -040056};
57
58/*
59 * Try to read one refname component from the front of refname.
60 * Return the length of the component found, or -1 if the component is
61 * not legal. It is legal if it is something reasonable to have under
62 * ".git/refs/"; We do not like it if:
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020063 *
64 * - any path component of it begins with ".", or
65 * - it has double dots "..", or
Jacob Keller53a85552015-07-22 14:05:32 -070066 * - it has ASCII control characters, or
Jacob Kellercd377f42015-07-22 14:05:33 -070067 * - it has ":", "?", "[", "\", "^", "~", SP, or TAB anywhere, or
68 * - it has "*" anywhere unless REFNAME_REFSPEC_PATTERN is set, or
Jacob Keller53a85552015-07-22 14:05:32 -070069 * - it ends with a "/", or
70 * - it ends with ".lock", or
71 * - it contains a "@{" portion
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020072 */
Jacob Kellercd377f42015-07-22 14:05:33 -070073static int check_refname_component(const char *refname, int *flags)
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020074{
75 const char *cp;
76 char last = '\0';
77
78 for (cp = refname; ; cp++) {
David Turnerdde8a902014-06-03 23:38:10 -040079 int ch = *cp & 255;
80 unsigned char disp = refname_disposition[ch];
81 switch (disp) {
Junio C Hamano5e650222014-07-28 10:41:53 -070082 case 1:
David Turnerdde8a902014-06-03 23:38:10 -040083 goto out;
Junio C Hamano5e650222014-07-28 10:41:53 -070084 case 2:
David Turnerdde8a902014-06-03 23:38:10 -040085 if (last == '.')
86 return -1; /* Refname contains "..". */
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020087 break;
Junio C Hamano5e650222014-07-28 10:41:53 -070088 case 3:
David Turnerdde8a902014-06-03 23:38:10 -040089 if (last == '@')
90 return -1; /* Refname contains "@{". */
91 break;
Junio C Hamano5e650222014-07-28 10:41:53 -070092 case 4:
David Turnerdde8a902014-06-03 23:38:10 -040093 return -1;
Jacob Kellercd377f42015-07-22 14:05:33 -070094 case 5:
95 if (!(*flags & REFNAME_REFSPEC_PATTERN))
96 return -1; /* refspec can't be a pattern */
97
98 /*
99 * Unset the pattern flag so that we only accept
100 * a single asterisk for one side of refspec.
101 */
102 *flags &= ~ REFNAME_REFSPEC_PATTERN;
103 break;
David Turnerdde8a902014-06-03 23:38:10 -0400104 }
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200105 last = ch;
106 }
David Turnerdde8a902014-06-03 23:38:10 -0400107out:
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200108 if (cp == refname)
Michael Haggertydac529e2012-04-10 07:30:22 +0200109 return 0; /* Component has zero length. */
Jonathan Niederf3cc52d2014-09-26 12:22:22 -0700110 if (refname[0] == '.')
111 return -1; /* Component starts with '.'. */
Michael Haggerty7108ad22014-10-01 12:28:15 +0200112 if (cp - refname >= LOCK_SUFFIX_LEN &&
113 !memcmp(cp - LOCK_SUFFIX_LEN, LOCK_SUFFIX, LOCK_SUFFIX_LEN))
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200114 return -1; /* Refname ends with ".lock". */
115 return cp - refname;
116}
117
Junio C Hamano5e650222014-07-28 10:41:53 -0700118int check_refname_format(const char *refname, int flags)
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200119{
120 int component_len, component_count = 0;
121
Felipe Contreras9ba89f42013-09-02 01:34:30 -0500122 if (!strcmp(refname, "@"))
123 /* Refname is a single character '@'. */
124 return -1;
125
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200126 while (1) {
127 /* We are at the start of a path component. */
Jacob Kellercd377f42015-07-22 14:05:33 -0700128 component_len = check_refname_component(refname, &flags);
129 if (component_len <= 0)
130 return -1;
131
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200132 component_count++;
133 if (refname[component_len] == '\0')
134 break;
135 /* Skip to next component. */
136 refname += component_len + 1;
137 }
138
139 if (refname[component_len - 1] == '.')
140 return -1; /* Refname ends with '.'. */
141 if (!(flags & REFNAME_ALLOW_ONELEVEL) && component_count < 2)
142 return -1; /* Refname has only one component. */
143 return 0;
144}
145
Michael Haggerty4cb77002015-11-10 12:42:36 +0100146int refname_is_safe(const char *refname)
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700147{
Michael Haggerty39950fe2016-04-27 12:39:11 +0200148 const char *rest;
149
150 if (skip_prefix(refname, "refs/", &rest)) {
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700151 char *buf;
152 int result;
Michael Haggertye40f3552016-04-27 12:40:39 +0200153 size_t restlen = strlen(rest);
154
155 /* rest must not be empty, or start or end with "/" */
156 if (!restlen || *rest == '/' || rest[restlen - 1] == '/')
157 return 0;
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700158
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700159 /*
160 * Does the refname try to escape refs/?
161 * For example: refs/foo/../bar is safe but refs/foo/../../bar
162 * is not.
163 */
Michael Haggertye40f3552016-04-27 12:40:39 +0200164 buf = xmallocz(restlen);
165 result = !normalize_path_copy(buf, rest) && !strcmp(buf, rest);
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700166 free(buf);
167 return result;
168 }
Michael Haggerty35db25c2016-04-27 12:42:27 +0200169
170 do {
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700171 if (!isupper(*refname) && *refname != '_')
172 return 0;
173 refname++;
Michael Haggerty35db25c2016-04-27 12:42:27 +0200174 } while (*refname);
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700175 return 1;
176}
177
Michael Haggerty67be7c52017-06-23 09:01:37 +0200178/*
179 * Return true if refname, which has the specified oid and flags, can
180 * be resolved to an object in the database. If the referred-to object
181 * does not exist, emit a warning and return false.
182 */
183int ref_resolves_to_object(const char *refname,
184 const struct object_id *oid,
185 unsigned int flags)
186{
187 if (flags & REF_ISBROKEN)
188 return 0;
189 if (!has_sha1_file(oid->hash)) {
190 error("%s does not point to a valid object!", refname);
191 return 0;
192 }
193 return 1;
194}
195
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700196char *refs_resolve_refdup(struct ref_store *refs,
197 const char *refname, int resolve_flags,
brian m. carlson0f2dc722017-10-15 22:06:55 +0000198 struct object_id *oid, int *flags)
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700199{
200 const char *result;
201
202 result = refs_resolve_ref_unsafe(refs, refname, resolve_flags,
brian m. carlson49e61472017-10-15 22:07:09 +0000203 oid, flags);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700204 return xstrdup_or_null(result);
205}
206
Michael Haggertyfb58c8d2015-06-22 16:03:05 +0200207char *resolve_refdup(const char *refname, int resolve_flags,
brian m. carlson0f2dc722017-10-15 22:06:55 +0000208 struct object_id *oid, int *flags)
Nguyễn Thái Ngọc Duy96ec7b12011-12-13 21:17:48 +0700209{
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700210 return refs_resolve_refdup(get_main_ref_store(the_repository),
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700211 refname, resolve_flags,
brian m. carlson0f2dc722017-10-15 22:06:55 +0000212 oid, flags);
Nguyễn Thái Ngọc Duy96ec7b12011-12-13 21:17:48 +0700213}
214
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200215/* The argument to filter_refs */
216struct ref_filter {
217 const char *pattern;
218 each_ref_fn *fn;
219 void *cb_data;
220};
221
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700222int refs_read_ref_full(struct ref_store *refs, const char *refname,
brian m. carlson34c290a2017-10-15 22:06:56 +0000223 int resolve_flags, struct object_id *oid, int *flags)
Linus Torvalds8a65ff72005-07-02 20:23:36 -0700224{
brian m. carlson49e61472017-10-15 22:07:09 +0000225 if (refs_resolve_ref_unsafe(refs, refname, resolve_flags, oid, flags))
Junio C Hamanoa876ed82005-09-30 14:08:25 -0700226 return 0;
227 return -1;
Linus Torvalds8a65ff72005-07-02 20:23:36 -0700228}
229
brian m. carlson34c290a2017-10-15 22:06:56 +0000230int read_ref_full(const char *refname, int resolve_flags, struct object_id *oid, int *flags)
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700231{
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700232 return refs_read_ref_full(get_main_ref_store(the_repository), refname,
brian m. carlson34c290a2017-10-15 22:06:56 +0000233 resolve_flags, oid, flags);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700234}
235
brian m. carlson34c290a2017-10-15 22:06:56 +0000236int read_ref(const char *refname, struct object_id *oid)
Nguyễn Thái Ngọc Duyc6893322011-11-13 17:22:14 +0700237{
brian m. carlson34c290a2017-10-15 22:06:56 +0000238 return read_ref_full(refname, RESOLVE_REF_READING, oid, NULL);
Nguyễn Thái Ngọc Duyc6893322011-11-13 17:22:14 +0700239}
240
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200241int ref_exists(const char *refname)
Junio C Hamanoef06b912006-11-18 22:13:33 -0800242{
René Scharfe744c0402017-09-23 11:45:04 +0200243 return !!resolve_ref_unsafe(refname, RESOLVE_REF_READING, NULL, NULL);
Junio C Hamanoef06b912006-11-18 22:13:33 -0800244}
245
Rafael Ascensão65516f52017-11-21 21:33:41 +0000246static int match_ref_pattern(const char *refname,
247 const struct string_list_item *item)
248{
249 int matched = 0;
250 if (item->util == NULL) {
251 if (!wildmatch(item->string, refname, 0))
252 matched = 1;
253 } else {
254 const char *rest;
255 if (skip_prefix(refname, item->string, &rest) &&
256 (!*rest || *rest == '/'))
257 matched = 1;
258 }
259 return matched;
260}
261
262int ref_filter_match(const char *refname,
263 const struct string_list *include_patterns,
264 const struct string_list *exclude_patterns)
265{
266 struct string_list_item *item;
267
268 if (exclude_patterns && exclude_patterns->nr) {
269 for_each_string_list_item(item, exclude_patterns) {
270 if (match_ref_pattern(refname, item))
271 return 0;
272 }
273 }
274
275 if (include_patterns && include_patterns->nr) {
276 int found = 0;
277 for_each_string_list_item(item, include_patterns) {
278 if (match_ref_pattern(refname, item)) {
279 found = 1;
280 break;
281 }
282 }
283
284 if (!found)
285 return 0;
286 }
287 return 1;
288}
289
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000290static int filter_refs(const char *refname, const struct object_id *oid,
Michael Haggerty4e675d12015-05-25 18:39:21 +0000291 int flags, void *data)
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200292{
293 struct ref_filter *filter = (struct ref_filter *)data;
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000294
Ævar Arnfjörð Bjarmason55d34262017-06-22 21:38:08 +0000295 if (wildmatch(filter->pattern, refname, 0))
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200296 return 0;
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000297 return filter->fn(refname, oid, flags, filter->cb_data);
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200298}
299
brian m. carlsonac2ed0d2017-10-15 22:07:10 +0000300enum peel_status peel_object(const struct object_id *name, struct object_id *oid)
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200301{
brian m. carlsonac2ed0d2017-10-15 22:07:10 +0000302 struct object *o = lookup_unknown_object(name->hash);
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200303
304 if (o->type == OBJ_NONE) {
brian m. carlsonabef9022018-03-12 02:27:46 +0000305 int type = oid_object_info(name, NULL);
Jeff King8ff226a2014-07-13 02:42:03 -0400306 if (type < 0 || !object_as_type(o, type, 0))
Michael Haggerty68cf8702013-04-22 21:52:20 +0200307 return PEEL_INVALID;
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200308 }
309
310 if (o->type != OBJ_TAG)
Michael Haggerty68cf8702013-04-22 21:52:20 +0200311 return PEEL_NON_TAG;
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200312
313 o = deref_tag_noverify(o);
314 if (!o)
Michael Haggerty68cf8702013-04-22 21:52:20 +0200315 return PEEL_INVALID;
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200316
brian m. carlsonac2ed0d2017-10-15 22:07:10 +0000317 oidcpy(oid, &o->oid);
Michael Haggerty68cf8702013-04-22 21:52:20 +0200318 return PEEL_PEELED;
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200319}
320
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200321struct warn_if_dangling_data {
322 FILE *fp;
323 const char *refname;
Jens Lindströme6bea662014-05-23 12:30:25 +0200324 const struct string_list *refnames;
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200325 const char *msg_fmt;
326};
327
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000328static int warn_if_dangling_symref(const char *refname, const struct object_id *oid,
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200329 int flags, void *cb_data)
330{
331 struct warn_if_dangling_data *d = cb_data;
332 const char *resolves_to;
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200333
334 if (!(flags & REF_ISSYMREF))
335 return 0;
336
René Scharfe744c0402017-09-23 11:45:04 +0200337 resolves_to = resolve_ref_unsafe(refname, 0, NULL, NULL);
Jens Lindströme6bea662014-05-23 12:30:25 +0200338 if (!resolves_to
339 || (d->refname
340 ? strcmp(resolves_to, d->refname)
341 : !string_list_has_string(d->refnames, resolves_to))) {
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200342 return 0;
Jens Lindströme6bea662014-05-23 12:30:25 +0200343 }
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200344
345 fprintf(d->fp, d->msg_fmt, refname);
Junio C Hamano1be65ed2012-05-02 13:51:35 -0700346 fputc('\n', d->fp);
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200347 return 0;
348}
349
350void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
351{
352 struct warn_if_dangling_data data;
353
354 data.fp = fp;
355 data.refname = refname;
Jens Lindströme6bea662014-05-23 12:30:25 +0200356 data.refnames = NULL;
357 data.msg_fmt = msg_fmt;
358 for_each_rawref(warn_if_dangling_symref, &data);
359}
360
361void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list *refnames)
362{
363 struct warn_if_dangling_data data;
364
365 data.fp = fp;
366 data.refname = NULL;
367 data.refnames = refnames;
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200368 data.msg_fmt = msg_fmt;
369 for_each_rawref(warn_if_dangling_symref, &data);
370}
371
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700372int refs_for_each_tag_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
373{
374 return refs_for_each_ref_in(refs, "refs/tags/", fn, cb_data);
375}
376
Junio C Hamanocb5d7092006-09-20 21:47:42 -0700377int for_each_tag_ref(each_ref_fn fn, void *cb_data)
Seana62be772006-05-13 21:43:00 -0400378{
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700379 return refs_for_each_tag_ref(get_main_ref_store(the_repository), fn, cb_data);
Seana62be772006-05-13 21:43:00 -0400380}
381
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700382int refs_for_each_branch_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
383{
384 return refs_for_each_ref_in(refs, "refs/heads/", fn, cb_data);
Heiko Voigt9ef6aeb2010-07-07 15:39:12 +0200385}
386
Junio C Hamanocb5d7092006-09-20 21:47:42 -0700387int for_each_branch_ref(each_ref_fn fn, void *cb_data)
Seana62be772006-05-13 21:43:00 -0400388{
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700389 return refs_for_each_branch_ref(get_main_ref_store(the_repository), fn, cb_data);
Seana62be772006-05-13 21:43:00 -0400390}
391
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700392int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
393{
394 return refs_for_each_ref_in(refs, "refs/remotes/", fn, cb_data);
Heiko Voigt9ef6aeb2010-07-07 15:39:12 +0200395}
396
Junio C Hamanocb5d7092006-09-20 21:47:42 -0700397int for_each_remote_ref(each_ref_fn fn, void *cb_data)
Seana62be772006-05-13 21:43:00 -0400398{
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700399 return refs_for_each_remote_ref(get_main_ref_store(the_repository), fn, cb_data);
Junio C Hamanof8948e22009-02-08 23:27:10 -0800400}
401
Josh Tripletta1bea2c2011-07-05 10:54:44 -0700402int head_ref_namespaced(each_ref_fn fn, void *cb_data)
403{
404 struct strbuf buf = STRBUF_INIT;
405 int ret = 0;
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000406 struct object_id oid;
Josh Tripletta1bea2c2011-07-05 10:54:44 -0700407 int flag;
408
409 strbuf_addf(&buf, "%sHEAD", get_git_namespace());
brian m. carlson34c290a2017-10-15 22:06:56 +0000410 if (!read_ref_full(buf.buf, RESOLVE_REF_READING, &oid, &flag))
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000411 ret = fn(buf.buf, &oid, flag, cb_data);
Josh Tripletta1bea2c2011-07-05 10:54:44 -0700412 strbuf_release(&buf);
413
414 return ret;
415}
416
Rafael Ascensão65516f52017-11-21 21:33:41 +0000417void normalize_glob_ref(struct string_list_item *item, const char *prefix,
418 const char *pattern)
419{
420 struct strbuf normalized_pattern = STRBUF_INIT;
421
422 if (*pattern == '/')
423 BUG("pattern must not start with '/'");
424
425 if (prefix) {
426 strbuf_addstr(&normalized_pattern, prefix);
427 }
428 else if (!starts_with(pattern, "refs/"))
429 strbuf_addstr(&normalized_pattern, "refs/");
430 strbuf_addstr(&normalized_pattern, pattern);
431 strbuf_strip_suffix(&normalized_pattern, "/");
432
433 item->string = strbuf_detach(&normalized_pattern, NULL);
434 item->util = has_glob_specials(pattern) ? NULL : item->string;
435 strbuf_release(&normalized_pattern);
436}
437
Ilari Liusvaarab09fe972010-01-20 11:48:26 +0200438int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
439 const char *prefix, void *cb_data)
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200440{
441 struct strbuf real_pattern = STRBUF_INIT;
442 struct ref_filter filter;
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200443 int ret;
444
Christian Couder59556542013-11-30 21:55:40 +0100445 if (!prefix && !starts_with(pattern, "refs/"))
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200446 strbuf_addstr(&real_pattern, "refs/");
Ilari Liusvaarab09fe972010-01-20 11:48:26 +0200447 else if (prefix)
448 strbuf_addstr(&real_pattern, prefix);
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200449 strbuf_addstr(&real_pattern, pattern);
450
Thomas Rast894a9d32010-03-12 18:04:26 +0100451 if (!has_glob_specials(pattern)) {
Junio C Hamano9517e6b2010-02-03 21:23:18 -0800452 /* Append implied '/' '*' if not present. */
Jeff King00b6c172015-09-24 17:08:35 -0400453 strbuf_complete(&real_pattern, '/');
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200454 /* No need to check for '*', there is none. */
455 strbuf_addch(&real_pattern, '*');
456 }
457
458 filter.pattern = real_pattern.buf;
459 filter.fn = fn;
460 filter.cb_data = cb_data;
461 ret = for_each_ref(filter_refs, &filter);
462
463 strbuf_release(&real_pattern);
464 return ret;
465}
466
Ilari Liusvaarab09fe972010-01-20 11:48:26 +0200467int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
468{
469 return for_each_glob_ref_in(fn, pattern, NULL, cb_data);
470}
471
Felipe Contreras4577e482009-05-14 00:22:04 +0300472const char *prettify_refname(const char *name)
Daniel Barkalowa9c37a72009-03-08 21:06:05 -0400473{
SZEDER Gábor3e5b36c2017-03-23 16:50:12 +0100474 if (skip_prefix(name, "refs/heads/", &name) ||
475 skip_prefix(name, "refs/tags/", &name) ||
476 skip_prefix(name, "refs/remotes/", &name))
477 ; /* nothing */
478 return name;
Daniel Barkalowa9c37a72009-03-08 21:06:05 -0400479}
480
Michael Haggerty54457fe2014-01-14 04:16:07 +0100481static const char *ref_rev_parse_rules[] = {
Steffen Prohaska79803322007-11-11 15:01:46 +0100482 "%.*s",
483 "refs/%.*s",
484 "refs/tags/%.*s",
485 "refs/heads/%.*s",
486 "refs/remotes/%.*s",
487 "refs/remotes/%.*s/HEAD",
488 NULL
489};
490
Michael Haggerty54457fe2014-01-14 04:16:07 +0100491int refname_match(const char *abbrev_name, const char *full_name)
Steffen Prohaska79803322007-11-11 15:01:46 +0100492{
493 const char **p;
494 const int abbrev_name_len = strlen(abbrev_name);
495
Michael Haggerty54457fe2014-01-14 04:16:07 +0100496 for (p = ref_rev_parse_rules; *p; p++) {
Steffen Prohaska79803322007-11-11 15:01:46 +0100497 if (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name))) {
498 return 1;
499 }
500 }
501
502 return 0;
503}
504
Michael Haggerty19b68b12011-12-12 06:38:12 +0100505/*
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700506 * *string and *len will only be substituted, and *string returned (for
507 * later free()ing) if the string passed in is a magic short-hand form
508 * to name a branch.
509 */
510static char *substitute_branch_name(const char **string, int *len)
511{
512 struct strbuf buf = STRBUF_INIT;
Jeff King0e9f62d2017-03-02 03:23:01 -0500513 int ret = interpret_branch_name(*string, *len, &buf, 0);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700514
515 if (ret == *len) {
516 size_t size;
517 *string = strbuf_detach(&buf, &size);
518 *len = size;
519 return (char *)*string;
520 }
521
522 return NULL;
523}
524
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000525int dwim_ref(const char *str, int len, struct object_id *oid, char **ref)
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700526{
527 char *last_branch = substitute_branch_name(&str, &len);
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000528 int refs_found = expand_ref(str, len, oid, ref);
Nguyễn Thái Ngọc Duy41da7112016-06-12 17:54:02 +0700529 free(last_branch);
530 return refs_found;
531}
532
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000533int expand_ref(const char *str, int len, struct object_id *oid, char **ref)
Nguyễn Thái Ngọc Duy41da7112016-06-12 17:54:02 +0700534{
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700535 const char **p, *r;
536 int refs_found = 0;
Jeff King6cd4a892017-03-28 15:46:33 -0400537 struct strbuf fullref = STRBUF_INIT;
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700538
539 *ref = NULL;
540 for (p = ref_rev_parse_rules; *p; p++) {
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000541 struct object_id oid_from_ref;
542 struct object_id *this_result;
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700543 int flag;
544
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000545 this_result = refs_found ? &oid_from_ref : oid;
Jeff King6cd4a892017-03-28 15:46:33 -0400546 strbuf_reset(&fullref);
547 strbuf_addf(&fullref, *p, len, str);
548 r = resolve_ref_unsafe(fullref.buf, RESOLVE_REF_READING,
brian m. carlson49e61472017-10-15 22:07:09 +0000549 this_result, &flag);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700550 if (r) {
551 if (!refs_found++)
552 *ref = xstrdup(r);
553 if (!warn_ambiguous_refs)
554 break;
Jeff King6cd4a892017-03-28 15:46:33 -0400555 } else if ((flag & REF_ISSYMREF) && strcmp(fullref.buf, "HEAD")) {
556 warning("ignoring dangling symref %s.", fullref.buf);
557 } else if ((flag & REF_ISBROKEN) && strchr(fullref.buf, '/')) {
558 warning("ignoring broken ref %s.", fullref.buf);
Junio C Hamano55956352011-10-19 13:55:49 -0700559 }
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700560 }
Jeff King6cd4a892017-03-28 15:46:33 -0400561 strbuf_release(&fullref);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700562 return refs_found;
563}
564
brian m. carlson334dc522017-10-15 22:06:59 +0000565int dwim_log(const char *str, int len, struct object_id *oid, char **log)
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700566{
567 char *last_branch = substitute_branch_name(&str, &len);
568 const char **p;
569 int logs_found = 0;
Jeff King6cd4a892017-03-28 15:46:33 -0400570 struct strbuf path = STRBUF_INIT;
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700571
572 *log = NULL;
573 for (p = ref_rev_parse_rules; *p; p++) {
brian m. carlson334dc522017-10-15 22:06:59 +0000574 struct object_id hash;
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700575 const char *ref, *it;
576
Jeff King6cd4a892017-03-28 15:46:33 -0400577 strbuf_reset(&path);
578 strbuf_addf(&path, *p, len, str);
579 ref = resolve_ref_unsafe(path.buf, RESOLVE_REF_READING,
brian m. carlson49e61472017-10-15 22:07:09 +0000580 &hash, NULL);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700581 if (!ref)
582 continue;
Jeff King6cd4a892017-03-28 15:46:33 -0400583 if (reflog_exists(path.buf))
584 it = path.buf;
585 else if (strcmp(ref, path.buf) && reflog_exists(ref))
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700586 it = ref;
587 else
588 continue;
589 if (!logs_found++) {
590 *log = xstrdup(it);
brian m. carlson334dc522017-10-15 22:06:59 +0000591 oidcpy(oid, &hash);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700592 }
593 if (!warn_ambiguous_refs)
594 break;
595 }
Jeff King6cd4a892017-03-28 15:46:33 -0400596 strbuf_release(&path);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700597 free(last_branch);
598 return logs_found;
599}
600
David Turner266b1822015-07-31 02:06:18 -0400601static int is_per_worktree_ref(const char *refname)
602{
David Turnerce414b32015-08-31 22:13:11 -0400603 return !strcmp(refname, "HEAD") ||
604 starts_with(refname, "refs/bisect/");
David Turner266b1822015-07-31 02:06:18 -0400605}
606
607static int is_pseudoref_syntax(const char *refname)
608{
609 const char *c;
610
611 for (c = refname; *c; c++) {
612 if (!isupper(*c) && *c != '-' && *c != '_')
613 return 0;
614 }
615
616 return 1;
617}
618
619enum ref_type ref_type(const char *refname)
620{
621 if (is_per_worktree_ref(refname))
622 return REF_TYPE_PER_WORKTREE;
623 if (is_pseudoref_syntax(refname))
624 return REF_TYPE_PSEUDOREF;
625 return REF_TYPE_NORMAL;
626}
627
Michael Haggerty4ff0f012017-08-21 13:51:34 +0200628long get_files_ref_lock_timeout_ms(void)
629{
630 static int configured = 0;
631
632 /* The default timeout is 100 ms: */
633 static int timeout_ms = 100;
634
635 if (!configured) {
636 git_config_get_int("core.filesreflocktimeout", &timeout_ms);
637 configured = 1;
638 }
639
640 return timeout_ms;
641}
642
brian m. carlsonae077772017-10-15 22:06:51 +0000643static int write_pseudoref(const char *pseudoref, const struct object_id *oid,
644 const struct object_id *old_oid, struct strbuf *err)
David Turner74ec19d2015-07-31 02:06:19 -0400645{
646 const char *filename;
647 int fd;
648 static struct lock_file lock;
649 struct strbuf buf = STRBUF_INIT;
650 int ret = -1;
651
brian m. carlson6ee18212017-10-15 22:06:52 +0000652 if (!oid)
653 return 0;
654
brian m. carlsonae077772017-10-15 22:06:51 +0000655 strbuf_addf(&buf, "%s\n", oid_to_hex(oid));
David Turner74ec19d2015-07-31 02:06:19 -0400656
657 filename = git_path("%s", pseudoref);
Michael Haggerty4ff0f012017-08-21 13:51:34 +0200658 fd = hold_lock_file_for_update_timeout(&lock, filename,
659 LOCK_DIE_ON_ERROR,
660 get_files_ref_lock_timeout_ms());
David Turner74ec19d2015-07-31 02:06:19 -0400661 if (fd < 0) {
Michael Haggerty0568c8e2016-04-27 15:21:36 +0200662 strbuf_addf(err, "could not open '%s' for writing: %s",
David Turner74ec19d2015-07-31 02:06:19 -0400663 filename, strerror(errno));
Rene Scharfeaeb014f2017-08-30 19:58:12 +0200664 goto done;
David Turner74ec19d2015-07-31 02:06:19 -0400665 }
666
brian m. carlsonae077772017-10-15 22:06:51 +0000667 if (old_oid) {
668 struct object_id actual_old_oid;
David Turner2c3aed12015-07-15 18:05:28 -0400669
brian m. carlson34c290a2017-10-15 22:06:56 +0000670 if (read_ref(pseudoref, &actual_old_oid))
David Turner2c3aed12015-07-15 18:05:28 -0400671 die("could not read ref '%s'", pseudoref);
brian m. carlsonae077772017-10-15 22:06:51 +0000672 if (oidcmp(&actual_old_oid, old_oid)) {
Michael Haggerty0568c8e2016-04-27 15:21:36 +0200673 strbuf_addf(err, "unexpected sha1 when writing '%s'", pseudoref);
David Turner74ec19d2015-07-31 02:06:19 -0400674 rollback_lock_file(&lock);
675 goto done;
676 }
677 }
678
Jeff King06f46f22017-09-13 13:16:03 -0400679 if (write_in_full(fd, buf.buf, buf.len) < 0) {
Michael Haggerty0568c8e2016-04-27 15:21:36 +0200680 strbuf_addf(err, "could not write to '%s'", filename);
David Turner74ec19d2015-07-31 02:06:19 -0400681 rollback_lock_file(&lock);
682 goto done;
683 }
684
685 commit_lock_file(&lock);
686 ret = 0;
687done:
688 strbuf_release(&buf);
689 return ret;
690}
691
brian m. carlson2616a5e2017-10-15 22:06:50 +0000692static int delete_pseudoref(const char *pseudoref, const struct object_id *old_oid)
David Turner74ec19d2015-07-31 02:06:19 -0400693{
694 static struct lock_file lock;
695 const char *filename;
696
697 filename = git_path("%s", pseudoref);
698
brian m. carlson2616a5e2017-10-15 22:06:50 +0000699 if (old_oid && !is_null_oid(old_oid)) {
David Turner74ec19d2015-07-31 02:06:19 -0400700 int fd;
brian m. carlson2616a5e2017-10-15 22:06:50 +0000701 struct object_id actual_old_oid;
David Turner74ec19d2015-07-31 02:06:19 -0400702
Michael Haggerty4ff0f012017-08-21 13:51:34 +0200703 fd = hold_lock_file_for_update_timeout(
704 &lock, filename, LOCK_DIE_ON_ERROR,
705 get_files_ref_lock_timeout_ms());
David Turner74ec19d2015-07-31 02:06:19 -0400706 if (fd < 0)
707 die_errno(_("Could not open '%s' for writing"), filename);
brian m. carlson34c290a2017-10-15 22:06:56 +0000708 if (read_ref(pseudoref, &actual_old_oid))
David Turner2c3aed12015-07-15 18:05:28 -0400709 die("could not read ref '%s'", pseudoref);
brian m. carlson2616a5e2017-10-15 22:06:50 +0000710 if (oidcmp(&actual_old_oid, old_oid)) {
David Turner74ec19d2015-07-31 02:06:19 -0400711 warning("Unexpected sha1 when deleting %s", pseudoref);
712 rollback_lock_file(&lock);
713 return -1;
714 }
715
716 unlink(filename);
717 rollback_lock_file(&lock);
718 } else {
719 unlink(filename);
720 }
721
722 return 0;
723}
724
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700725int refs_delete_ref(struct ref_store *refs, const char *msg,
726 const char *refname,
brian m. carlson2616a5e2017-10-15 22:06:50 +0000727 const struct object_id *old_oid,
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700728 unsigned int flags)
Junio C Hamanoc0277d12006-09-30 15:02:00 -0700729{
Ronnie Sahlberg7521cc42014-04-30 09:22:45 -0700730 struct ref_transaction *transaction;
731 struct strbuf err = STRBUF_INIT;
Junio C Hamanoc0277d12006-09-30 15:02:00 -0700732
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700733 if (ref_type(refname) == REF_TYPE_PSEUDOREF) {
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700734 assert(refs == get_main_ref_store(the_repository));
brian m. carlson2616a5e2017-10-15 22:06:50 +0000735 return delete_pseudoref(refname, old_oid);
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700736 }
David Turner74ec19d2015-07-31 02:06:19 -0400737
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700738 transaction = ref_store_transaction_begin(refs, &err);
Ronnie Sahlberg7521cc42014-04-30 09:22:45 -0700739 if (!transaction ||
brian m. carlson89f3bbd2017-10-15 22:06:53 +0000740 ref_transaction_delete(transaction, refname, old_oid,
Kyle Meyer755b49a2017-02-20 20:10:32 -0500741 flags, msg, &err) ||
Ronnie Sahlbergdb7516a2014-04-30 12:22:42 -0700742 ref_transaction_commit(transaction, &err)) {
Ronnie Sahlberg7521cc42014-04-30 09:22:45 -0700743 error("%s", err.buf);
744 ref_transaction_free(transaction);
745 strbuf_release(&err);
Junio C Hamanoc0277d12006-09-30 15:02:00 -0700746 return 1;
Ronnie Sahlberg7521cc42014-04-30 09:22:45 -0700747 }
748 ref_transaction_free(transaction);
749 strbuf_release(&err);
750 return 0;
Shawn Pearce4bd18c42006-05-17 05:55:02 -0400751}
752
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700753int delete_ref(const char *msg, const char *refname,
brian m. carlson2616a5e2017-10-15 22:06:50 +0000754 const struct object_id *old_oid, unsigned int flags)
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700755{
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700756 return refs_delete_ref(get_main_ref_store(the_repository), msg, refname,
brian m. carlson2616a5e2017-10-15 22:06:50 +0000757 old_oid, flags);
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700758}
759
Michael Haggerty4cb77002015-11-10 12:42:36 +0100760int copy_reflog_msg(char *buf, const char *msg)
Junio C Hamano0ec29a42007-07-28 17:17:17 -0700761{
762 char *cp = buf;
763 char c;
764 int wasspace = 1;
765
766 *cp++ = '\t';
767 while ((c = *msg++)) {
768 if (wasspace && isspace(c))
769 continue;
770 wasspace = isspace(c);
771 if (wasspace)
772 c = ' ';
773 *cp++ = c;
774 }
775 while (buf < cp && isspace(cp[-1]))
776 cp--;
777 *cp++ = '\n';
778 return cp - buf;
779}
780
Michael Haggerty4cb77002015-11-10 12:42:36 +0100781int should_autocreate_reflog(const char *refname)
David Turner4e2bef52015-07-21 17:04:51 -0400782{
Cornelius Weig341fb282017-01-27 11:09:47 +0100783 switch (log_all_ref_updates) {
784 case LOG_REFS_ALWAYS:
785 return 1;
786 case LOG_REFS_NORMAL:
787 return starts_with(refname, "refs/heads/") ||
788 starts_with(refname, "refs/remotes/") ||
789 starts_with(refname, "refs/notes/") ||
790 !strcmp(refname, "HEAD");
791 default:
David Turner4e2bef52015-07-21 17:04:51 -0400792 return 0;
Cornelius Weig341fb282017-01-27 11:09:47 +0100793 }
David Turner4e2bef52015-07-21 17:04:51 -0400794}
795
Ronnie Sahlberge7e0f262014-07-15 16:02:38 -0700796int is_branch(const char *refname)
Linus Torvaldsc3b0dec2008-01-15 15:50:17 -0800797{
Christian Couder59556542013-11-30 21:55:40 +0100798 return !strcmp(refname, "HEAD") || starts_with(refname, "refs/heads/");
Linus Torvaldsc3b0dec2008-01-15 15:50:17 -0800799}
800
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700801struct read_ref_at_cb {
802 const char *refname;
Johannes Schindelindddbad72017-04-26 21:29:31 +0200803 timestamp_t at_time;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700804 int cnt;
805 int reccnt;
brian m. carlson8eb36d92017-10-15 22:07:03 +0000806 struct object_id *oid;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700807 int found_it;
808
brian m. carlson8eb36d92017-10-15 22:07:03 +0000809 struct object_id ooid;
810 struct object_id noid;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700811 int tz;
Johannes Schindelindddbad72017-04-26 21:29:31 +0200812 timestamp_t date;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700813 char **msg;
Johannes Schindelindddbad72017-04-26 21:29:31 +0200814 timestamp_t *cutoff_time;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700815 int *cutoff_tz;
816 int *cutoff_cnt;
817};
818
brian m. carlson9461d272017-02-21 23:47:32 +0000819static int read_ref_at_ent(struct object_id *ooid, struct object_id *noid,
Johannes Schindelindddbad72017-04-26 21:29:31 +0200820 const char *email, timestamp_t timestamp, int tz,
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700821 const char *message, void *cb_data)
Junio C Hamano16d7cc92007-01-19 01:19:05 -0800822{
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700823 struct read_ref_at_cb *cb = cb_data;
824
825 cb->reccnt++;
826 cb->tz = tz;
827 cb->date = timestamp;
828
829 if (timestamp <= cb->at_time || cb->cnt == 0) {
830 if (cb->msg)
831 *cb->msg = xstrdup(message);
832 if (cb->cutoff_time)
833 *cb->cutoff_time = timestamp;
834 if (cb->cutoff_tz)
835 *cb->cutoff_tz = tz;
836 if (cb->cutoff_cnt)
837 *cb->cutoff_cnt = cb->reccnt - 1;
838 /*
Michael Haggerty78fb4572017-11-05 09:42:09 +0100839 * we have not yet updated cb->[n|o]oid so they still
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700840 * hold the values for the previous record.
841 */
brian m. carlson8eb36d92017-10-15 22:07:03 +0000842 if (!is_null_oid(&cb->ooid)) {
843 oidcpy(cb->oid, noid);
844 if (oidcmp(&cb->ooid, noid))
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700845 warning("Log for ref %s has gap after %s.",
Jeff Kinga5481a62015-06-25 12:55:02 -0400846 cb->refname, show_date(cb->date, cb->tz, DATE_MODE(RFC2822)));
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700847 }
848 else if (cb->date == cb->at_time)
brian m. carlson8eb36d92017-10-15 22:07:03 +0000849 oidcpy(cb->oid, noid);
850 else if (oidcmp(noid, cb->oid))
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700851 warning("Log for ref %s unexpectedly ended on %s.",
852 cb->refname, show_date(cb->date, cb->tz,
Jeff Kinga5481a62015-06-25 12:55:02 -0400853 DATE_MODE(RFC2822)));
brian m. carlson8eb36d92017-10-15 22:07:03 +0000854 oidcpy(&cb->ooid, ooid);
855 oidcpy(&cb->noid, noid);
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700856 cb->found_it = 1;
857 return 1;
858 }
brian m. carlson8eb36d92017-10-15 22:07:03 +0000859 oidcpy(&cb->ooid, ooid);
860 oidcpy(&cb->noid, noid);
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700861 if (cb->cnt > 0)
862 cb->cnt--;
863 return 0;
864}
865
brian m. carlson9461d272017-02-21 23:47:32 +0000866static int read_ref_at_ent_oldest(struct object_id *ooid, struct object_id *noid,
Johannes Schindelindddbad72017-04-26 21:29:31 +0200867 const char *email, timestamp_t timestamp,
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700868 int tz, const char *message, void *cb_data)
869{
870 struct read_ref_at_cb *cb = cb_data;
871
872 if (cb->msg)
873 *cb->msg = xstrdup(message);
874 if (cb->cutoff_time)
875 *cb->cutoff_time = timestamp;
876 if (cb->cutoff_tz)
877 *cb->cutoff_tz = tz;
878 if (cb->cutoff_cnt)
879 *cb->cutoff_cnt = cb->reccnt;
brian m. carlson8eb36d92017-10-15 22:07:03 +0000880 oidcpy(cb->oid, ooid);
881 if (is_null_oid(cb->oid))
882 oidcpy(cb->oid, noid);
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700883 /* We just want the first entry */
884 return 1;
Junio C Hamano16d7cc92007-01-19 01:19:05 -0800885}
886
Johannes Schindelindddbad72017-04-26 21:29:31 +0200887int read_ref_at(const char *refname, unsigned int flags, timestamp_t at_time, int cnt,
brian m. carlson8eb36d92017-10-15 22:07:03 +0000888 struct object_id *oid, char **msg,
Johannes Schindelindddbad72017-04-26 21:29:31 +0200889 timestamp_t *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
Shawn Pearced556fae2006-05-17 05:56:09 -0400890{
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700891 struct read_ref_at_cb cb;
Shawn Pearced556fae2006-05-17 05:56:09 -0400892
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700893 memset(&cb, 0, sizeof(cb));
894 cb.refname = refname;
895 cb.at_time = at_time;
896 cb.cnt = cnt;
897 cb.msg = msg;
898 cb.cutoff_time = cutoff_time;
899 cb.cutoff_tz = cutoff_tz;
900 cb.cutoff_cnt = cutoff_cnt;
brian m. carlson8eb36d92017-10-15 22:07:03 +0000901 cb.oid = oid;
Shawn Pearced556fae2006-05-17 05:56:09 -0400902
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700903 for_each_reflog_ent_reverse(refname, read_ref_at_ent, &cb);
Shawn Pearced556fae2006-05-17 05:56:09 -0400904
David Aguilarc41a87d2014-09-18 20:45:37 -0700905 if (!cb.reccnt) {
brian m. carlson321c89b2017-07-13 23:49:29 +0000906 if (flags & GET_OID_QUIETLY)
David Aguilarc41a87d2014-09-18 20:45:37 -0700907 exit(128);
908 else
909 die("Log for %s is empty.", refname);
910 }
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700911 if (cb.found_it)
912 return 0;
Junio C Hamano16d7cc92007-01-19 01:19:05 -0800913
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700914 for_each_reflog_ent(refname, read_ref_at_ent_oldest, &cb);
915
Junio C Hamano16d7cc92007-01-19 01:19:05 -0800916 return 1;
Shawn Pearced556fae2006-05-17 05:56:09 -0400917}
Junio C Hamano2ff81662006-12-18 01:18:16 -0800918
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700919struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs,
920 struct strbuf *err)
Michael Haggertycaa40462014-04-07 15:48:10 +0200921{
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700922 struct ref_transaction *tr;
Jonathan Nieder5a603b02014-08-28 16:42:37 -0700923 assert(err);
924
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700925 tr = xcalloc(1, sizeof(struct ref_transaction));
926 tr->ref_store = refs;
927 return tr;
928}
929
930struct ref_transaction *ref_transaction_begin(struct strbuf *err)
931{
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700932 return ref_store_transaction_begin(get_main_ref_store(the_repository), err);
Michael Haggertycaa40462014-04-07 15:48:10 +0200933}
934
Ronnie Sahlberg026bd1d2014-06-20 07:42:42 -0700935void ref_transaction_free(struct ref_transaction *transaction)
Michael Haggertycaa40462014-04-07 15:48:10 +0200936{
Michael Haggerty43a2dfd2017-05-22 16:17:37 +0200937 size_t i;
Michael Haggertycaa40462014-04-07 15:48:10 +0200938
Ronnie Sahlberg1b072552014-06-20 07:42:45 -0700939 if (!transaction)
940 return;
941
Michael Haggerty30173b82017-05-22 16:17:44 +0200942 switch (transaction->state) {
943 case REF_TRANSACTION_OPEN:
944 case REF_TRANSACTION_CLOSED:
945 /* OK */
946 break;
947 case REF_TRANSACTION_PREPARED:
948 die("BUG: free called on a prepared reference transaction");
949 break;
950 default:
951 die("BUG: unexpected reference transaction state");
952 break;
953 }
954
Ronnie Sahlbergdb7516a2014-04-30 12:22:42 -0700955 for (i = 0; i < transaction->nr; i++) {
956 free(transaction->updates[i]->msg);
Michael Haggerty88615912014-04-07 15:48:14 +0200957 free(transaction->updates[i]);
Ronnie Sahlbergdb7516a2014-04-30 12:22:42 -0700958 }
Michael Haggertycaa40462014-04-07 15:48:10 +0200959 free(transaction->updates);
960 free(transaction);
961}
962
Michael Haggerty71564512016-04-25 11:39:54 +0200963struct ref_update *ref_transaction_add_update(
964 struct ref_transaction *transaction,
965 const char *refname, unsigned int flags,
brian m. carlson89f3bbd2017-10-15 22:06:53 +0000966 const struct object_id *new_oid,
967 const struct object_id *old_oid,
Michael Haggerty71564512016-04-25 11:39:54 +0200968 const char *msg)
Michael Haggertycaa40462014-04-07 15:48:10 +0200969{
Jeff King96ffc062016-02-22 17:44:32 -0500970 struct ref_update *update;
Michael Haggerty71564512016-04-25 11:39:54 +0200971
972 if (transaction->state != REF_TRANSACTION_OPEN)
973 die("BUG: update called for transaction that is not open");
974
Jeff King96ffc062016-02-22 17:44:32 -0500975 FLEX_ALLOC_STR(update, refname, refname);
Michael Haggertycaa40462014-04-07 15:48:10 +0200976 ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc);
977 transaction->updates[transaction->nr++] = update;
Michael Haggerty71564512016-04-25 11:39:54 +0200978
979 update->flags = flags;
980
981 if (flags & REF_HAVE_NEW)
brian m. carlson89f3bbd2017-10-15 22:06:53 +0000982 oidcpy(&update->new_oid, new_oid);
Michael Haggerty71564512016-04-25 11:39:54 +0200983 if (flags & REF_HAVE_OLD)
brian m. carlson89f3bbd2017-10-15 22:06:53 +0000984 oidcpy(&update->old_oid, old_oid);
Junio C Hamano13092a92016-10-12 11:20:23 -0700985 update->msg = xstrdup_or_null(msg);
Michael Haggertycaa40462014-04-07 15:48:10 +0200986 return update;
987}
988
Ronnie Sahlberg8e348002014-06-20 07:43:00 -0700989int ref_transaction_update(struct ref_transaction *transaction,
990 const char *refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +0000991 const struct object_id *new_oid,
992 const struct object_id *old_oid,
Michael Haggerty1d147bd2015-02-17 18:00:15 +0100993 unsigned int flags, const char *msg,
Ronnie Sahlberg8e348002014-06-20 07:43:00 -0700994 struct strbuf *err)
Michael Haggertycaa40462014-04-07 15:48:10 +0200995{
Jonathan Nieder5a603b02014-08-28 16:42:37 -0700996 assert(err);
997
brian m. carlson89f3bbd2017-10-15 22:06:53 +0000998 if ((new_oid && !is_null_oid(new_oid)) ?
Michael Haggerty8a679de2016-04-27 15:54:45 +0200999 check_refname_format(refname, REFNAME_ALLOW_ONELEVEL) :
1000 !refname_is_safe(refname)) {
Michael Haggerty0568c8e2016-04-27 15:21:36 +02001001 strbuf_addf(err, "refusing to update ref with bad name '%s'",
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -07001002 refname);
1003 return -1;
1004 }
1005
Michael Haggertya9bbbce2017-11-05 09:42:03 +01001006 if (flags & ~REF_TRANSACTION_UPDATE_ALLOWED_FLAGS)
1007 BUG("illegal flags 0x%x passed to ref_transaction_update()", flags);
Thomas Gummererc788c542017-09-12 23:59:21 +01001008
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001009 flags |= (new_oid ? REF_HAVE_NEW : 0) | (old_oid ? REF_HAVE_OLD : 0);
Michael Haggerty71564512016-04-25 11:39:54 +02001010
1011 ref_transaction_add_update(transaction, refname, flags,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001012 new_oid, old_oid, msg);
Ronnie Sahlberg8e348002014-06-20 07:43:00 -07001013 return 0;
Michael Haggertycaa40462014-04-07 15:48:10 +02001014}
1015
Ronnie Sahlbergb416af52014-04-16 15:26:44 -07001016int ref_transaction_create(struct ref_transaction *transaction,
1017 const char *refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001018 const struct object_id *new_oid,
Michael Haggertyfec14ec2015-02-17 18:00:13 +01001019 unsigned int flags, const char *msg,
Ronnie Sahlbergb416af52014-04-16 15:26:44 -07001020 struct strbuf *err)
Michael Haggertycaa40462014-04-07 15:48:10 +02001021{
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001022 if (!new_oid || is_null_oid(new_oid))
1023 die("BUG: create called without valid new_oid");
1024 return ref_transaction_update(transaction, refname, new_oid,
1025 &null_oid, flags, msg, err);
Michael Haggertycaa40462014-04-07 15:48:10 +02001026}
1027
Ronnie Sahlberg8c8bdc02014-04-16 15:27:45 -07001028int ref_transaction_delete(struct ref_transaction *transaction,
1029 const char *refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001030 const struct object_id *old_oid,
Michael Haggertyfb5a6bb2015-02-17 18:00:16 +01001031 unsigned int flags, const char *msg,
Ronnie Sahlberg8c8bdc02014-04-16 15:27:45 -07001032 struct strbuf *err)
Michael Haggertycaa40462014-04-07 15:48:10 +02001033{
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001034 if (old_oid && is_null_oid(old_oid))
1035 die("BUG: delete called with old_oid set to zeros");
Michael Haggerty1d147bd2015-02-17 18:00:15 +01001036 return ref_transaction_update(transaction, refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001037 &null_oid, old_oid,
Michael Haggerty1d147bd2015-02-17 18:00:15 +01001038 flags, msg, err);
Michael Haggertycaa40462014-04-07 15:48:10 +02001039}
1040
Michael Haggerty16180332015-02-17 18:00:21 +01001041int ref_transaction_verify(struct ref_transaction *transaction,
1042 const char *refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001043 const struct object_id *old_oid,
Michael Haggerty16180332015-02-17 18:00:21 +01001044 unsigned int flags,
1045 struct strbuf *err)
1046{
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001047 if (!old_oid)
1048 die("BUG: verify called with old_oid set to NULL");
Michael Haggerty16180332015-02-17 18:00:21 +01001049 return ref_transaction_update(transaction, refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001050 NULL, old_oid,
Michael Haggerty16180332015-02-17 18:00:21 +01001051 flags, NULL, err);
1052}
1053
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001054int refs_update_ref(struct ref_store *refs, const char *msg,
brian m. carlsonae077772017-10-15 22:06:51 +00001055 const char *refname, const struct object_id *new_oid,
1056 const struct object_id *old_oid, unsigned int flags,
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001057 enum action_on_err onerr)
Brad King4738a332013-09-04 11:22:40 -04001058{
David Turner74ec19d2015-07-31 02:06:19 -04001059 struct ref_transaction *t = NULL;
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001060 struct strbuf err = STRBUF_INIT;
David Turner74ec19d2015-07-31 02:06:19 -04001061 int ret = 0;
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001062
David Turner74ec19d2015-07-31 02:06:19 -04001063 if (ref_type(refname) == REF_TYPE_PSEUDOREF) {
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001064 assert(refs == get_main_ref_store(the_repository));
brian m. carlsonae077772017-10-15 22:06:51 +00001065 ret = write_pseudoref(refname, new_oid, old_oid, &err);
David Turner74ec19d2015-07-31 02:06:19 -04001066 } else {
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001067 t = ref_store_transaction_begin(refs, &err);
David Turner74ec19d2015-07-31 02:06:19 -04001068 if (!t ||
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001069 ref_transaction_update(t, refname, new_oid, old_oid,
David Turner74ec19d2015-07-31 02:06:19 -04001070 flags, msg, &err) ||
1071 ref_transaction_commit(t, &err)) {
1072 ret = 1;
1073 ref_transaction_free(t);
1074 }
1075 }
1076 if (ret) {
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001077 const char *str = "update_ref failed for ref '%s': %s";
1078
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001079 switch (onerr) {
1080 case UPDATE_REFS_MSG_ON_ERR:
1081 error(str, refname, err.buf);
1082 break;
1083 case UPDATE_REFS_DIE_ON_ERR:
1084 die(str, refname, err.buf);
1085 break;
1086 case UPDATE_REFS_QUIET_ON_ERR:
1087 break;
1088 }
1089 strbuf_release(&err);
Brad King4738a332013-09-04 11:22:40 -04001090 return 1;
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001091 }
1092 strbuf_release(&err);
David Turner74ec19d2015-07-31 02:06:19 -04001093 if (t)
1094 ref_transaction_free(t);
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001095 return 0;
Brad King4738a332013-09-04 11:22:40 -04001096}
1097
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001098int update_ref(const char *msg, const char *refname,
brian m. carlsonae077772017-10-15 22:06:51 +00001099 const struct object_id *new_oid,
1100 const struct object_id *old_oid,
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001101 unsigned int flags, enum action_on_err onerr)
1102{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001103 return refs_update_ref(get_main_ref_store(the_repository), msg, refname, new_oid,
brian m. carlsonae077772017-10-15 22:06:51 +00001104 old_oid, flags, onerr);
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001105}
1106
Michael Haggertydfefa932011-12-12 06:38:09 +01001107char *shorten_unambiguous_ref(const char *refname, int strict)
Jeff King7c2b3022009-04-07 03:14:20 -04001108{
1109 int i;
1110 static char **scanf_fmts;
1111 static int nr_rules;
1112 char *short_name;
Jeff King6cd4a892017-03-28 15:46:33 -04001113 struct strbuf resolved_buf = STRBUF_INIT;
Jeff King7c2b3022009-04-07 03:14:20 -04001114
Jeff King7c2b3022009-04-07 03:14:20 -04001115 if (!nr_rules) {
Michael Haggerty43466632014-01-08 15:43:39 +01001116 /*
1117 * Pre-generate scanf formats from ref_rev_parse_rules[].
1118 * Generate a format suitable for scanf from a
1119 * ref_rev_parse_rules rule by interpolating "%s" at the
1120 * location of the "%.*s".
1121 */
Jeff King7c2b3022009-04-07 03:14:20 -04001122 size_t total_len = 0;
Michael Haggerty84d56332014-01-08 15:43:38 +01001123 size_t offset = 0;
Jeff King7c2b3022009-04-07 03:14:20 -04001124
1125 /* the rule list is NULL terminated, count them first */
Jeff Kinga4165852013-10-24 04:45:13 -04001126 for (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++)
Michael Haggerty7902fe02014-01-08 15:43:40 +01001127 /* -2 for strlen("%.*s") - strlen("%s"); +1 for NUL */
1128 total_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 + 1;
Jeff King7c2b3022009-04-07 03:14:20 -04001129
René Scharfe50492f72016-07-30 20:18:31 +02001130 scanf_fmts = xmalloc(st_add(st_mult(sizeof(char *), nr_rules), total_len));
Jeff King7c2b3022009-04-07 03:14:20 -04001131
Michael Haggerty84d56332014-01-08 15:43:38 +01001132 offset = 0;
Jeff King7c2b3022009-04-07 03:14:20 -04001133 for (i = 0; i < nr_rules; i++) {
Michael Haggerty43466632014-01-08 15:43:39 +01001134 assert(offset < total_len);
Michael Haggerty84d56332014-01-08 15:43:38 +01001135 scanf_fmts[i] = (char *)&scanf_fmts[nr_rules] + offset;
Michael Haggerty43466632014-01-08 15:43:39 +01001136 offset += snprintf(scanf_fmts[i], total_len - offset,
1137 ref_rev_parse_rules[i], 2, "%s") + 1;
Jeff King7c2b3022009-04-07 03:14:20 -04001138 }
1139 }
1140
1141 /* bail out if there are no rules */
1142 if (!nr_rules)
Michael Haggertydfefa932011-12-12 06:38:09 +01001143 return xstrdup(refname);
Jeff King7c2b3022009-04-07 03:14:20 -04001144
Michael Haggertydfefa932011-12-12 06:38:09 +01001145 /* buffer for scanf result, at most refname must fit */
1146 short_name = xstrdup(refname);
Jeff King7c2b3022009-04-07 03:14:20 -04001147
1148 /* skip first rule, it will always match */
1149 for (i = nr_rules - 1; i > 0 ; --i) {
1150 int j;
Bert Wesarg6e7b3302009-04-13 12:25:46 +02001151 int rules_to_fail = i;
Jeff King7c2b3022009-04-07 03:14:20 -04001152 int short_name_len;
1153
Michael Haggertydfefa932011-12-12 06:38:09 +01001154 if (1 != sscanf(refname, scanf_fmts[i], short_name))
Jeff King7c2b3022009-04-07 03:14:20 -04001155 continue;
1156
1157 short_name_len = strlen(short_name);
1158
1159 /*
Bert Wesarg6e7b3302009-04-13 12:25:46 +02001160 * in strict mode, all (except the matched one) rules
1161 * must fail to resolve to a valid non-ambiguous ref
1162 */
1163 if (strict)
1164 rules_to_fail = nr_rules;
1165
1166 /*
Jeff King7c2b3022009-04-07 03:14:20 -04001167 * check if the short name resolves to a valid ref,
1168 * but use only rules prior to the matched one
1169 */
Bert Wesarg6e7b3302009-04-13 12:25:46 +02001170 for (j = 0; j < rules_to_fail; j++) {
Jeff King7c2b3022009-04-07 03:14:20 -04001171 const char *rule = ref_rev_parse_rules[j];
Jeff King7c2b3022009-04-07 03:14:20 -04001172
Bert Wesarg6e7b3302009-04-13 12:25:46 +02001173 /* skip matched rule */
1174 if (i == j)
1175 continue;
1176
Jeff King7c2b3022009-04-07 03:14:20 -04001177 /*
1178 * the short name is ambiguous, if it resolves
1179 * (with this previous rule) to a valid ref
1180 * read_ref() returns 0 on success
1181 */
Jeff King6cd4a892017-03-28 15:46:33 -04001182 strbuf_reset(&resolved_buf);
1183 strbuf_addf(&resolved_buf, rule,
1184 short_name_len, short_name);
1185 if (ref_exists(resolved_buf.buf))
Jeff King7c2b3022009-04-07 03:14:20 -04001186 break;
1187 }
1188
1189 /*
1190 * short name is non-ambiguous if all previous rules
1191 * haven't resolved to a valid ref
1192 */
Jeff King6cd4a892017-03-28 15:46:33 -04001193 if (j == rules_to_fail) {
1194 strbuf_release(&resolved_buf);
Jeff King7c2b3022009-04-07 03:14:20 -04001195 return short_name;
Jeff King6cd4a892017-03-28 15:46:33 -04001196 }
Jeff King7c2b3022009-04-07 03:14:20 -04001197 }
1198
Jeff King6cd4a892017-03-28 15:46:33 -04001199 strbuf_release(&resolved_buf);
Jeff King7c2b3022009-04-07 03:14:20 -04001200 free(short_name);
Michael Haggertydfefa932011-12-12 06:38:09 +01001201 return xstrdup(refname);
Jeff King7c2b3022009-04-07 03:14:20 -04001202}
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001203
1204static struct string_list *hide_refs;
1205
1206int parse_hide_refs_config(const char *var, const char *value, const char *section)
1207{
Jeff Kingad8c7cd2017-02-24 16:08:16 -05001208 const char *key;
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001209 if (!strcmp("transfer.hiderefs", var) ||
Jeff Kingad8c7cd2017-02-24 16:08:16 -05001210 (!parse_config_key(var, section, NULL, NULL, &key) &&
1211 !strcmp(key, "hiderefs"))) {
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001212 char *ref;
1213 int len;
1214
1215 if (!value)
1216 return config_error_nonbool(var);
1217 ref = xstrdup(value);
1218 len = strlen(ref);
1219 while (len && ref[len - 1] == '/')
1220 ref[--len] = '\0';
1221 if (!hide_refs) {
1222 hide_refs = xcalloc(1, sizeof(*hide_refs));
1223 hide_refs->strdup_strings = 1;
1224 }
1225 string_list_append(hide_refs, ref);
1226 }
1227 return 0;
1228}
1229
Lukas Fleischer78a766a2015-11-03 08:58:16 +01001230int ref_is_hidden(const char *refname, const char *refname_full)
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001231{
Jeff King2bc31d12015-07-28 16:23:26 -04001232 int i;
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001233
1234 if (!hide_refs)
1235 return 0;
Jeff King2bc31d12015-07-28 16:23:26 -04001236 for (i = hide_refs->nr - 1; i >= 0; i--) {
1237 const char *match = hide_refs->items[i].string;
Lukas Fleischer78a766a2015-11-03 08:58:16 +01001238 const char *subject;
Jeff King2bc31d12015-07-28 16:23:26 -04001239 int neg = 0;
Christian Couder7a40a952017-07-22 06:39:12 +02001240 const char *p;
Jeff King2bc31d12015-07-28 16:23:26 -04001241
1242 if (*match == '!') {
1243 neg = 1;
1244 match++;
1245 }
1246
Lukas Fleischer78a766a2015-11-03 08:58:16 +01001247 if (*match == '^') {
1248 subject = refname_full;
1249 match++;
1250 } else {
1251 subject = refname;
1252 }
1253
1254 /* refname can be NULL when namespaces are used. */
Christian Couder7a40a952017-07-22 06:39:12 +02001255 if (subject &&
1256 skip_prefix(subject, match, &p) &&
1257 (!*p || *p == '/'))
Jeff King2bc31d12015-07-28 16:23:26 -04001258 return !neg;
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001259 }
1260 return 0;
1261}
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001262
David Turner08451222015-11-10 12:42:40 +01001263const char *find_descendant_ref(const char *dirname,
1264 const struct string_list *extras,
1265 const struct string_list *skip)
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001266{
David Turner08451222015-11-10 12:42:40 +01001267 int pos;
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001268
David Turner08451222015-11-10 12:42:40 +01001269 if (!extras)
1270 return NULL;
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001271
1272 /*
David Turner08451222015-11-10 12:42:40 +01001273 * Look at the place where dirname would be inserted into
1274 * extras. If there is an entry at that position that starts
1275 * with dirname (remember, dirname includes the trailing
1276 * slash) and is not in skip, then we have a conflict.
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001277 */
David Turner08451222015-11-10 12:42:40 +01001278 for (pos = string_list_find_insert_index(extras, dirname, 0);
1279 pos < extras->nr; pos++) {
1280 const char *extra_refname = extras->items[pos].string;
1281
1282 if (!starts_with(extra_refname, dirname))
1283 break;
1284
1285 if (!skip || !string_list_has_string(skip, extra_refname))
1286 return extra_refname;
Michael Haggerty4a32b2e2015-05-11 17:25:15 +02001287 }
David Turner08451222015-11-10 12:42:40 +01001288 return NULL;
1289}
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001290
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001291int refs_rename_ref_available(struct ref_store *refs,
1292 const char *old_refname,
1293 const char *new_refname)
David Turner08451222015-11-10 12:42:40 +01001294{
1295 struct string_list skip = STRING_LIST_INIT_NODUP;
1296 struct strbuf err = STRBUF_INIT;
David Turnerff3a2992016-09-04 18:08:08 +02001297 int ok;
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001298
David Turnerff3a2992016-09-04 18:08:08 +02001299 string_list_insert(&skip, old_refname);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001300 ok = !refs_verify_refname_available(refs, new_refname,
1301 NULL, &skip, &err);
David Turnerff3a2992016-09-04 18:08:08 +02001302 if (!ok)
David Turner08451222015-11-10 12:42:40 +01001303 error("%s", err.buf);
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001304
David Turner08451222015-11-10 12:42:40 +01001305 string_list_clear(&skip, 0);
1306 strbuf_release(&err);
David Turnerff3a2992016-09-04 18:08:08 +02001307 return ok;
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001308}
David Turner2bf68ed2016-04-07 15:02:48 -04001309
Nguyễn Thái Ngọc Duy62f0b392017-08-23 19:36:55 +07001310int refs_head_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
David Turner2bf68ed2016-04-07 15:02:48 -04001311{
1312 struct object_id oid;
1313 int flag;
1314
Nguyễn Thái Ngọc Duy62f0b392017-08-23 19:36:55 +07001315 if (!refs_read_ref_full(refs, "HEAD", RESOLVE_REF_READING,
brian m. carlson34c290a2017-10-15 22:06:56 +00001316 &oid, &flag))
David Turner2bf68ed2016-04-07 15:02:48 -04001317 return fn("HEAD", &oid, flag, cb_data);
1318
1319 return 0;
1320}
1321
1322int head_ref(each_ref_fn fn, void *cb_data)
1323{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001324 return refs_head_ref(get_main_ref_store(the_repository), fn, cb_data);
David Turner2bf68ed2016-04-07 15:02:48 -04001325}
David Turner93770592016-04-07 15:02:49 -04001326
Michael Haggertye121b9c2017-03-20 17:33:08 +01001327struct ref_iterator *refs_ref_iterator_begin(
1328 struct ref_store *refs,
1329 const char *prefix, int trim, int flags)
1330{
1331 struct ref_iterator *iter;
1332
Michael Haggerty0a0865b2017-05-22 16:17:52 +02001333 if (ref_paranoia < 0)
1334 ref_paranoia = git_env_bool("GIT_REF_PARANOIA", 0);
1335 if (ref_paranoia)
1336 flags |= DO_FOR_EACH_INCLUDE_BROKEN;
1337
Michael Haggertye121b9c2017-03-20 17:33:08 +01001338 iter = refs->be->iterator_begin(refs, prefix, flags);
Michael Haggertyc7599712017-05-22 16:17:36 +02001339
1340 /*
1341 * `iterator_begin()` already takes care of prefix, but we
1342 * might need to do some trimming:
1343 */
1344 if (trim)
1345 iter = prefix_ref_iterator_begin(iter, "", trim);
Michael Haggertye121b9c2017-03-20 17:33:08 +01001346
Michael Haggerty8738a8a2017-09-13 19:15:55 +02001347 /* Sanity check for subclasses: */
1348 if (!iter->ordered)
1349 BUG("reference iterator is not ordered");
1350
Michael Haggertye121b9c2017-03-20 17:33:08 +01001351 return iter;
1352}
1353
Michael Haggerty4c4de892016-06-18 06:15:16 +02001354/*
1355 * Call fn for each reference in the specified submodule for which the
1356 * refname begins with prefix. If trim is non-zero, then trim that
1357 * many characters off the beginning of each refname before passing
1358 * the refname to fn. flags can be DO_FOR_EACH_INCLUDE_BROKEN to
1359 * include broken references in the iteration. If fn ever returns a
1360 * non-zero value, stop the iteration and return that value;
1361 * otherwise, return 0.
1362 */
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001363static int do_for_each_ref(struct ref_store *refs, const char *prefix,
Michael Haggerty4c4de892016-06-18 06:15:16 +02001364 each_ref_fn fn, int trim, int flags, void *cb_data)
1365{
1366 struct ref_iterator *iter;
1367
Michael Haggerty00eebe32016-09-04 18:08:11 +02001368 if (!refs)
1369 return 0;
1370
Michael Haggertye121b9c2017-03-20 17:33:08 +01001371 iter = refs_ref_iterator_begin(refs, prefix, trim, flags);
Michael Haggerty4c4de892016-06-18 06:15:16 +02001372
1373 return do_for_each_ref_iterator(iter, fn, cb_data);
1374}
1375
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001376int refs_for_each_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
1377{
1378 return do_for_each_ref(refs, "", fn, 0, 0, cb_data);
1379}
1380
David Turner93770592016-04-07 15:02:49 -04001381int for_each_ref(each_ref_fn fn, void *cb_data)
1382{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001383 return refs_for_each_ref(get_main_ref_store(the_repository), fn, cb_data);
David Turner93770592016-04-07 15:02:49 -04001384}
1385
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001386int refs_for_each_ref_in(struct ref_store *refs, const char *prefix,
1387 each_ref_fn fn, void *cb_data)
1388{
1389 return do_for_each_ref(refs, prefix, fn, strlen(prefix), 0, cb_data);
David Turner93770592016-04-07 15:02:49 -04001390}
1391
1392int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
1393{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001394 return refs_for_each_ref_in(get_main_ref_store(the_repository), prefix, fn, cb_data);
David Turner93770592016-04-07 15:02:49 -04001395}
1396
1397int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken)
1398{
1399 unsigned int flag = 0;
1400
1401 if (broken)
1402 flag = DO_FOR_EACH_INCLUDE_BROKEN;
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001403 return do_for_each_ref(get_main_ref_store(the_repository),
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001404 prefix, fn, 0, flag, cb_data);
David Turner93770592016-04-07 15:02:49 -04001405}
1406
Nguyễn Thái Ngọc Duy073cf632017-08-23 19:36:56 +07001407int refs_for_each_fullref_in(struct ref_store *refs, const char *prefix,
1408 each_ref_fn fn, void *cb_data,
1409 unsigned int broken)
Michael Haggerty03df5672017-06-18 15:39:41 +02001410{
1411 unsigned int flag = 0;
1412
1413 if (broken)
1414 flag = DO_FOR_EACH_INCLUDE_BROKEN;
Nguyễn Thái Ngọc Duy073cf632017-08-23 19:36:56 +07001415 return do_for_each_ref(refs, prefix, fn, 0, flag, cb_data);
Michael Haggerty03df5672017-06-18 15:39:41 +02001416}
1417
Stefan Beller0d296c52018-04-11 17:21:15 -07001418int for_each_replace_ref(struct repository *r, each_ref_fn fn, void *cb_data)
David Turner93770592016-04-07 15:02:49 -04001419{
Stefan Beller0d296c52018-04-11 17:21:15 -07001420 return do_for_each_ref(get_main_ref_store(r),
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001421 git_replace_ref_base, fn,
1422 strlen(git_replace_ref_base),
Stefan Beller006f3f22017-09-12 10:31:40 -07001423 DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
David Turner93770592016-04-07 15:02:49 -04001424}
1425
1426int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
1427{
1428 struct strbuf buf = STRBUF_INIT;
1429 int ret;
1430 strbuf_addf(&buf, "%srefs/", get_git_namespace());
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001431 ret = do_for_each_ref(get_main_ref_store(the_repository),
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001432 buf.buf, fn, 0, 0, cb_data);
David Turner93770592016-04-07 15:02:49 -04001433 strbuf_release(&buf);
1434 return ret;
1435}
1436
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001437int refs_for_each_rawref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
David Turner93770592016-04-07 15:02:49 -04001438{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001439 return do_for_each_ref(refs, "", fn, 0,
David Turner93770592016-04-07 15:02:49 -04001440 DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
1441}
David Turner2d0663b2016-04-07 15:03:10 -04001442
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001443int for_each_rawref(each_ref_fn fn, void *cb_data)
1444{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001445 return refs_for_each_rawref(get_main_ref_store(the_repository), fn, cb_data);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001446}
1447
Michael Haggerty470be512017-03-20 17:33:07 +01001448int refs_read_raw_ref(struct ref_store *ref_store,
brian m. carlson99afe912017-10-15 22:07:11 +00001449 const char *refname, struct object_id *oid,
Michael Haggerty470be512017-03-20 17:33:07 +01001450 struct strbuf *referent, unsigned int *type)
1451{
brian m. carlson99afe912017-10-15 22:07:11 +00001452 return ref_store->be->read_raw_ref(ref_store, refname, oid, referent, type);
Michael Haggerty470be512017-03-20 17:33:07 +01001453}
1454
David Turner2d0663b2016-04-07 15:03:10 -04001455/* This function needs to return a meaningful errno on failure */
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001456const char *refs_resolve_ref_unsafe(struct ref_store *refs,
Michael Haggerty3c0cb0c2017-02-09 21:53:52 +01001457 const char *refname,
1458 int resolve_flags,
brian m. carlson49e61472017-10-15 22:07:09 +00001459 struct object_id *oid, int *flags)
David Turner2d0663b2016-04-07 15:03:10 -04001460{
1461 static struct strbuf sb_refname = STRBUF_INIT;
René Scharfe54fad662017-09-23 11:41:45 +02001462 struct object_id unused_oid;
David Turner2d0663b2016-04-07 15:03:10 -04001463 int unused_flags;
1464 int symref_count;
1465
brian m. carlson49e61472017-10-15 22:07:09 +00001466 if (!oid)
1467 oid = &unused_oid;
David Turner2d0663b2016-04-07 15:03:10 -04001468 if (!flags)
1469 flags = &unused_flags;
1470
1471 *flags = 0;
1472
1473 if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
1474 if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
1475 !refname_is_safe(refname)) {
1476 errno = EINVAL;
1477 return NULL;
1478 }
1479
1480 /*
1481 * dwim_ref() uses REF_ISBROKEN to distinguish between
1482 * missing refs and refs that were present but invalid,
1483 * to complain about the latter to stderr.
1484 *
1485 * We don't know whether the ref exists, so don't set
1486 * REF_ISBROKEN yet.
1487 */
1488 *flags |= REF_BAD_NAME;
1489 }
1490
1491 for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) {
1492 unsigned int read_flags = 0;
1493
Michael Haggerty470be512017-03-20 17:33:07 +01001494 if (refs_read_raw_ref(refs, refname,
brian m. carlson99afe912017-10-15 22:07:11 +00001495 oid, &sb_refname, &read_flags)) {
David Turner2d0663b2016-04-07 15:03:10 -04001496 *flags |= read_flags;
Jeff Kinga1c1d812017-10-06 10:42:17 -04001497
1498 /* In reading mode, refs must eventually resolve */
1499 if (resolve_flags & RESOLVE_REF_READING)
David Turner2d0663b2016-04-07 15:03:10 -04001500 return NULL;
Jeff Kinga1c1d812017-10-06 10:42:17 -04001501
1502 /*
1503 * Otherwise a missing ref is OK. But the files backend
1504 * may show errors besides ENOENT if there are
1505 * similarly-named refs.
1506 */
1507 if (errno != ENOENT &&
1508 errno != EISDIR &&
1509 errno != ENOTDIR)
1510 return NULL;
1511
brian m. carlson49e61472017-10-15 22:07:09 +00001512 oidclr(oid);
David Turner2d0663b2016-04-07 15:03:10 -04001513 if (*flags & REF_BAD_NAME)
1514 *flags |= REF_ISBROKEN;
1515 return refname;
1516 }
1517
1518 *flags |= read_flags;
1519
1520 if (!(read_flags & REF_ISSYMREF)) {
1521 if (*flags & REF_BAD_NAME) {
brian m. carlson49e61472017-10-15 22:07:09 +00001522 oidclr(oid);
David Turner2d0663b2016-04-07 15:03:10 -04001523 *flags |= REF_ISBROKEN;
1524 }
1525 return refname;
1526 }
1527
1528 refname = sb_refname.buf;
1529 if (resolve_flags & RESOLVE_REF_NO_RECURSE) {
brian m. carlson49e61472017-10-15 22:07:09 +00001530 oidclr(oid);
David Turner2d0663b2016-04-07 15:03:10 -04001531 return refname;
1532 }
1533 if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
1534 if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
1535 !refname_is_safe(refname)) {
1536 errno = EINVAL;
1537 return NULL;
1538 }
1539
1540 *flags |= REF_ISBROKEN | REF_BAD_NAME;
1541 }
1542 }
1543
1544 errno = ELOOP;
1545 return NULL;
1546}
Michael Haggerty00eebe32016-09-04 18:08:11 +02001547
David Turner6fb5acf2016-09-04 18:08:41 +02001548/* backend functions */
1549int refs_init_db(struct strbuf *err)
1550{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001551 struct ref_store *refs = get_main_ref_store(the_repository);
David Turner6fb5acf2016-09-04 18:08:41 +02001552
1553 return refs->be->init_db(refs, err);
1554}
1555
Michael Haggertybd40dcd2016-09-04 18:08:21 +02001556const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
brian m. carlson49e61472017-10-15 22:07:09 +00001557 struct object_id *oid, int *flags)
Michael Haggertybd40dcd2016-09-04 18:08:21 +02001558{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001559 return refs_resolve_ref_unsafe(get_main_ref_store(the_repository), refname,
brian m. carlson49e61472017-10-15 22:07:09 +00001560 resolve_flags, oid, flags);
Michael Haggertybd40dcd2016-09-04 18:08:21 +02001561}
1562
Michael Haggertya8355bb2016-09-04 18:08:24 +02001563int resolve_gitlink_ref(const char *submodule, const char *refname,
brian m. carlsona98e6102017-10-15 22:07:07 +00001564 struct object_id *oid)
Michael Haggerty424dcc72016-09-04 18:08:22 +02001565{
Michael Haggerty424dcc72016-09-04 18:08:22 +02001566 struct ref_store *refs;
1567 int flags;
1568
Nguyễn Thái Ngọc Duy29babbe2017-08-23 19:36:54 +07001569 refs = get_submodule_ref_store(submodule);
Michael Haggerty48a84752016-09-04 18:08:23 +02001570
Michael Haggerty424dcc72016-09-04 18:08:22 +02001571 if (!refs)
1572 return -1;
1573
brian m. carlson49e61472017-10-15 22:07:09 +00001574 if (!refs_resolve_ref_unsafe(refs, refname, 0, oid, &flags) ||
brian m. carlsona98e6102017-10-15 22:07:07 +00001575 is_null_oid(oid))
Michael Haggerty424dcc72016-09-04 18:08:22 +02001576 return -1;
1577 return 0;
1578}
1579
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001580struct ref_store_hash_entry
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001581{
1582 struct hashmap_entry ent; /* must be the first member! */
1583
1584 struct ref_store *refs;
1585
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001586 /* NUL-terminated identifier of the ref store: */
1587 char name[FLEX_ARRAY];
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001588};
1589
Stefan Beller7663cdc2017-06-30 12:14:05 -07001590static int ref_store_hash_cmp(const void *unused_cmp_data,
1591 const void *entry, const void *entry_or_key,
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001592 const void *keydata)
1593{
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001594 const struct ref_store_hash_entry *e1 = entry, *e2 = entry_or_key;
1595 const char *name = keydata ? keydata : e2->name;
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001596
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001597 return strcmp(e1->name, name);
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001598}
1599
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001600static struct ref_store_hash_entry *alloc_ref_store_hash_entry(
1601 const char *name, struct ref_store *refs)
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001602{
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001603 struct ref_store_hash_entry *entry;
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001604
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001605 FLEX_ALLOC_STR(entry, name, name);
1606 hashmap_entry_init(entry, strhash(name));
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001607 entry->refs = refs;
1608 return entry;
1609}
1610
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001611/* A hashmap of ref_stores, stored by submodule name: */
1612static struct hashmap submodule_ref_stores;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001613
Nguyễn Thái Ngọc Duy17eff962017-04-24 17:01:22 +07001614/* A hashmap of ref_stores, stored by worktree id: */
1615static struct hashmap worktree_ref_stores;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001616
Michael Haggerty00eebe32016-09-04 18:08:11 +02001617/*
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001618 * Look up a ref store by name. If that ref_store hasn't been
1619 * registered yet, return NULL.
Michael Haggerty00eebe32016-09-04 18:08:11 +02001620 */
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001621static struct ref_store *lookup_ref_store_map(struct hashmap *map,
1622 const char *name)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001623{
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001624 struct ref_store_hash_entry *entry;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001625
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001626 if (!map->tablesize)
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001627 /* It's initialized on demand in register_ref_store(). */
1628 return NULL;
Michael Haggerty620a66b2017-02-10 12:16:11 +01001629
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001630 entry = hashmap_get_from_hash(map, strhash(name), name);
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001631 return entry ? entry->refs : NULL;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001632}
1633
Michael Haggertyc468da42017-02-10 12:16:12 +01001634/*
1635 * Create, record, and return a ref_store instance for the specified
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +07001636 * gitdir.
Michael Haggertyc468da42017-02-10 12:16:12 +01001637 */
Nguyễn Thái Ngọc Duy9e7ec632017-03-26 09:42:32 +07001638static struct ref_store *ref_store_init(const char *gitdir,
1639 unsigned int flags)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001640{
1641 const char *be_name = "files";
1642 struct ref_storage_be *be = find_ref_storage_backend(be_name);
Michael Haggertyba88add2017-02-10 12:16:14 +01001643 struct ref_store *refs;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001644
1645 if (!be)
1646 die("BUG: reference backend %s is unknown", be_name);
1647
Nguyễn Thái Ngọc Duy9e7ec632017-03-26 09:42:32 +07001648 refs = be->init(gitdir, flags);
Michael Haggertyba88add2017-02-10 12:16:14 +01001649 return refs;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001650}
1651
Stefan Beller64a74162018-04-11 17:21:14 -07001652struct ref_store *get_main_ref_store(struct repository *r)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001653{
Stefan Beller64a74162018-04-11 17:21:14 -07001654 if (r->refs)
1655 return r->refs;
Nguyễn Thái Ngọc Duy24c84072017-03-26 09:42:25 +07001656
Stefan Beller64a74162018-04-11 17:21:14 -07001657 r->refs = ref_store_init(r->gitdir, REF_STORE_ALL_CAPS);
1658 return r->refs;
Nguyễn Thái Ngọc Duy378dc912017-03-26 09:42:28 +07001659}
1660
1661/*
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001662 * Associate a ref store with a name. It is a fatal error to call this
1663 * function twice for the same name.
Nguyễn Thái Ngọc Duy378dc912017-03-26 09:42:28 +07001664 */
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001665static void register_ref_store_map(struct hashmap *map,
1666 const char *type,
1667 struct ref_store *refs,
1668 const char *name)
Nguyễn Thái Ngọc Duy378dc912017-03-26 09:42:28 +07001669{
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001670 if (!map->tablesize)
Stefan Beller7663cdc2017-06-30 12:14:05 -07001671 hashmap_init(map, ref_store_hash_cmp, NULL, 0);
Nguyễn Thái Ngọc Duy378dc912017-03-26 09:42:28 +07001672
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001673 if (hashmap_put(map, alloc_ref_store_hash_entry(name, refs)))
1674 die("BUG: %s ref_store '%s' initialized twice", type, name);
Nguyễn Thái Ngọc Duy24c84072017-03-26 09:42:25 +07001675}
1676
Nguyễn Thái Ngọc Duy18d00022017-03-26 09:42:33 +07001677struct ref_store *get_submodule_ref_store(const char *submodule)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001678{
Nguyễn Thái Ngọc Duy126c9e02017-03-26 09:42:27 +07001679 struct strbuf submodule_sb = STRBUF_INIT;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001680 struct ref_store *refs;
Nguyễn Thái Ngọc Duy29babbe2017-08-23 19:36:54 +07001681 char *to_free = NULL;
1682 size_t len;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001683
Nguyễn Thái Ngọc Duy82a150f2017-08-23 19:37:03 +07001684 if (!submodule)
1685 return NULL;
1686
Nguyễn Thái Ngọc Duy873ea902017-08-23 19:37:04 +07001687 len = strlen(submodule);
1688 while (len && is_dir_sep(submodule[len - 1]))
1689 len--;
1690 if (!len)
1691 return NULL;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001692
Nguyễn Thái Ngọc Duy29babbe2017-08-23 19:36:54 +07001693 if (submodule[len])
1694 /* We need to strip off one or more trailing slashes */
1695 submodule = to_free = xmemdupz(submodule, len);
Michael Haggerty00eebe32016-09-04 18:08:11 +02001696
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001697 refs = lookup_ref_store_map(&submodule_ref_stores, submodule);
Nguyễn Thái Ngọc Duy126c9e02017-03-26 09:42:27 +07001698 if (refs)
Nguyễn Thái Ngọc Duy2c616c12017-08-23 19:36:53 +07001699 goto done;
Nguyễn Thái Ngọc Duy126c9e02017-03-26 09:42:27 +07001700
1701 strbuf_addstr(&submodule_sb, submodule);
Nguyễn Thái Ngọc Duy2c616c12017-08-23 19:36:53 +07001702 if (!is_nonbare_repository_dir(&submodule_sb))
1703 goto done;
Nguyễn Thái Ngọc Duy126c9e02017-03-26 09:42:27 +07001704
Nguyễn Thái Ngọc Duy2c616c12017-08-23 19:36:53 +07001705 if (submodule_to_gitdir(&submodule_sb, submodule))
1706 goto done;
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +07001707
Nguyễn Thái Ngọc Duy9e7ec632017-03-26 09:42:32 +07001708 /* assume that add_submodule_odb() has been called */
1709 refs = ref_store_init(submodule_sb.buf,
1710 REF_STORE_READ | REF_STORE_ODB);
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001711 register_ref_store_map(&submodule_ref_stores, "submodule",
1712 refs, submodule);
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +07001713
Nguyễn Thái Ngọc Duy2c616c12017-08-23 19:36:53 +07001714done:
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +07001715 strbuf_release(&submodule_sb);
Nguyễn Thái Ngọc Duy29babbe2017-08-23 19:36:54 +07001716 free(to_free);
1717
Michael Haggerty00eebe32016-09-04 18:08:11 +02001718 return refs;
1719}
1720
Nguyễn Thái Ngọc Duy17eff962017-04-24 17:01:22 +07001721struct ref_store *get_worktree_ref_store(const struct worktree *wt)
1722{
1723 struct ref_store *refs;
1724 const char *id;
1725
1726 if (wt->is_current)
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001727 return get_main_ref_store(the_repository);
Nguyễn Thái Ngọc Duy17eff962017-04-24 17:01:22 +07001728
1729 id = wt->id ? wt->id : "/";
1730 refs = lookup_ref_store_map(&worktree_ref_stores, id);
1731 if (refs)
1732 return refs;
1733
1734 if (wt->id)
1735 refs = ref_store_init(git_common_path("worktrees/%s", wt->id),
1736 REF_STORE_ALL_CAPS);
1737 else
1738 refs = ref_store_init(get_git_common_dir(),
1739 REF_STORE_ALL_CAPS);
1740
1741 if (refs)
1742 register_ref_store_map(&worktree_ref_stores, "worktree",
1743 refs, id);
1744 return refs;
1745}
1746
Michael Haggerty620a66b2017-02-10 12:16:11 +01001747void base_ref_store_init(struct ref_store *refs,
Michael Haggertyfbfd0a22017-02-10 12:16:17 +01001748 const struct ref_storage_be *be)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001749{
Michael Haggerty620a66b2017-02-10 12:16:11 +01001750 refs->be = be;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001751}
Ronnie Sahlberg127b42a2016-09-04 18:08:16 +02001752
1753/* backend functions */
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001754int refs_pack_refs(struct ref_store *refs, unsigned int flags)
Michael Haggerty82315272016-09-04 18:08:27 +02001755{
Michael Haggerty82315272016-09-04 18:08:27 +02001756 return refs->be->pack_refs(refs, flags);
1757}
1758
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001759int refs_peel_ref(struct ref_store *refs, const char *refname,
brian m. carlsonb420d902017-10-15 22:07:02 +00001760 struct object_id *oid)
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001761{
Michael Haggertyba1c0522017-09-25 10:00:14 +02001762 int flag;
brian m. carlson34c290a2017-10-15 22:06:56 +00001763 struct object_id base;
Michael Haggertyba1c0522017-09-25 10:00:14 +02001764
1765 if (current_ref_iter && current_ref_iter->refname == refname) {
1766 struct object_id peeled;
1767
1768 if (ref_iterator_peel(current_ref_iter, &peeled))
1769 return -1;
brian m. carlsonb420d902017-10-15 22:07:02 +00001770 oidcpy(oid, &peeled);
Michael Haggertyba1c0522017-09-25 10:00:14 +02001771 return 0;
1772 }
1773
1774 if (refs_read_ref_full(refs, refname,
brian m. carlson34c290a2017-10-15 22:06:56 +00001775 RESOLVE_REF_READING, &base, &flag))
Michael Haggertyba1c0522017-09-25 10:00:14 +02001776 return -1;
1777
brian m. carlsonac2ed0d2017-10-15 22:07:10 +00001778 return peel_object(&base, oid);
Ronnie Sahlberg127b42a2016-09-04 18:08:16 +02001779}
1780
brian m. carlsonb420d902017-10-15 22:07:02 +00001781int peel_ref(const char *refname, struct object_id *oid)
Michael Haggertybd427cf2016-09-04 18:08:29 +02001782{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001783 return refs_peel_ref(get_main_ref_store(the_repository), refname, oid);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001784}
Michael Haggertybd427cf2016-09-04 18:08:29 +02001785
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001786int refs_create_symref(struct ref_store *refs,
1787 const char *ref_target,
1788 const char *refs_heads_master,
1789 const char *logmsg)
1790{
1791 return refs->be->create_symref(refs, ref_target,
1792 refs_heads_master,
1793 logmsg);
Michael Haggertybd427cf2016-09-04 18:08:29 +02001794}
1795
Michael Haggerty284689b2016-09-04 18:08:28 +02001796int create_symref(const char *ref_target, const char *refs_heads_master,
1797 const char *logmsg)
1798{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001799 return refs_create_symref(get_main_ref_store(the_repository), ref_target,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001800 refs_heads_master, logmsg);
Michael Haggerty284689b2016-09-04 18:08:28 +02001801}
1802
Michael Haggerty2ced1052017-05-22 16:17:45 +02001803int ref_update_reject_duplicates(struct string_list *refnames,
1804 struct strbuf *err)
1805{
Michael Haggertya552e502017-05-22 16:17:46 +02001806 size_t i, n = refnames->nr;
Michael Haggerty2ced1052017-05-22 16:17:45 +02001807
1808 assert(err);
1809
Michael Haggerty8556f8d2017-05-22 16:17:47 +02001810 for (i = 1; i < n; i++) {
1811 int cmp = strcmp(refnames->items[i - 1].string,
1812 refnames->items[i].string);
1813
1814 if (!cmp) {
Michael Haggerty2ced1052017-05-22 16:17:45 +02001815 strbuf_addf(err,
1816 "multiple updates for ref '%s' not allowed.",
1817 refnames->items[i].string);
1818 return 1;
Michael Haggerty8556f8d2017-05-22 16:17:47 +02001819 } else if (cmp > 0) {
1820 die("BUG: ref_update_reject_duplicates() received unsorted list");
Michael Haggerty2ced1052017-05-22 16:17:45 +02001821 }
Michael Haggerty8556f8d2017-05-22 16:17:47 +02001822 }
Michael Haggerty2ced1052017-05-22 16:17:45 +02001823 return 0;
1824}
1825
Michael Haggerty30173b82017-05-22 16:17:44 +02001826int ref_transaction_prepare(struct ref_transaction *transaction,
1827 struct strbuf *err)
Daniel Barkalow95fc7512005-06-06 16:31:29 -04001828{
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001829 struct ref_store *refs = transaction->ref_store;
Daniel Barkalow95fc7512005-06-06 16:31:29 -04001830
Michael Haggerty8d4240d2017-05-22 16:17:43 +02001831 switch (transaction->state) {
1832 case REF_TRANSACTION_OPEN:
1833 /* Good. */
1834 break;
Michael Haggerty30173b82017-05-22 16:17:44 +02001835 case REF_TRANSACTION_PREPARED:
1836 die("BUG: prepare called twice on reference transaction");
1837 break;
Michael Haggerty8d4240d2017-05-22 16:17:43 +02001838 case REF_TRANSACTION_CLOSED:
1839 die("BUG: prepare called on a closed reference transaction");
1840 break;
1841 default:
1842 die("BUG: unexpected reference transaction state");
1843 break;
1844 }
1845
Jeff Kingd8f44812017-04-10 18:14:12 -04001846 if (getenv(GIT_QUARANTINE_ENVIRONMENT)) {
1847 strbuf_addstr(err,
1848 _("ref updates forbidden inside quarantine environment"));
1849 return -1;
1850 }
1851
Michael Haggerty30173b82017-05-22 16:17:44 +02001852 return refs->be->transaction_prepare(refs, transaction, err);
1853}
1854
1855int ref_transaction_abort(struct ref_transaction *transaction,
1856 struct strbuf *err)
1857{
1858 struct ref_store *refs = transaction->ref_store;
1859 int ret = 0;
1860
1861 switch (transaction->state) {
1862 case REF_TRANSACTION_OPEN:
1863 /* No need to abort explicitly. */
1864 break;
1865 case REF_TRANSACTION_PREPARED:
1866 ret = refs->be->transaction_abort(refs, transaction, err);
1867 break;
1868 case REF_TRANSACTION_CLOSED:
1869 die("BUG: abort called on a closed reference transaction");
1870 break;
1871 default:
1872 die("BUG: unexpected reference transaction state");
1873 break;
1874 }
1875
1876 ref_transaction_free(transaction);
1877 return ret;
1878}
1879
1880int ref_transaction_commit(struct ref_transaction *transaction,
1881 struct strbuf *err)
1882{
1883 struct ref_store *refs = transaction->ref_store;
1884 int ret;
1885
1886 switch (transaction->state) {
1887 case REF_TRANSACTION_OPEN:
1888 /* Need to prepare first. */
1889 ret = ref_transaction_prepare(transaction, err);
1890 if (ret)
1891 return ret;
1892 break;
1893 case REF_TRANSACTION_PREPARED:
1894 /* Fall through to finish. */
1895 break;
1896 case REF_TRANSACTION_CLOSED:
1897 die("BUG: commit called on a closed reference transaction");
1898 break;
1899 default:
1900 die("BUG: unexpected reference transaction state");
1901 break;
1902 }
1903
1904 return refs->be->transaction_finish(refs, transaction, err);
Daniel Barkalow95fc7512005-06-06 16:31:29 -04001905}
Michael Haggerty62665822016-09-04 18:08:26 +02001906
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001907int refs_verify_refname_available(struct ref_store *refs,
1908 const char *refname,
Michael Haggertyb05855b2017-04-16 08:41:26 +02001909 const struct string_list *extras,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001910 const struct string_list *skip,
1911 struct strbuf *err)
Michael Haggerty62665822016-09-04 18:08:26 +02001912{
Michael Haggertyb05855b2017-04-16 08:41:26 +02001913 const char *slash;
1914 const char *extra_refname;
1915 struct strbuf dirname = STRBUF_INIT;
1916 struct strbuf referent = STRBUF_INIT;
1917 struct object_id oid;
1918 unsigned int type;
1919 struct ref_iterator *iter;
1920 int ok;
1921 int ret = -1;
1922
1923 /*
1924 * For the sake of comments in this function, suppose that
1925 * refname is "refs/foo/bar".
1926 */
1927
1928 assert(err);
1929
1930 strbuf_grow(&dirname, strlen(refname) + 1);
1931 for (slash = strchr(refname, '/'); slash; slash = strchr(slash + 1, '/')) {
1932 /* Expand dirname to the new prefix, not including the trailing slash: */
1933 strbuf_add(&dirname, refname + dirname.len, slash - refname - dirname.len);
1934
1935 /*
1936 * We are still at a leading dir of the refname (e.g.,
1937 * "refs/foo"; if there is a reference with that name,
1938 * it is a conflict, *unless* it is in skip.
1939 */
1940 if (skip && string_list_has_string(skip, dirname.buf))
1941 continue;
1942
brian m. carlson99afe912017-10-15 22:07:11 +00001943 if (!refs_read_raw_ref(refs, dirname.buf, &oid, &referent, &type)) {
Michael Haggertyb05855b2017-04-16 08:41:26 +02001944 strbuf_addf(err, "'%s' exists; cannot create '%s'",
1945 dirname.buf, refname);
1946 goto cleanup;
1947 }
1948
1949 if (extras && string_list_has_string(extras, dirname.buf)) {
1950 strbuf_addf(err, "cannot process '%s' and '%s' at the same time",
1951 refname, dirname.buf);
1952 goto cleanup;
1953 }
1954 }
1955
1956 /*
1957 * We are at the leaf of our refname (e.g., "refs/foo/bar").
1958 * There is no point in searching for a reference with that
1959 * name, because a refname isn't considered to conflict with
1960 * itself. But we still need to check for references whose
1961 * names are in the "refs/foo/bar/" namespace, because they
1962 * *do* conflict.
1963 */
1964 strbuf_addstr(&dirname, refname + dirname.len);
1965 strbuf_addch(&dirname, '/');
1966
1967 iter = refs_ref_iterator_begin(refs, dirname.buf, 0,
1968 DO_FOR_EACH_INCLUDE_BROKEN);
1969 while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
1970 if (skip &&
1971 string_list_has_string(skip, iter->refname))
1972 continue;
1973
1974 strbuf_addf(err, "'%s' exists; cannot create '%s'",
1975 iter->refname, refname);
1976 ref_iterator_abort(iter);
1977 goto cleanup;
1978 }
1979
1980 if (ok != ITER_DONE)
1981 die("BUG: error while iterating over references");
1982
1983 extra_refname = find_descendant_ref(dirname.buf, extras, skip);
1984 if (extra_refname)
1985 strbuf_addf(err, "cannot process '%s' and '%s' at the same time",
1986 refname, extra_refname);
1987 else
1988 ret = 0;
1989
1990cleanup:
1991 strbuf_release(&referent);
1992 strbuf_release(&dirname);
1993 return ret;
Michael Haggerty62665822016-09-04 18:08:26 +02001994}
David Turnere3688bd2016-09-04 18:08:38 +02001995
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001996int refs_for_each_reflog(struct ref_store *refs, each_ref_fn fn, void *cb_data)
David Turnere3688bd2016-09-04 18:08:38 +02001997{
David Turnere3688bd2016-09-04 18:08:38 +02001998 struct ref_iterator *iter;
1999
2000 iter = refs->be->reflog_iterator_begin(refs);
2001
2002 return do_for_each_ref_iterator(iter, fn, cb_data);
2003}
2004
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002005int for_each_reflog(each_ref_fn fn, void *cb_data)
2006{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002007 return refs_for_each_reflog(get_main_ref_store(the_repository), fn, cb_data);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002008}
2009
2010int refs_for_each_reflog_ent_reverse(struct ref_store *refs,
2011 const char *refname,
2012 each_reflog_ent_fn fn,
2013 void *cb_data)
2014{
2015 return refs->be->for_each_reflog_ent_reverse(refs, refname,
2016 fn, cb_data);
2017}
2018
David Turnere3688bd2016-09-04 18:08:38 +02002019int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn,
2020 void *cb_data)
2021{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002022 return refs_for_each_reflog_ent_reverse(get_main_ref_store(the_repository),
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002023 refname, fn, cb_data);
2024}
David Turnere3688bd2016-09-04 18:08:38 +02002025
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002026int refs_for_each_reflog_ent(struct ref_store *refs, const char *refname,
2027 each_reflog_ent_fn fn, void *cb_data)
2028{
2029 return refs->be->for_each_reflog_ent(refs, refname, fn, cb_data);
David Turnere3688bd2016-09-04 18:08:38 +02002030}
2031
2032int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn,
2033 void *cb_data)
2034{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002035 return refs_for_each_reflog_ent(get_main_ref_store(the_repository), refname,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002036 fn, cb_data);
2037}
David Turnere3688bd2016-09-04 18:08:38 +02002038
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002039int refs_reflog_exists(struct ref_store *refs, const char *refname)
2040{
2041 return refs->be->reflog_exists(refs, refname);
David Turnere3688bd2016-09-04 18:08:38 +02002042}
2043
2044int reflog_exists(const char *refname)
2045{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002046 return refs_reflog_exists(get_main_ref_store(the_repository), refname);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002047}
David Turnere3688bd2016-09-04 18:08:38 +02002048
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002049int refs_create_reflog(struct ref_store *refs, const char *refname,
2050 int force_create, struct strbuf *err)
2051{
2052 return refs->be->create_reflog(refs, refname, force_create, err);
David Turnere3688bd2016-09-04 18:08:38 +02002053}
2054
2055int safe_create_reflog(const char *refname, int force_create,
2056 struct strbuf *err)
2057{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002058 return refs_create_reflog(get_main_ref_store(the_repository), refname,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002059 force_create, err);
2060}
David Turnere3688bd2016-09-04 18:08:38 +02002061
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002062int refs_delete_reflog(struct ref_store *refs, const char *refname)
2063{
2064 return refs->be->delete_reflog(refs, refname);
David Turnere3688bd2016-09-04 18:08:38 +02002065}
2066
2067int delete_reflog(const char *refname)
2068{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002069 return refs_delete_reflog(get_main_ref_store(the_repository), refname);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002070}
David Turnere3688bd2016-09-04 18:08:38 +02002071
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002072int refs_reflog_expire(struct ref_store *refs,
brian m. carlson0155f712017-10-15 22:07:04 +00002073 const char *refname, const struct object_id *oid,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002074 unsigned int flags,
2075 reflog_expiry_prepare_fn prepare_fn,
2076 reflog_expiry_should_prune_fn should_prune_fn,
2077 reflog_expiry_cleanup_fn cleanup_fn,
2078 void *policy_cb_data)
2079{
brian m. carlson0155f712017-10-15 22:07:04 +00002080 return refs->be->reflog_expire(refs, refname, oid, flags,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002081 prepare_fn, should_prune_fn,
2082 cleanup_fn, policy_cb_data);
David Turnere3688bd2016-09-04 18:08:38 +02002083}
2084
brian m. carlson0155f712017-10-15 22:07:04 +00002085int reflog_expire(const char *refname, const struct object_id *oid,
David Turnere3688bd2016-09-04 18:08:38 +02002086 unsigned int flags,
2087 reflog_expiry_prepare_fn prepare_fn,
2088 reflog_expiry_should_prune_fn should_prune_fn,
2089 reflog_expiry_cleanup_fn cleanup_fn,
2090 void *policy_cb_data)
2091{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002092 return refs_reflog_expire(get_main_ref_store(the_repository),
brian m. carlson0155f712017-10-15 22:07:04 +00002093 refname, oid, flags,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002094 prepare_fn, should_prune_fn,
2095 cleanup_fn, policy_cb_data);
David Turnere3688bd2016-09-04 18:08:38 +02002096}
David Turnerfc681462016-09-04 18:08:39 +02002097
2098int initial_ref_transaction_commit(struct ref_transaction *transaction,
2099 struct strbuf *err)
2100{
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07002101 struct ref_store *refs = transaction->ref_store;
David Turnerfc681462016-09-04 18:08:39 +02002102
2103 return refs->be->initial_transaction_commit(refs, transaction, err);
2104}
David Turnera27dcf82016-09-04 18:08:40 +02002105
Michael Haggerty64da4192017-05-22 16:17:38 +02002106int refs_delete_refs(struct ref_store *refs, const char *msg,
2107 struct string_list *refnames, unsigned int flags)
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002108{
Michael Haggerty64da4192017-05-22 16:17:38 +02002109 return refs->be->delete_refs(refs, msg, refnames, flags);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002110}
2111
Michael Haggerty64da4192017-05-22 16:17:38 +02002112int delete_refs(const char *msg, struct string_list *refnames,
2113 unsigned int flags)
David Turnera27dcf82016-09-04 18:08:40 +02002114{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002115 return refs_delete_refs(get_main_ref_store(the_repository), msg, refnames, flags);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002116}
David Turnera27dcf82016-09-04 18:08:40 +02002117
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002118int refs_rename_ref(struct ref_store *refs, const char *oldref,
2119 const char *newref, const char *logmsg)
2120{
2121 return refs->be->rename_ref(refs, oldref, newref, logmsg);
David Turnera27dcf82016-09-04 18:08:40 +02002122}
David Turner9b6b40d2016-09-04 18:08:42 +02002123
2124int rename_ref(const char *oldref, const char *newref, const char *logmsg)
2125{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002126 return refs_rename_ref(get_main_ref_store(the_repository), oldref, newref, logmsg);
David Turner9b6b40d2016-09-04 18:08:42 +02002127}
Sahil Dua52d59cc2017-06-18 23:19:16 +02002128
2129int refs_copy_existing_ref(struct ref_store *refs, const char *oldref,
2130 const char *newref, const char *logmsg)
2131{
2132 return refs->be->copy_ref(refs, oldref, newref, logmsg);
2133}
2134
2135int copy_existing_ref(const char *oldref, const char *newref, const char *logmsg)
2136{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002137 return refs_copy_existing_ref(get_main_ref_store(the_repository), oldref, newref, logmsg);
Sahil Dua52d59cc2017-06-18 23:19:16 +02002138}