blob: de81c7be7ca8d3ca033b34a61f33b0bff069932f [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"
Stefan Bellercbd53a22018-05-15 16:42:15 -070012#include "object-store.h"
Junio C Hamanocf0adba2006-11-19 13:22:44 -080013#include "object.h"
14#include "tag.h"
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +070015#include "submodule.h"
Nguyễn Thái Ngọc Duy17eff962017-04-24 17:01:22 +070016#include "worktree.h"
Brandon Williamsb4be7412018-03-15 10:31:24 -070017#include "argv-array.h"
Stefan Beller23a3f0c2018-04-11 17:21:09 -070018#include "repository.h"
Stefan Beller3581d792014-12-12 09:57:02 +010019
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020020/*
Ronnie Sahlberg3dce4442016-09-04 18:08:10 +020021 * List of all available backends
22 */
23static struct ref_storage_be *refs_backends = &refs_be_files;
24
25static struct ref_storage_be *find_ref_storage_backend(const char *name)
26{
27 struct ref_storage_be *be;
28 for (be = refs_backends; be; be = be->next)
29 if (!strcmp(be->name, name))
30 return be;
31 return NULL;
32}
33
34int ref_storage_backend_exists(const char *name)
35{
36 return find_ref_storage_backend(name) != NULL;
37}
38
39/*
David Turnerdde8a902014-06-03 23:38:10 -040040 * How to handle various characters in refnames:
41 * 0: An acceptable character for refs
Junio C Hamano5e650222014-07-28 10:41:53 -070042 * 1: End-of-component
43 * 2: ., look for a preceding . to reject .. in refs
44 * 3: {, look for a preceding @ to reject @{ in refs
Jacob Keller53a85552015-07-22 14:05:32 -070045 * 4: A bad character: ASCII control characters, and
Jacob Kellercd377f42015-07-22 14:05:33 -070046 * ":", "?", "[", "\", "^", "~", SP, or TAB
47 * 5: *, reject unless REFNAME_REFSPEC_PATTERN is set
David Turnerdde8a902014-06-03 23:38:10 -040048 */
49static unsigned char refname_disposition[256] = {
Junio C Hamano5e650222014-07-28 10:41:53 -070050 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
51 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
Jacob Kellercd377f42015-07-22 14:05:33 -070052 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 1,
Junio C Hamano5e650222014-07-28 10:41:53 -070053 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4,
David Turnerdde8a902014-06-03 23:38:10 -040054 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Junio C Hamano5e650222014-07-28 10:41:53 -070055 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 0,
56 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4
David Turnerdde8a902014-06-03 23:38:10 -040058};
59
60/*
61 * Try to read one refname component from the front of refname.
62 * Return the length of the component found, or -1 if the component is
63 * not legal. It is legal if it is something reasonable to have under
64 * ".git/refs/"; We do not like it if:
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020065 *
66 * - any path component of it begins with ".", or
67 * - it has double dots "..", or
Jacob Keller53a85552015-07-22 14:05:32 -070068 * - it has ASCII control characters, or
Jacob Kellercd377f42015-07-22 14:05:33 -070069 * - it has ":", "?", "[", "\", "^", "~", SP, or TAB anywhere, or
70 * - it has "*" anywhere unless REFNAME_REFSPEC_PATTERN is set, or
Jacob Keller53a85552015-07-22 14:05:32 -070071 * - it ends with a "/", or
72 * - it ends with ".lock", or
73 * - it contains a "@{" portion
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020074 */
Jacob Kellercd377f42015-07-22 14:05:33 -070075static int check_refname_component(const char *refname, int *flags)
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020076{
77 const char *cp;
78 char last = '\0';
79
80 for (cp = refname; ; cp++) {
David Turnerdde8a902014-06-03 23:38:10 -040081 int ch = *cp & 255;
82 unsigned char disp = refname_disposition[ch];
83 switch (disp) {
Junio C Hamano5e650222014-07-28 10:41:53 -070084 case 1:
David Turnerdde8a902014-06-03 23:38:10 -040085 goto out;
Junio C Hamano5e650222014-07-28 10:41:53 -070086 case 2:
David Turnerdde8a902014-06-03 23:38:10 -040087 if (last == '.')
88 return -1; /* Refname contains "..". */
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020089 break;
Junio C Hamano5e650222014-07-28 10:41:53 -070090 case 3:
David Turnerdde8a902014-06-03 23:38:10 -040091 if (last == '@')
92 return -1; /* Refname contains "@{". */
93 break;
Junio C Hamano5e650222014-07-28 10:41:53 -070094 case 4:
David Turnerdde8a902014-06-03 23:38:10 -040095 return -1;
Jacob Kellercd377f42015-07-22 14:05:33 -070096 case 5:
97 if (!(*flags & REFNAME_REFSPEC_PATTERN))
98 return -1; /* refspec can't be a pattern */
99
100 /*
101 * Unset the pattern flag so that we only accept
102 * a single asterisk for one side of refspec.
103 */
104 *flags &= ~ REFNAME_REFSPEC_PATTERN;
105 break;
David Turnerdde8a902014-06-03 23:38:10 -0400106 }
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200107 last = ch;
108 }
David Turnerdde8a902014-06-03 23:38:10 -0400109out:
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200110 if (cp == refname)
Michael Haggertydac529e2012-04-10 07:30:22 +0200111 return 0; /* Component has zero length. */
Jonathan Niederf3cc52d2014-09-26 12:22:22 -0700112 if (refname[0] == '.')
113 return -1; /* Component starts with '.'. */
Michael Haggerty7108ad22014-10-01 12:28:15 +0200114 if (cp - refname >= LOCK_SUFFIX_LEN &&
115 !memcmp(cp - LOCK_SUFFIX_LEN, LOCK_SUFFIX, LOCK_SUFFIX_LEN))
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200116 return -1; /* Refname ends with ".lock". */
117 return cp - refname;
118}
119
Junio C Hamano5e650222014-07-28 10:41:53 -0700120int check_refname_format(const char *refname, int flags)
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200121{
122 int component_len, component_count = 0;
123
Felipe Contreras9ba89f42013-09-02 01:34:30 -0500124 if (!strcmp(refname, "@"))
125 /* Refname is a single character '@'. */
126 return -1;
127
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200128 while (1) {
129 /* We are at the start of a path component. */
Jacob Kellercd377f42015-07-22 14:05:33 -0700130 component_len = check_refname_component(refname, &flags);
131 if (component_len <= 0)
132 return -1;
133
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200134 component_count++;
135 if (refname[component_len] == '\0')
136 break;
137 /* Skip to next component. */
138 refname += component_len + 1;
139 }
140
141 if (refname[component_len - 1] == '.')
142 return -1; /* Refname ends with '.'. */
143 if (!(flags & REFNAME_ALLOW_ONELEVEL) && component_count < 2)
144 return -1; /* Refname has only one component. */
145 return 0;
146}
147
Michael Haggerty4cb77002015-11-10 12:42:36 +0100148int refname_is_safe(const char *refname)
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700149{
Michael Haggerty39950fe2016-04-27 12:39:11 +0200150 const char *rest;
151
152 if (skip_prefix(refname, "refs/", &rest)) {
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700153 char *buf;
154 int result;
Michael Haggertye40f3552016-04-27 12:40:39 +0200155 size_t restlen = strlen(rest);
156
157 /* rest must not be empty, or start or end with "/" */
158 if (!restlen || *rest == '/' || rest[restlen - 1] == '/')
159 return 0;
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700160
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700161 /*
162 * Does the refname try to escape refs/?
163 * For example: refs/foo/../bar is safe but refs/foo/../../bar
164 * is not.
165 */
Michael Haggertye40f3552016-04-27 12:40:39 +0200166 buf = xmallocz(restlen);
167 result = !normalize_path_copy(buf, rest) && !strcmp(buf, rest);
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700168 free(buf);
169 return result;
170 }
Michael Haggerty35db25c2016-04-27 12:42:27 +0200171
172 do {
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700173 if (!isupper(*refname) && *refname != '_')
174 return 0;
175 refname++;
Michael Haggerty35db25c2016-04-27 12:42:27 +0200176 } while (*refname);
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700177 return 1;
178}
179
Michael Haggerty67be7c52017-06-23 09:01:37 +0200180/*
181 * Return true if refname, which has the specified oid and flags, can
182 * be resolved to an object in the database. If the referred-to object
183 * does not exist, emit a warning and return false.
184 */
185int ref_resolves_to_object(const char *refname,
186 const struct object_id *oid,
187 unsigned int flags)
188{
189 if (flags & REF_ISBROKEN)
190 return 0;
191 if (!has_sha1_file(oid->hash)) {
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +0200192 error(_("%s does not point to a valid object!"), refname);
Michael Haggerty67be7c52017-06-23 09:01:37 +0200193 return 0;
194 }
195 return 1;
196}
197
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700198char *refs_resolve_refdup(struct ref_store *refs,
199 const char *refname, int resolve_flags,
brian m. carlson0f2dc722017-10-15 22:06:55 +0000200 struct object_id *oid, int *flags)
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700201{
202 const char *result;
203
204 result = refs_resolve_ref_unsafe(refs, refname, resolve_flags,
brian m. carlson49e61472017-10-15 22:07:09 +0000205 oid, flags);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700206 return xstrdup_or_null(result);
207}
208
Michael Haggertyfb58c8d2015-06-22 16:03:05 +0200209char *resolve_refdup(const char *refname, int resolve_flags,
brian m. carlson0f2dc722017-10-15 22:06:55 +0000210 struct object_id *oid, int *flags)
Nguyễn Thái Ngọc Duy96ec7b12011-12-13 21:17:48 +0700211{
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700212 return refs_resolve_refdup(get_main_ref_store(the_repository),
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700213 refname, resolve_flags,
brian m. carlson0f2dc722017-10-15 22:06:55 +0000214 oid, flags);
Nguyễn Thái Ngọc Duy96ec7b12011-12-13 21:17:48 +0700215}
216
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200217/* The argument to filter_refs */
218struct ref_filter {
219 const char *pattern;
220 each_ref_fn *fn;
221 void *cb_data;
222};
223
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700224int refs_read_ref_full(struct ref_store *refs, const char *refname,
brian m. carlson34c290a2017-10-15 22:06:56 +0000225 int resolve_flags, struct object_id *oid, int *flags)
Linus Torvalds8a65ff72005-07-02 20:23:36 -0700226{
brian m. carlson49e61472017-10-15 22:07:09 +0000227 if (refs_resolve_ref_unsafe(refs, refname, resolve_flags, oid, flags))
Junio C Hamanoa876ed82005-09-30 14:08:25 -0700228 return 0;
229 return -1;
Linus Torvalds8a65ff72005-07-02 20:23:36 -0700230}
231
brian m. carlson34c290a2017-10-15 22:06:56 +0000232int 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 +0700233{
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700234 return refs_read_ref_full(get_main_ref_store(the_repository), refname,
brian m. carlson34c290a2017-10-15 22:06:56 +0000235 resolve_flags, oid, flags);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700236}
237
brian m. carlson34c290a2017-10-15 22:06:56 +0000238int read_ref(const char *refname, struct object_id *oid)
Nguyễn Thái Ngọc Duyc6893322011-11-13 17:22:14 +0700239{
brian m. carlson34c290a2017-10-15 22:06:56 +0000240 return read_ref_full(refname, RESOLVE_REF_READING, oid, NULL);
Nguyễn Thái Ngọc Duyc6893322011-11-13 17:22:14 +0700241}
242
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200243int ref_exists(const char *refname)
Junio C Hamanoef06b912006-11-18 22:13:33 -0800244{
René Scharfe744c0402017-09-23 11:45:04 +0200245 return !!resolve_ref_unsafe(refname, RESOLVE_REF_READING, NULL, NULL);
Junio C Hamanoef06b912006-11-18 22:13:33 -0800246}
247
Rafael Ascensão65516f52017-11-21 21:33:41 +0000248static int match_ref_pattern(const char *refname,
249 const struct string_list_item *item)
250{
251 int matched = 0;
252 if (item->util == NULL) {
253 if (!wildmatch(item->string, refname, 0))
254 matched = 1;
255 } else {
256 const char *rest;
257 if (skip_prefix(refname, item->string, &rest) &&
258 (!*rest || *rest == '/'))
259 matched = 1;
260 }
261 return matched;
262}
263
264int ref_filter_match(const char *refname,
265 const struct string_list *include_patterns,
266 const struct string_list *exclude_patterns)
267{
268 struct string_list_item *item;
269
270 if (exclude_patterns && exclude_patterns->nr) {
271 for_each_string_list_item(item, exclude_patterns) {
272 if (match_ref_pattern(refname, item))
273 return 0;
274 }
275 }
276
277 if (include_patterns && include_patterns->nr) {
278 int found = 0;
279 for_each_string_list_item(item, include_patterns) {
280 if (match_ref_pattern(refname, item)) {
281 found = 1;
282 break;
283 }
284 }
285
286 if (!found)
287 return 0;
288 }
289 return 1;
290}
291
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000292static int filter_refs(const char *refname, const struct object_id *oid,
Michael Haggerty4e675d12015-05-25 18:39:21 +0000293 int flags, void *data)
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200294{
295 struct ref_filter *filter = (struct ref_filter *)data;
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000296
Ævar Arnfjörð Bjarmason55d34262017-06-22 21:38:08 +0000297 if (wildmatch(filter->pattern, refname, 0))
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200298 return 0;
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000299 return filter->fn(refname, oid, flags, filter->cb_data);
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200300}
301
brian m. carlsonac2ed0d2017-10-15 22:07:10 +0000302enum peel_status peel_object(const struct object_id *name, struct object_id *oid)
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200303{
brian m. carlsonac2ed0d2017-10-15 22:07:10 +0000304 struct object *o = lookup_unknown_object(name->hash);
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200305
306 if (o->type == OBJ_NONE) {
Stefan Beller0df8e962018-04-25 11:20:59 -0700307 int type = oid_object_info(the_repository, name, NULL);
Stefan Beller1268dfa2018-06-28 18:21:54 -0700308 if (type < 0 || !object_as_type(the_repository, o, type, 0))
Michael Haggerty68cf8702013-04-22 21:52:20 +0200309 return PEEL_INVALID;
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200310 }
311
312 if (o->type != OBJ_TAG)
Michael Haggerty68cf8702013-04-22 21:52:20 +0200313 return PEEL_NON_TAG;
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200314
315 o = deref_tag_noverify(o);
316 if (!o)
Michael Haggerty68cf8702013-04-22 21:52:20 +0200317 return PEEL_INVALID;
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200318
brian m. carlsonac2ed0d2017-10-15 22:07:10 +0000319 oidcpy(oid, &o->oid);
Michael Haggerty68cf8702013-04-22 21:52:20 +0200320 return PEEL_PEELED;
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200321}
322
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200323struct warn_if_dangling_data {
324 FILE *fp;
325 const char *refname;
Jens Lindströme6bea662014-05-23 12:30:25 +0200326 const struct string_list *refnames;
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200327 const char *msg_fmt;
328};
329
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000330static int warn_if_dangling_symref(const char *refname, const struct object_id *oid,
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200331 int flags, void *cb_data)
332{
333 struct warn_if_dangling_data *d = cb_data;
334 const char *resolves_to;
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200335
336 if (!(flags & REF_ISSYMREF))
337 return 0;
338
René Scharfe744c0402017-09-23 11:45:04 +0200339 resolves_to = resolve_ref_unsafe(refname, 0, NULL, NULL);
Jens Lindströme6bea662014-05-23 12:30:25 +0200340 if (!resolves_to
341 || (d->refname
342 ? strcmp(resolves_to, d->refname)
343 : !string_list_has_string(d->refnames, resolves_to))) {
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200344 return 0;
Jens Lindströme6bea662014-05-23 12:30:25 +0200345 }
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200346
347 fprintf(d->fp, d->msg_fmt, refname);
Junio C Hamano1be65ed2012-05-02 13:51:35 -0700348 fputc('\n', d->fp);
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200349 return 0;
350}
351
352void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
353{
354 struct warn_if_dangling_data data;
355
356 data.fp = fp;
357 data.refname = refname;
Jens Lindströme6bea662014-05-23 12:30:25 +0200358 data.refnames = NULL;
359 data.msg_fmt = msg_fmt;
360 for_each_rawref(warn_if_dangling_symref, &data);
361}
362
363void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list *refnames)
364{
365 struct warn_if_dangling_data data;
366
367 data.fp = fp;
368 data.refname = NULL;
369 data.refnames = refnames;
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200370 data.msg_fmt = msg_fmt;
371 for_each_rawref(warn_if_dangling_symref, &data);
372}
373
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700374int refs_for_each_tag_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
375{
376 return refs_for_each_ref_in(refs, "refs/tags/", fn, cb_data);
377}
378
Junio C Hamanocb5d7092006-09-20 21:47:42 -0700379int for_each_tag_ref(each_ref_fn fn, void *cb_data)
Seana62be772006-05-13 21:43:00 -0400380{
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700381 return refs_for_each_tag_ref(get_main_ref_store(the_repository), fn, cb_data);
Seana62be772006-05-13 21:43:00 -0400382}
383
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700384int refs_for_each_branch_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
385{
386 return refs_for_each_ref_in(refs, "refs/heads/", fn, cb_data);
Heiko Voigt9ef6aeb2010-07-07 15:39:12 +0200387}
388
Junio C Hamanocb5d7092006-09-20 21:47:42 -0700389int for_each_branch_ref(each_ref_fn fn, void *cb_data)
Seana62be772006-05-13 21:43:00 -0400390{
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700391 return refs_for_each_branch_ref(get_main_ref_store(the_repository), fn, cb_data);
Seana62be772006-05-13 21:43:00 -0400392}
393
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700394int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
395{
396 return refs_for_each_ref_in(refs, "refs/remotes/", fn, cb_data);
Heiko Voigt9ef6aeb2010-07-07 15:39:12 +0200397}
398
Junio C Hamanocb5d7092006-09-20 21:47:42 -0700399int for_each_remote_ref(each_ref_fn fn, void *cb_data)
Seana62be772006-05-13 21:43:00 -0400400{
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700401 return refs_for_each_remote_ref(get_main_ref_store(the_repository), fn, cb_data);
Junio C Hamanof8948e22009-02-08 23:27:10 -0800402}
403
Josh Tripletta1bea2c2011-07-05 10:54:44 -0700404int head_ref_namespaced(each_ref_fn fn, void *cb_data)
405{
406 struct strbuf buf = STRBUF_INIT;
407 int ret = 0;
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000408 struct object_id oid;
Josh Tripletta1bea2c2011-07-05 10:54:44 -0700409 int flag;
410
411 strbuf_addf(&buf, "%sHEAD", get_git_namespace());
brian m. carlson34c290a2017-10-15 22:06:56 +0000412 if (!read_ref_full(buf.buf, RESOLVE_REF_READING, &oid, &flag))
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000413 ret = fn(buf.buf, &oid, flag, cb_data);
Josh Tripletta1bea2c2011-07-05 10:54:44 -0700414 strbuf_release(&buf);
415
416 return ret;
417}
418
Rafael Ascensão65516f52017-11-21 21:33:41 +0000419void normalize_glob_ref(struct string_list_item *item, const char *prefix,
420 const char *pattern)
421{
422 struct strbuf normalized_pattern = STRBUF_INIT;
423
424 if (*pattern == '/')
425 BUG("pattern must not start with '/'");
426
427 if (prefix) {
428 strbuf_addstr(&normalized_pattern, prefix);
429 }
430 else if (!starts_with(pattern, "refs/"))
431 strbuf_addstr(&normalized_pattern, "refs/");
432 strbuf_addstr(&normalized_pattern, pattern);
433 strbuf_strip_suffix(&normalized_pattern, "/");
434
435 item->string = strbuf_detach(&normalized_pattern, NULL);
436 item->util = has_glob_specials(pattern) ? NULL : item->string;
437 strbuf_release(&normalized_pattern);
438}
439
Ilari Liusvaarab09fe972010-01-20 11:48:26 +0200440int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
441 const char *prefix, void *cb_data)
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200442{
443 struct strbuf real_pattern = STRBUF_INIT;
444 struct ref_filter filter;
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200445 int ret;
446
Christian Couder59556542013-11-30 21:55:40 +0100447 if (!prefix && !starts_with(pattern, "refs/"))
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200448 strbuf_addstr(&real_pattern, "refs/");
Ilari Liusvaarab09fe972010-01-20 11:48:26 +0200449 else if (prefix)
450 strbuf_addstr(&real_pattern, prefix);
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200451 strbuf_addstr(&real_pattern, pattern);
452
Thomas Rast894a9d32010-03-12 18:04:26 +0100453 if (!has_glob_specials(pattern)) {
Junio C Hamano9517e6b2010-02-03 21:23:18 -0800454 /* Append implied '/' '*' if not present. */
Jeff King00b6c172015-09-24 17:08:35 -0400455 strbuf_complete(&real_pattern, '/');
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200456 /* No need to check for '*', there is none. */
457 strbuf_addch(&real_pattern, '*');
458 }
459
460 filter.pattern = real_pattern.buf;
461 filter.fn = fn;
462 filter.cb_data = cb_data;
463 ret = for_each_ref(filter_refs, &filter);
464
465 strbuf_release(&real_pattern);
466 return ret;
467}
468
Ilari Liusvaarab09fe972010-01-20 11:48:26 +0200469int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
470{
471 return for_each_glob_ref_in(fn, pattern, NULL, cb_data);
472}
473
Felipe Contreras4577e482009-05-14 00:22:04 +0300474const char *prettify_refname(const char *name)
Daniel Barkalowa9c37a72009-03-08 21:06:05 -0400475{
SZEDER Gábor3e5b36c2017-03-23 16:50:12 +0100476 if (skip_prefix(name, "refs/heads/", &name) ||
477 skip_prefix(name, "refs/tags/", &name) ||
478 skip_prefix(name, "refs/remotes/", &name))
479 ; /* nothing */
480 return name;
Daniel Barkalowa9c37a72009-03-08 21:06:05 -0400481}
482
Michael Haggerty54457fe2014-01-14 04:16:07 +0100483static const char *ref_rev_parse_rules[] = {
Steffen Prohaska79803322007-11-11 15:01:46 +0100484 "%.*s",
485 "refs/%.*s",
486 "refs/tags/%.*s",
487 "refs/heads/%.*s",
488 "refs/remotes/%.*s",
489 "refs/remotes/%.*s/HEAD",
490 NULL
491};
492
Junio C Hamano60650a42018-08-01 09:22:37 -0700493#define NUM_REV_PARSE_RULES (ARRAY_SIZE(ref_rev_parse_rules) - 1)
494
495/*
496 * Is it possible that the caller meant full_name with abbrev_name?
497 * If so return a non-zero value to signal "yes"; the magnitude of
498 * the returned value gives the precedence used for disambiguation.
499 *
500 * If abbrev_name cannot mean full_name, return 0.
501 */
Michael Haggerty54457fe2014-01-14 04:16:07 +0100502int refname_match(const char *abbrev_name, const char *full_name)
Steffen Prohaska79803322007-11-11 15:01:46 +0100503{
504 const char **p;
505 const int abbrev_name_len = strlen(abbrev_name);
Junio C Hamano60650a42018-08-01 09:22:37 -0700506 const int num_rules = NUM_REV_PARSE_RULES;
Steffen Prohaska79803322007-11-11 15:01:46 +0100507
Junio C Hamano60650a42018-08-01 09:22:37 -0700508 for (p = ref_rev_parse_rules; *p; p++)
509 if (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name)))
510 return &ref_rev_parse_rules[num_rules] - p;
Steffen Prohaska79803322007-11-11 15:01:46 +0100511
512 return 0;
513}
514
Michael Haggerty19b68b12011-12-12 06:38:12 +0100515/*
Brandon Williamsb4be7412018-03-15 10:31:24 -0700516 * Given a 'prefix' expand it by the rules in 'ref_rev_parse_rules' and add
517 * the results to 'prefixes'
518 */
519void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
520{
521 const char **p;
522 int len = strlen(prefix);
523
524 for (p = ref_rev_parse_rules; *p; p++)
525 argv_array_pushf(prefixes, *p, len, prefix);
526}
527
528/*
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700529 * *string and *len will only be substituted, and *string returned (for
530 * later free()ing) if the string passed in is a magic short-hand form
531 * to name a branch.
532 */
533static char *substitute_branch_name(const char **string, int *len)
534{
535 struct strbuf buf = STRBUF_INIT;
Jeff King0e9f62d2017-03-02 03:23:01 -0500536 int ret = interpret_branch_name(*string, *len, &buf, 0);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700537
538 if (ret == *len) {
539 size_t size;
540 *string = strbuf_detach(&buf, &size);
541 *len = size;
542 return (char *)*string;
543 }
544
545 return NULL;
546}
547
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000548int dwim_ref(const char *str, int len, struct object_id *oid, char **ref)
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700549{
550 char *last_branch = substitute_branch_name(&str, &len);
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000551 int refs_found = expand_ref(str, len, oid, ref);
Nguyễn Thái Ngọc Duy41da7112016-06-12 17:54:02 +0700552 free(last_branch);
553 return refs_found;
554}
555
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000556int 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 +0700557{
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700558 const char **p, *r;
559 int refs_found = 0;
Jeff King6cd4a892017-03-28 15:46:33 -0400560 struct strbuf fullref = STRBUF_INIT;
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700561
562 *ref = NULL;
563 for (p = ref_rev_parse_rules; *p; p++) {
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000564 struct object_id oid_from_ref;
565 struct object_id *this_result;
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700566 int flag;
567
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000568 this_result = refs_found ? &oid_from_ref : oid;
Jeff King6cd4a892017-03-28 15:46:33 -0400569 strbuf_reset(&fullref);
570 strbuf_addf(&fullref, *p, len, str);
571 r = resolve_ref_unsafe(fullref.buf, RESOLVE_REF_READING,
brian m. carlson49e61472017-10-15 22:07:09 +0000572 this_result, &flag);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700573 if (r) {
574 if (!refs_found++)
575 *ref = xstrdup(r);
576 if (!warn_ambiguous_refs)
577 break;
Jeff King6cd4a892017-03-28 15:46:33 -0400578 } else if ((flag & REF_ISSYMREF) && strcmp(fullref.buf, "HEAD")) {
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +0200579 warning(_("ignoring dangling symref %s"), fullref.buf);
Jeff King6cd4a892017-03-28 15:46:33 -0400580 } else if ((flag & REF_ISBROKEN) && strchr(fullref.buf, '/')) {
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +0200581 warning(_("ignoring broken ref %s"), fullref.buf);
Junio C Hamano55956352011-10-19 13:55:49 -0700582 }
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700583 }
Jeff King6cd4a892017-03-28 15:46:33 -0400584 strbuf_release(&fullref);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700585 return refs_found;
586}
587
brian m. carlson334dc522017-10-15 22:06:59 +0000588int dwim_log(const char *str, int len, struct object_id *oid, char **log)
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700589{
590 char *last_branch = substitute_branch_name(&str, &len);
591 const char **p;
592 int logs_found = 0;
Jeff King6cd4a892017-03-28 15:46:33 -0400593 struct strbuf path = STRBUF_INIT;
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700594
595 *log = NULL;
596 for (p = ref_rev_parse_rules; *p; p++) {
brian m. carlson334dc522017-10-15 22:06:59 +0000597 struct object_id hash;
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700598 const char *ref, *it;
599
Jeff King6cd4a892017-03-28 15:46:33 -0400600 strbuf_reset(&path);
601 strbuf_addf(&path, *p, len, str);
602 ref = resolve_ref_unsafe(path.buf, RESOLVE_REF_READING,
brian m. carlson49e61472017-10-15 22:07:09 +0000603 &hash, NULL);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700604 if (!ref)
605 continue;
Jeff King6cd4a892017-03-28 15:46:33 -0400606 if (reflog_exists(path.buf))
607 it = path.buf;
608 else if (strcmp(ref, path.buf) && reflog_exists(ref))
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700609 it = ref;
610 else
611 continue;
612 if (!logs_found++) {
613 *log = xstrdup(it);
brian m. carlson334dc522017-10-15 22:06:59 +0000614 oidcpy(oid, &hash);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700615 }
616 if (!warn_ambiguous_refs)
617 break;
618 }
Jeff King6cd4a892017-03-28 15:46:33 -0400619 strbuf_release(&path);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700620 free(last_branch);
621 return logs_found;
622}
623
David Turner266b1822015-07-31 02:06:18 -0400624static int is_per_worktree_ref(const char *refname)
625{
David Turnerce414b32015-08-31 22:13:11 -0400626 return !strcmp(refname, "HEAD") ||
Johannes Schindelina9be29c2018-04-25 14:29:16 +0200627 starts_with(refname, "refs/bisect/") ||
628 starts_with(refname, "refs/rewritten/");
David Turner266b1822015-07-31 02:06:18 -0400629}
630
631static int is_pseudoref_syntax(const char *refname)
632{
633 const char *c;
634
635 for (c = refname; *c; c++) {
636 if (!isupper(*c) && *c != '-' && *c != '_')
637 return 0;
638 }
639
640 return 1;
641}
642
643enum ref_type ref_type(const char *refname)
644{
645 if (is_per_worktree_ref(refname))
646 return REF_TYPE_PER_WORKTREE;
647 if (is_pseudoref_syntax(refname))
648 return REF_TYPE_PSEUDOREF;
649 return REF_TYPE_NORMAL;
650}
651
Michael Haggerty4ff0f012017-08-21 13:51:34 +0200652long get_files_ref_lock_timeout_ms(void)
653{
654 static int configured = 0;
655
656 /* The default timeout is 100 ms: */
657 static int timeout_ms = 100;
658
659 if (!configured) {
660 git_config_get_int("core.filesreflocktimeout", &timeout_ms);
661 configured = 1;
662 }
663
664 return timeout_ms;
665}
666
brian m. carlsonae077772017-10-15 22:06:51 +0000667static int write_pseudoref(const char *pseudoref, const struct object_id *oid,
668 const struct object_id *old_oid, struct strbuf *err)
David Turner74ec19d2015-07-31 02:06:19 -0400669{
670 const char *filename;
671 int fd;
Martin Ågren01084512018-05-09 22:55:36 +0200672 struct lock_file lock = LOCK_INIT;
David Turner74ec19d2015-07-31 02:06:19 -0400673 struct strbuf buf = STRBUF_INIT;
674 int ret = -1;
675
brian m. carlson6ee18212017-10-15 22:06:52 +0000676 if (!oid)
677 return 0;
678
brian m. carlsonae077772017-10-15 22:06:51 +0000679 strbuf_addf(&buf, "%s\n", oid_to_hex(oid));
David Turner74ec19d2015-07-31 02:06:19 -0400680
681 filename = git_path("%s", pseudoref);
Martin Ågren01084512018-05-09 22:55:36 +0200682 fd = hold_lock_file_for_update_timeout(&lock, filename, 0,
Michael Haggerty4ff0f012017-08-21 13:51:34 +0200683 get_files_ref_lock_timeout_ms());
David Turner74ec19d2015-07-31 02:06:19 -0400684 if (fd < 0) {
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +0200685 strbuf_addf(err, _("could not open '%s' for writing: %s"),
David Turner74ec19d2015-07-31 02:06:19 -0400686 filename, strerror(errno));
Rene Scharfeaeb014f2017-08-30 19:58:12 +0200687 goto done;
David Turner74ec19d2015-07-31 02:06:19 -0400688 }
689
brian m. carlsonae077772017-10-15 22:06:51 +0000690 if (old_oid) {
691 struct object_id actual_old_oid;
David Turner2c3aed12015-07-15 18:05:28 -0400692
Martin Ågrendb0210d2018-05-10 21:29:56 +0200693 if (read_ref(pseudoref, &actual_old_oid)) {
694 if (!is_null_oid(old_oid)) {
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +0200695 strbuf_addf(err, _("could not read ref '%s'"),
Martin Ågrendb0210d2018-05-10 21:29:56 +0200696 pseudoref);
697 rollback_lock_file(&lock);
698 goto done;
699 }
700 } else if (is_null_oid(old_oid)) {
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +0200701 strbuf_addf(err, _("ref '%s' already exists"),
Martin Ågrendb0210d2018-05-10 21:29:56 +0200702 pseudoref);
703 rollback_lock_file(&lock);
704 goto done;
705 } else if (oidcmp(&actual_old_oid, old_oid)) {
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +0200706 strbuf_addf(err, _("unexpected object ID when writing '%s'"),
Martin Ågrenc0bdd652018-05-10 21:29:54 +0200707 pseudoref);
David Turner74ec19d2015-07-31 02:06:19 -0400708 rollback_lock_file(&lock);
709 goto done;
710 }
711 }
712
Jeff King06f46f22017-09-13 13:16:03 -0400713 if (write_in_full(fd, buf.buf, buf.len) < 0) {
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +0200714 strbuf_addf(err, _("could not write to '%s'"), filename);
David Turner74ec19d2015-07-31 02:06:19 -0400715 rollback_lock_file(&lock);
716 goto done;
717 }
718
719 commit_lock_file(&lock);
720 ret = 0;
721done:
722 strbuf_release(&buf);
723 return ret;
724}
725
brian m. carlson2616a5e2017-10-15 22:06:50 +0000726static int delete_pseudoref(const char *pseudoref, const struct object_id *old_oid)
David Turner74ec19d2015-07-31 02:06:19 -0400727{
David Turner74ec19d2015-07-31 02:06:19 -0400728 const char *filename;
729
730 filename = git_path("%s", pseudoref);
731
brian m. carlson2616a5e2017-10-15 22:06:50 +0000732 if (old_oid && !is_null_oid(old_oid)) {
Martin Ågren3c6fad42018-05-09 22:55:37 +0200733 struct lock_file lock = LOCK_INIT;
David Turner74ec19d2015-07-31 02:06:19 -0400734 int fd;
brian m. carlson2616a5e2017-10-15 22:06:50 +0000735 struct object_id actual_old_oid;
David Turner74ec19d2015-07-31 02:06:19 -0400736
Michael Haggerty4ff0f012017-08-21 13:51:34 +0200737 fd = hold_lock_file_for_update_timeout(
Martin Ågren3c6fad42018-05-09 22:55:37 +0200738 &lock, filename, 0,
Michael Haggerty4ff0f012017-08-21 13:51:34 +0200739 get_files_ref_lock_timeout_ms());
Martin Ågren3c6fad42018-05-09 22:55:37 +0200740 if (fd < 0) {
741 error_errno(_("could not open '%s' for writing"),
742 filename);
743 return -1;
744 }
brian m. carlson34c290a2017-10-15 22:06:56 +0000745 if (read_ref(pseudoref, &actual_old_oid))
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +0200746 die(_("could not read ref '%s'"), pseudoref);
brian m. carlson2616a5e2017-10-15 22:06:50 +0000747 if (oidcmp(&actual_old_oid, old_oid)) {
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +0200748 error(_("unexpected object ID when deleting '%s'"),
Martin Ågrenc0bdd652018-05-10 21:29:54 +0200749 pseudoref);
David Turner74ec19d2015-07-31 02:06:19 -0400750 rollback_lock_file(&lock);
751 return -1;
752 }
753
754 unlink(filename);
755 rollback_lock_file(&lock);
756 } else {
757 unlink(filename);
758 }
759
760 return 0;
761}
762
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700763int refs_delete_ref(struct ref_store *refs, const char *msg,
764 const char *refname,
brian m. carlson2616a5e2017-10-15 22:06:50 +0000765 const struct object_id *old_oid,
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700766 unsigned int flags)
Junio C Hamanoc0277d12006-09-30 15:02:00 -0700767{
Ronnie Sahlberg7521cc42014-04-30 09:22:45 -0700768 struct ref_transaction *transaction;
769 struct strbuf err = STRBUF_INIT;
Junio C Hamanoc0277d12006-09-30 15:02:00 -0700770
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700771 if (ref_type(refname) == REF_TYPE_PSEUDOREF) {
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700772 assert(refs == get_main_ref_store(the_repository));
brian m. carlson2616a5e2017-10-15 22:06:50 +0000773 return delete_pseudoref(refname, old_oid);
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700774 }
David Turner74ec19d2015-07-31 02:06:19 -0400775
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700776 transaction = ref_store_transaction_begin(refs, &err);
Ronnie Sahlberg7521cc42014-04-30 09:22:45 -0700777 if (!transaction ||
brian m. carlson89f3bbd2017-10-15 22:06:53 +0000778 ref_transaction_delete(transaction, refname, old_oid,
Kyle Meyer755b49a2017-02-20 20:10:32 -0500779 flags, msg, &err) ||
Ronnie Sahlbergdb7516a2014-04-30 12:22:42 -0700780 ref_transaction_commit(transaction, &err)) {
Ronnie Sahlberg7521cc42014-04-30 09:22:45 -0700781 error("%s", err.buf);
782 ref_transaction_free(transaction);
783 strbuf_release(&err);
Junio C Hamanoc0277d12006-09-30 15:02:00 -0700784 return 1;
Ronnie Sahlberg7521cc42014-04-30 09:22:45 -0700785 }
786 ref_transaction_free(transaction);
787 strbuf_release(&err);
788 return 0;
Shawn Pearce4bd18c42006-05-17 05:55:02 -0400789}
790
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700791int delete_ref(const char *msg, const char *refname,
brian m. carlson2616a5e2017-10-15 22:06:50 +0000792 const struct object_id *old_oid, unsigned int flags)
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700793{
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700794 return refs_delete_ref(get_main_ref_store(the_repository), msg, refname,
brian m. carlson2616a5e2017-10-15 22:06:50 +0000795 old_oid, flags);
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700796}
797
Ben Peart80a6c202018-07-10 21:08:22 +0000798void copy_reflog_msg(struct strbuf *sb, const char *msg)
Junio C Hamano0ec29a42007-07-28 17:17:17 -0700799{
Junio C Hamano0ec29a42007-07-28 17:17:17 -0700800 char c;
801 int wasspace = 1;
802
Ben Peart80a6c202018-07-10 21:08:22 +0000803 strbuf_addch(sb, '\t');
Junio C Hamano0ec29a42007-07-28 17:17:17 -0700804 while ((c = *msg++)) {
805 if (wasspace && isspace(c))
806 continue;
807 wasspace = isspace(c);
808 if (wasspace)
809 c = ' ';
Ben Peart80a6c202018-07-10 21:08:22 +0000810 strbuf_addch(sb, c);
Junio C Hamano0ec29a42007-07-28 17:17:17 -0700811 }
Ben Peart80a6c202018-07-10 21:08:22 +0000812 strbuf_rtrim(sb);
Junio C Hamano0ec29a42007-07-28 17:17:17 -0700813}
814
Michael Haggerty4cb77002015-11-10 12:42:36 +0100815int should_autocreate_reflog(const char *refname)
David Turner4e2bef52015-07-21 17:04:51 -0400816{
Cornelius Weig341fb282017-01-27 11:09:47 +0100817 switch (log_all_ref_updates) {
818 case LOG_REFS_ALWAYS:
819 return 1;
820 case LOG_REFS_NORMAL:
821 return starts_with(refname, "refs/heads/") ||
822 starts_with(refname, "refs/remotes/") ||
823 starts_with(refname, "refs/notes/") ||
824 !strcmp(refname, "HEAD");
825 default:
David Turner4e2bef52015-07-21 17:04:51 -0400826 return 0;
Cornelius Weig341fb282017-01-27 11:09:47 +0100827 }
David Turner4e2bef52015-07-21 17:04:51 -0400828}
829
Ronnie Sahlberge7e0f262014-07-15 16:02:38 -0700830int is_branch(const char *refname)
Linus Torvaldsc3b0dec2008-01-15 15:50:17 -0800831{
Christian Couder59556542013-11-30 21:55:40 +0100832 return !strcmp(refname, "HEAD") || starts_with(refname, "refs/heads/");
Linus Torvaldsc3b0dec2008-01-15 15:50:17 -0800833}
834
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700835struct read_ref_at_cb {
836 const char *refname;
Johannes Schindelindddbad72017-04-26 21:29:31 +0200837 timestamp_t at_time;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700838 int cnt;
839 int reccnt;
brian m. carlson8eb36d92017-10-15 22:07:03 +0000840 struct object_id *oid;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700841 int found_it;
842
brian m. carlson8eb36d92017-10-15 22:07:03 +0000843 struct object_id ooid;
844 struct object_id noid;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700845 int tz;
Johannes Schindelindddbad72017-04-26 21:29:31 +0200846 timestamp_t date;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700847 char **msg;
Johannes Schindelindddbad72017-04-26 21:29:31 +0200848 timestamp_t *cutoff_time;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700849 int *cutoff_tz;
850 int *cutoff_cnt;
851};
852
brian m. carlson9461d272017-02-21 23:47:32 +0000853static int read_ref_at_ent(struct object_id *ooid, struct object_id *noid,
Johannes Schindelindddbad72017-04-26 21:29:31 +0200854 const char *email, timestamp_t timestamp, int tz,
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700855 const char *message, void *cb_data)
Junio C Hamano16d7cc92007-01-19 01:19:05 -0800856{
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700857 struct read_ref_at_cb *cb = cb_data;
858
859 cb->reccnt++;
860 cb->tz = tz;
861 cb->date = timestamp;
862
863 if (timestamp <= cb->at_time || cb->cnt == 0) {
864 if (cb->msg)
865 *cb->msg = xstrdup(message);
866 if (cb->cutoff_time)
867 *cb->cutoff_time = timestamp;
868 if (cb->cutoff_tz)
869 *cb->cutoff_tz = tz;
870 if (cb->cutoff_cnt)
871 *cb->cutoff_cnt = cb->reccnt - 1;
872 /*
Michael Haggerty78fb4572017-11-05 09:42:09 +0100873 * we have not yet updated cb->[n|o]oid so they still
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700874 * hold the values for the previous record.
875 */
brian m. carlson8eb36d92017-10-15 22:07:03 +0000876 if (!is_null_oid(&cb->ooid)) {
877 oidcpy(cb->oid, noid);
878 if (oidcmp(&cb->ooid, noid))
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +0200879 warning(_("log for ref %s has gap after %s"),
Jeff Kinga5481a62015-06-25 12:55:02 -0400880 cb->refname, show_date(cb->date, cb->tz, DATE_MODE(RFC2822)));
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700881 }
882 else if (cb->date == cb->at_time)
brian m. carlson8eb36d92017-10-15 22:07:03 +0000883 oidcpy(cb->oid, noid);
884 else if (oidcmp(noid, cb->oid))
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +0200885 warning(_("log for ref %s unexpectedly ended on %s"),
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700886 cb->refname, show_date(cb->date, cb->tz,
Jeff Kinga5481a62015-06-25 12:55:02 -0400887 DATE_MODE(RFC2822)));
brian m. carlson8eb36d92017-10-15 22:07:03 +0000888 oidcpy(&cb->ooid, ooid);
889 oidcpy(&cb->noid, noid);
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700890 cb->found_it = 1;
891 return 1;
892 }
brian m. carlson8eb36d92017-10-15 22:07:03 +0000893 oidcpy(&cb->ooid, ooid);
894 oidcpy(&cb->noid, noid);
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700895 if (cb->cnt > 0)
896 cb->cnt--;
897 return 0;
898}
899
brian m. carlson9461d272017-02-21 23:47:32 +0000900static int read_ref_at_ent_oldest(struct object_id *ooid, struct object_id *noid,
Johannes Schindelindddbad72017-04-26 21:29:31 +0200901 const char *email, timestamp_t timestamp,
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700902 int tz, const char *message, void *cb_data)
903{
904 struct read_ref_at_cb *cb = cb_data;
905
906 if (cb->msg)
907 *cb->msg = xstrdup(message);
908 if (cb->cutoff_time)
909 *cb->cutoff_time = timestamp;
910 if (cb->cutoff_tz)
911 *cb->cutoff_tz = tz;
912 if (cb->cutoff_cnt)
913 *cb->cutoff_cnt = cb->reccnt;
brian m. carlson8eb36d92017-10-15 22:07:03 +0000914 oidcpy(cb->oid, ooid);
915 if (is_null_oid(cb->oid))
916 oidcpy(cb->oid, noid);
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700917 /* We just want the first entry */
918 return 1;
Junio C Hamano16d7cc92007-01-19 01:19:05 -0800919}
920
Johannes Schindelindddbad72017-04-26 21:29:31 +0200921int read_ref_at(const char *refname, unsigned int flags, timestamp_t at_time, int cnt,
brian m. carlson8eb36d92017-10-15 22:07:03 +0000922 struct object_id *oid, char **msg,
Johannes Schindelindddbad72017-04-26 21:29:31 +0200923 timestamp_t *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
Shawn Pearced556fae2006-05-17 05:56:09 -0400924{
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700925 struct read_ref_at_cb cb;
Shawn Pearced556fae2006-05-17 05:56:09 -0400926
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700927 memset(&cb, 0, sizeof(cb));
928 cb.refname = refname;
929 cb.at_time = at_time;
930 cb.cnt = cnt;
931 cb.msg = msg;
932 cb.cutoff_time = cutoff_time;
933 cb.cutoff_tz = cutoff_tz;
934 cb.cutoff_cnt = cutoff_cnt;
brian m. carlson8eb36d92017-10-15 22:07:03 +0000935 cb.oid = oid;
Shawn Pearced556fae2006-05-17 05:56:09 -0400936
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700937 for_each_reflog_ent_reverse(refname, read_ref_at_ent, &cb);
Shawn Pearced556fae2006-05-17 05:56:09 -0400938
David Aguilarc41a87d2014-09-18 20:45:37 -0700939 if (!cb.reccnt) {
brian m. carlson321c89b2017-07-13 23:49:29 +0000940 if (flags & GET_OID_QUIETLY)
David Aguilarc41a87d2014-09-18 20:45:37 -0700941 exit(128);
942 else
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +0200943 die(_("log for %s is empty"), refname);
David Aguilarc41a87d2014-09-18 20:45:37 -0700944 }
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700945 if (cb.found_it)
946 return 0;
Junio C Hamano16d7cc92007-01-19 01:19:05 -0800947
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700948 for_each_reflog_ent(refname, read_ref_at_ent_oldest, &cb);
949
Junio C Hamano16d7cc92007-01-19 01:19:05 -0800950 return 1;
Shawn Pearced556fae2006-05-17 05:56:09 -0400951}
Junio C Hamano2ff81662006-12-18 01:18:16 -0800952
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700953struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs,
954 struct strbuf *err)
Michael Haggertycaa40462014-04-07 15:48:10 +0200955{
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700956 struct ref_transaction *tr;
Jonathan Nieder5a603b02014-08-28 16:42:37 -0700957 assert(err);
958
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700959 tr = xcalloc(1, sizeof(struct ref_transaction));
960 tr->ref_store = refs;
961 return tr;
962}
963
964struct ref_transaction *ref_transaction_begin(struct strbuf *err)
965{
Stefan Beller23a3f0c2018-04-11 17:21:09 -0700966 return ref_store_transaction_begin(get_main_ref_store(the_repository), err);
Michael Haggertycaa40462014-04-07 15:48:10 +0200967}
968
Ronnie Sahlberg026bd1d2014-06-20 07:42:42 -0700969void ref_transaction_free(struct ref_transaction *transaction)
Michael Haggertycaa40462014-04-07 15:48:10 +0200970{
Michael Haggerty43a2dfd2017-05-22 16:17:37 +0200971 size_t i;
Michael Haggertycaa40462014-04-07 15:48:10 +0200972
Ronnie Sahlberg1b072552014-06-20 07:42:45 -0700973 if (!transaction)
974 return;
975
Michael Haggerty30173b82017-05-22 16:17:44 +0200976 switch (transaction->state) {
977 case REF_TRANSACTION_OPEN:
978 case REF_TRANSACTION_CLOSED:
979 /* OK */
980 break;
981 case REF_TRANSACTION_PREPARED:
Johannes Schindelin033abf92018-05-02 11:38:39 +0200982 BUG("free called on a prepared reference transaction");
Michael Haggerty30173b82017-05-22 16:17:44 +0200983 break;
984 default:
Johannes Schindelin033abf92018-05-02 11:38:39 +0200985 BUG("unexpected reference transaction state");
Michael Haggerty30173b82017-05-22 16:17:44 +0200986 break;
987 }
988
Ronnie Sahlbergdb7516a2014-04-30 12:22:42 -0700989 for (i = 0; i < transaction->nr; i++) {
990 free(transaction->updates[i]->msg);
Michael Haggerty88615912014-04-07 15:48:14 +0200991 free(transaction->updates[i]);
Ronnie Sahlbergdb7516a2014-04-30 12:22:42 -0700992 }
Michael Haggertycaa40462014-04-07 15:48:10 +0200993 free(transaction->updates);
994 free(transaction);
995}
996
Michael Haggerty71564512016-04-25 11:39:54 +0200997struct ref_update *ref_transaction_add_update(
998 struct ref_transaction *transaction,
999 const char *refname, unsigned int flags,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001000 const struct object_id *new_oid,
1001 const struct object_id *old_oid,
Michael Haggerty71564512016-04-25 11:39:54 +02001002 const char *msg)
Michael Haggertycaa40462014-04-07 15:48:10 +02001003{
Jeff King96ffc062016-02-22 17:44:32 -05001004 struct ref_update *update;
Michael Haggerty71564512016-04-25 11:39:54 +02001005
1006 if (transaction->state != REF_TRANSACTION_OPEN)
Johannes Schindelin033abf92018-05-02 11:38:39 +02001007 BUG("update called for transaction that is not open");
Michael Haggerty71564512016-04-25 11:39:54 +02001008
Jeff King96ffc062016-02-22 17:44:32 -05001009 FLEX_ALLOC_STR(update, refname, refname);
Michael Haggertycaa40462014-04-07 15:48:10 +02001010 ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc);
1011 transaction->updates[transaction->nr++] = update;
Michael Haggerty71564512016-04-25 11:39:54 +02001012
1013 update->flags = flags;
1014
1015 if (flags & REF_HAVE_NEW)
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001016 oidcpy(&update->new_oid, new_oid);
Michael Haggerty71564512016-04-25 11:39:54 +02001017 if (flags & REF_HAVE_OLD)
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001018 oidcpy(&update->old_oid, old_oid);
Junio C Hamano13092a92016-10-12 11:20:23 -07001019 update->msg = xstrdup_or_null(msg);
Michael Haggertycaa40462014-04-07 15:48:10 +02001020 return update;
1021}
1022
Ronnie Sahlberg8e348002014-06-20 07:43:00 -07001023int ref_transaction_update(struct ref_transaction *transaction,
1024 const char *refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001025 const struct object_id *new_oid,
1026 const struct object_id *old_oid,
Michael Haggerty1d147bd2015-02-17 18:00:15 +01001027 unsigned int flags, const char *msg,
Ronnie Sahlberg8e348002014-06-20 07:43:00 -07001028 struct strbuf *err)
Michael Haggertycaa40462014-04-07 15:48:10 +02001029{
Jonathan Nieder5a603b02014-08-28 16:42:37 -07001030 assert(err);
1031
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001032 if ((new_oid && !is_null_oid(new_oid)) ?
Michael Haggerty8a679de2016-04-27 15:54:45 +02001033 check_refname_format(refname, REFNAME_ALLOW_ONELEVEL) :
1034 !refname_is_safe(refname)) {
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +02001035 strbuf_addf(err, _("refusing to update ref with bad name '%s'"),
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -07001036 refname);
1037 return -1;
1038 }
1039
Michael Haggertya9bbbce2017-11-05 09:42:03 +01001040 if (flags & ~REF_TRANSACTION_UPDATE_ALLOWED_FLAGS)
1041 BUG("illegal flags 0x%x passed to ref_transaction_update()", flags);
Thomas Gummererc788c542017-09-12 23:59:21 +01001042
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001043 flags |= (new_oid ? REF_HAVE_NEW : 0) | (old_oid ? REF_HAVE_OLD : 0);
Michael Haggerty71564512016-04-25 11:39:54 +02001044
1045 ref_transaction_add_update(transaction, refname, flags,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001046 new_oid, old_oid, msg);
Ronnie Sahlberg8e348002014-06-20 07:43:00 -07001047 return 0;
Michael Haggertycaa40462014-04-07 15:48:10 +02001048}
1049
Ronnie Sahlbergb416af52014-04-16 15:26:44 -07001050int ref_transaction_create(struct ref_transaction *transaction,
1051 const char *refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001052 const struct object_id *new_oid,
Michael Haggertyfec14ec2015-02-17 18:00:13 +01001053 unsigned int flags, const char *msg,
Ronnie Sahlbergb416af52014-04-16 15:26:44 -07001054 struct strbuf *err)
Michael Haggertycaa40462014-04-07 15:48:10 +02001055{
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001056 if (!new_oid || is_null_oid(new_oid))
Johannes Schindelin033abf92018-05-02 11:38:39 +02001057 BUG("create called without valid new_oid");
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001058 return ref_transaction_update(transaction, refname, new_oid,
1059 &null_oid, flags, msg, err);
Michael Haggertycaa40462014-04-07 15:48:10 +02001060}
1061
Ronnie Sahlberg8c8bdc02014-04-16 15:27:45 -07001062int ref_transaction_delete(struct ref_transaction *transaction,
1063 const char *refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001064 const struct object_id *old_oid,
Michael Haggertyfb5a6bb2015-02-17 18:00:16 +01001065 unsigned int flags, const char *msg,
Ronnie Sahlberg8c8bdc02014-04-16 15:27:45 -07001066 struct strbuf *err)
Michael Haggertycaa40462014-04-07 15:48:10 +02001067{
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001068 if (old_oid && is_null_oid(old_oid))
Johannes Schindelin033abf92018-05-02 11:38:39 +02001069 BUG("delete called with old_oid set to zeros");
Michael Haggerty1d147bd2015-02-17 18:00:15 +01001070 return ref_transaction_update(transaction, refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001071 &null_oid, old_oid,
Michael Haggerty1d147bd2015-02-17 18:00:15 +01001072 flags, msg, err);
Michael Haggertycaa40462014-04-07 15:48:10 +02001073}
1074
Michael Haggerty16180332015-02-17 18:00:21 +01001075int ref_transaction_verify(struct ref_transaction *transaction,
1076 const char *refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001077 const struct object_id *old_oid,
Michael Haggerty16180332015-02-17 18:00:21 +01001078 unsigned int flags,
1079 struct strbuf *err)
1080{
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001081 if (!old_oid)
Johannes Schindelin033abf92018-05-02 11:38:39 +02001082 BUG("verify called with old_oid set to NULL");
Michael Haggerty16180332015-02-17 18:00:21 +01001083 return ref_transaction_update(transaction, refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001084 NULL, old_oid,
Michael Haggerty16180332015-02-17 18:00:21 +01001085 flags, NULL, err);
1086}
1087
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001088int refs_update_ref(struct ref_store *refs, const char *msg,
brian m. carlsonae077772017-10-15 22:06:51 +00001089 const char *refname, const struct object_id *new_oid,
1090 const struct object_id *old_oid, unsigned int flags,
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001091 enum action_on_err onerr)
Brad King4738a332013-09-04 11:22:40 -04001092{
David Turner74ec19d2015-07-31 02:06:19 -04001093 struct ref_transaction *t = NULL;
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001094 struct strbuf err = STRBUF_INIT;
David Turner74ec19d2015-07-31 02:06:19 -04001095 int ret = 0;
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001096
David Turner74ec19d2015-07-31 02:06:19 -04001097 if (ref_type(refname) == REF_TYPE_PSEUDOREF) {
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001098 assert(refs == get_main_ref_store(the_repository));
brian m. carlsonae077772017-10-15 22:06:51 +00001099 ret = write_pseudoref(refname, new_oid, old_oid, &err);
David Turner74ec19d2015-07-31 02:06:19 -04001100 } else {
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001101 t = ref_store_transaction_begin(refs, &err);
David Turner74ec19d2015-07-31 02:06:19 -04001102 if (!t ||
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001103 ref_transaction_update(t, refname, new_oid, old_oid,
David Turner74ec19d2015-07-31 02:06:19 -04001104 flags, msg, &err) ||
1105 ref_transaction_commit(t, &err)) {
1106 ret = 1;
1107 ref_transaction_free(t);
1108 }
1109 }
1110 if (ret) {
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +02001111 const char *str = _("update_ref failed for ref '%s': %s");
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001112
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001113 switch (onerr) {
1114 case UPDATE_REFS_MSG_ON_ERR:
1115 error(str, refname, err.buf);
1116 break;
1117 case UPDATE_REFS_DIE_ON_ERR:
1118 die(str, refname, err.buf);
1119 break;
1120 case UPDATE_REFS_QUIET_ON_ERR:
1121 break;
1122 }
1123 strbuf_release(&err);
Brad King4738a332013-09-04 11:22:40 -04001124 return 1;
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001125 }
1126 strbuf_release(&err);
David Turner74ec19d2015-07-31 02:06:19 -04001127 if (t)
1128 ref_transaction_free(t);
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001129 return 0;
Brad King4738a332013-09-04 11:22:40 -04001130}
1131
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001132int update_ref(const char *msg, const char *refname,
brian m. carlsonae077772017-10-15 22:06:51 +00001133 const struct object_id *new_oid,
1134 const struct object_id *old_oid,
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001135 unsigned int flags, enum action_on_err onerr)
1136{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001137 return refs_update_ref(get_main_ref_store(the_repository), msg, refname, new_oid,
brian m. carlsonae077772017-10-15 22:06:51 +00001138 old_oid, flags, onerr);
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001139}
1140
Michael Haggertydfefa932011-12-12 06:38:09 +01001141char *shorten_unambiguous_ref(const char *refname, int strict)
Jeff King7c2b3022009-04-07 03:14:20 -04001142{
1143 int i;
1144 static char **scanf_fmts;
1145 static int nr_rules;
1146 char *short_name;
Jeff King6cd4a892017-03-28 15:46:33 -04001147 struct strbuf resolved_buf = STRBUF_INIT;
Jeff King7c2b3022009-04-07 03:14:20 -04001148
Jeff King7c2b3022009-04-07 03:14:20 -04001149 if (!nr_rules) {
Michael Haggerty43466632014-01-08 15:43:39 +01001150 /*
1151 * Pre-generate scanf formats from ref_rev_parse_rules[].
1152 * Generate a format suitable for scanf from a
1153 * ref_rev_parse_rules rule by interpolating "%s" at the
1154 * location of the "%.*s".
1155 */
Jeff King7c2b3022009-04-07 03:14:20 -04001156 size_t total_len = 0;
Michael Haggerty84d56332014-01-08 15:43:38 +01001157 size_t offset = 0;
Jeff King7c2b3022009-04-07 03:14:20 -04001158
1159 /* the rule list is NULL terminated, count them first */
Jeff Kinga4165852013-10-24 04:45:13 -04001160 for (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++)
Michael Haggerty7902fe02014-01-08 15:43:40 +01001161 /* -2 for strlen("%.*s") - strlen("%s"); +1 for NUL */
1162 total_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 + 1;
Jeff King7c2b3022009-04-07 03:14:20 -04001163
René Scharfe50492f72016-07-30 20:18:31 +02001164 scanf_fmts = xmalloc(st_add(st_mult(sizeof(char *), nr_rules), total_len));
Jeff King7c2b3022009-04-07 03:14:20 -04001165
Michael Haggerty84d56332014-01-08 15:43:38 +01001166 offset = 0;
Jeff King7c2b3022009-04-07 03:14:20 -04001167 for (i = 0; i < nr_rules; i++) {
Michael Haggerty43466632014-01-08 15:43:39 +01001168 assert(offset < total_len);
Michael Haggerty84d56332014-01-08 15:43:38 +01001169 scanf_fmts[i] = (char *)&scanf_fmts[nr_rules] + offset;
Jeff Kingbf4baf12018-05-18 18:58:20 -07001170 offset += xsnprintf(scanf_fmts[i], total_len - offset,
1171 ref_rev_parse_rules[i], 2, "%s") + 1;
Jeff King7c2b3022009-04-07 03:14:20 -04001172 }
1173 }
1174
1175 /* bail out if there are no rules */
1176 if (!nr_rules)
Michael Haggertydfefa932011-12-12 06:38:09 +01001177 return xstrdup(refname);
Jeff King7c2b3022009-04-07 03:14:20 -04001178
Michael Haggertydfefa932011-12-12 06:38:09 +01001179 /* buffer for scanf result, at most refname must fit */
1180 short_name = xstrdup(refname);
Jeff King7c2b3022009-04-07 03:14:20 -04001181
1182 /* skip first rule, it will always match */
1183 for (i = nr_rules - 1; i > 0 ; --i) {
1184 int j;
Bert Wesarg6e7b3302009-04-13 12:25:46 +02001185 int rules_to_fail = i;
Jeff King7c2b3022009-04-07 03:14:20 -04001186 int short_name_len;
1187
Michael Haggertydfefa932011-12-12 06:38:09 +01001188 if (1 != sscanf(refname, scanf_fmts[i], short_name))
Jeff King7c2b3022009-04-07 03:14:20 -04001189 continue;
1190
1191 short_name_len = strlen(short_name);
1192
1193 /*
Bert Wesarg6e7b3302009-04-13 12:25:46 +02001194 * in strict mode, all (except the matched one) rules
1195 * must fail to resolve to a valid non-ambiguous ref
1196 */
1197 if (strict)
1198 rules_to_fail = nr_rules;
1199
1200 /*
Jeff King7c2b3022009-04-07 03:14:20 -04001201 * check if the short name resolves to a valid ref,
1202 * but use only rules prior to the matched one
1203 */
Bert Wesarg6e7b3302009-04-13 12:25:46 +02001204 for (j = 0; j < rules_to_fail; j++) {
Jeff King7c2b3022009-04-07 03:14:20 -04001205 const char *rule = ref_rev_parse_rules[j];
Jeff King7c2b3022009-04-07 03:14:20 -04001206
Bert Wesarg6e7b3302009-04-13 12:25:46 +02001207 /* skip matched rule */
1208 if (i == j)
1209 continue;
1210
Jeff King7c2b3022009-04-07 03:14:20 -04001211 /*
1212 * the short name is ambiguous, if it resolves
1213 * (with this previous rule) to a valid ref
1214 * read_ref() returns 0 on success
1215 */
Jeff King6cd4a892017-03-28 15:46:33 -04001216 strbuf_reset(&resolved_buf);
1217 strbuf_addf(&resolved_buf, rule,
1218 short_name_len, short_name);
1219 if (ref_exists(resolved_buf.buf))
Jeff King7c2b3022009-04-07 03:14:20 -04001220 break;
1221 }
1222
1223 /*
1224 * short name is non-ambiguous if all previous rules
1225 * haven't resolved to a valid ref
1226 */
Jeff King6cd4a892017-03-28 15:46:33 -04001227 if (j == rules_to_fail) {
1228 strbuf_release(&resolved_buf);
Jeff King7c2b3022009-04-07 03:14:20 -04001229 return short_name;
Jeff King6cd4a892017-03-28 15:46:33 -04001230 }
Jeff King7c2b3022009-04-07 03:14:20 -04001231 }
1232
Jeff King6cd4a892017-03-28 15:46:33 -04001233 strbuf_release(&resolved_buf);
Jeff King7c2b3022009-04-07 03:14:20 -04001234 free(short_name);
Michael Haggertydfefa932011-12-12 06:38:09 +01001235 return xstrdup(refname);
Jeff King7c2b3022009-04-07 03:14:20 -04001236}
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001237
1238static struct string_list *hide_refs;
1239
1240int parse_hide_refs_config(const char *var, const char *value, const char *section)
1241{
Jeff Kingad8c7cd2017-02-24 16:08:16 -05001242 const char *key;
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001243 if (!strcmp("transfer.hiderefs", var) ||
Jeff Kingad8c7cd2017-02-24 16:08:16 -05001244 (!parse_config_key(var, section, NULL, NULL, &key) &&
1245 !strcmp(key, "hiderefs"))) {
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001246 char *ref;
1247 int len;
1248
1249 if (!value)
1250 return config_error_nonbool(var);
1251 ref = xstrdup(value);
1252 len = strlen(ref);
1253 while (len && ref[len - 1] == '/')
1254 ref[--len] = '\0';
1255 if (!hide_refs) {
1256 hide_refs = xcalloc(1, sizeof(*hide_refs));
1257 hide_refs->strdup_strings = 1;
1258 }
1259 string_list_append(hide_refs, ref);
1260 }
1261 return 0;
1262}
1263
Lukas Fleischer78a766a2015-11-03 08:58:16 +01001264int ref_is_hidden(const char *refname, const char *refname_full)
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001265{
Jeff King2bc31d12015-07-28 16:23:26 -04001266 int i;
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001267
1268 if (!hide_refs)
1269 return 0;
Jeff King2bc31d12015-07-28 16:23:26 -04001270 for (i = hide_refs->nr - 1; i >= 0; i--) {
1271 const char *match = hide_refs->items[i].string;
Lukas Fleischer78a766a2015-11-03 08:58:16 +01001272 const char *subject;
Jeff King2bc31d12015-07-28 16:23:26 -04001273 int neg = 0;
Christian Couder7a40a952017-07-22 06:39:12 +02001274 const char *p;
Jeff King2bc31d12015-07-28 16:23:26 -04001275
1276 if (*match == '!') {
1277 neg = 1;
1278 match++;
1279 }
1280
Lukas Fleischer78a766a2015-11-03 08:58:16 +01001281 if (*match == '^') {
1282 subject = refname_full;
1283 match++;
1284 } else {
1285 subject = refname;
1286 }
1287
1288 /* refname can be NULL when namespaces are used. */
Christian Couder7a40a952017-07-22 06:39:12 +02001289 if (subject &&
1290 skip_prefix(subject, match, &p) &&
1291 (!*p || *p == '/'))
Jeff King2bc31d12015-07-28 16:23:26 -04001292 return !neg;
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001293 }
1294 return 0;
1295}
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001296
David Turner08451222015-11-10 12:42:40 +01001297const char *find_descendant_ref(const char *dirname,
1298 const struct string_list *extras,
1299 const struct string_list *skip)
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001300{
David Turner08451222015-11-10 12:42:40 +01001301 int pos;
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001302
David Turner08451222015-11-10 12:42:40 +01001303 if (!extras)
1304 return NULL;
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001305
1306 /*
David Turner08451222015-11-10 12:42:40 +01001307 * Look at the place where dirname would be inserted into
1308 * extras. If there is an entry at that position that starts
1309 * with dirname (remember, dirname includes the trailing
1310 * slash) and is not in skip, then we have a conflict.
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001311 */
David Turner08451222015-11-10 12:42:40 +01001312 for (pos = string_list_find_insert_index(extras, dirname, 0);
1313 pos < extras->nr; pos++) {
1314 const char *extra_refname = extras->items[pos].string;
1315
1316 if (!starts_with(extra_refname, dirname))
1317 break;
1318
1319 if (!skip || !string_list_has_string(skip, extra_refname))
1320 return extra_refname;
Michael Haggerty4a32b2e2015-05-11 17:25:15 +02001321 }
David Turner08451222015-11-10 12:42:40 +01001322 return NULL;
1323}
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001324
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001325int refs_rename_ref_available(struct ref_store *refs,
1326 const char *old_refname,
1327 const char *new_refname)
David Turner08451222015-11-10 12:42:40 +01001328{
1329 struct string_list skip = STRING_LIST_INIT_NODUP;
1330 struct strbuf err = STRBUF_INIT;
David Turnerff3a2992016-09-04 18:08:08 +02001331 int ok;
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001332
David Turnerff3a2992016-09-04 18:08:08 +02001333 string_list_insert(&skip, old_refname);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001334 ok = !refs_verify_refname_available(refs, new_refname,
1335 NULL, &skip, &err);
David Turnerff3a2992016-09-04 18:08:08 +02001336 if (!ok)
David Turner08451222015-11-10 12:42:40 +01001337 error("%s", err.buf);
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001338
David Turner08451222015-11-10 12:42:40 +01001339 string_list_clear(&skip, 0);
1340 strbuf_release(&err);
David Turnerff3a2992016-09-04 18:08:08 +02001341 return ok;
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001342}
David Turner2bf68ed2016-04-07 15:02:48 -04001343
Nguyễn Thái Ngọc Duy62f0b392017-08-23 19:36:55 +07001344int refs_head_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
David Turner2bf68ed2016-04-07 15:02:48 -04001345{
1346 struct object_id oid;
1347 int flag;
1348
Nguyễn Thái Ngọc Duy62f0b392017-08-23 19:36:55 +07001349 if (!refs_read_ref_full(refs, "HEAD", RESOLVE_REF_READING,
brian m. carlson34c290a2017-10-15 22:06:56 +00001350 &oid, &flag))
David Turner2bf68ed2016-04-07 15:02:48 -04001351 return fn("HEAD", &oid, flag, cb_data);
1352
1353 return 0;
1354}
1355
1356int head_ref(each_ref_fn fn, void *cb_data)
1357{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001358 return refs_head_ref(get_main_ref_store(the_repository), fn, cb_data);
David Turner2bf68ed2016-04-07 15:02:48 -04001359}
David Turner93770592016-04-07 15:02:49 -04001360
Michael Haggertye121b9c2017-03-20 17:33:08 +01001361struct ref_iterator *refs_ref_iterator_begin(
1362 struct ref_store *refs,
1363 const char *prefix, int trim, int flags)
1364{
1365 struct ref_iterator *iter;
1366
Michael Haggerty0a0865b2017-05-22 16:17:52 +02001367 if (ref_paranoia < 0)
1368 ref_paranoia = git_env_bool("GIT_REF_PARANOIA", 0);
1369 if (ref_paranoia)
1370 flags |= DO_FOR_EACH_INCLUDE_BROKEN;
1371
Michael Haggertye121b9c2017-03-20 17:33:08 +01001372 iter = refs->be->iterator_begin(refs, prefix, flags);
Michael Haggertyc7599712017-05-22 16:17:36 +02001373
1374 /*
1375 * `iterator_begin()` already takes care of prefix, but we
1376 * might need to do some trimming:
1377 */
1378 if (trim)
1379 iter = prefix_ref_iterator_begin(iter, "", trim);
Michael Haggertye121b9c2017-03-20 17:33:08 +01001380
Michael Haggerty8738a8a2017-09-13 19:15:55 +02001381 /* Sanity check for subclasses: */
1382 if (!iter->ordered)
1383 BUG("reference iterator is not ordered");
1384
Michael Haggertye121b9c2017-03-20 17:33:08 +01001385 return iter;
1386}
1387
Michael Haggerty4c4de892016-06-18 06:15:16 +02001388/*
1389 * Call fn for each reference in the specified submodule for which the
1390 * refname begins with prefix. If trim is non-zero, then trim that
1391 * many characters off the beginning of each refname before passing
1392 * the refname to fn. flags can be DO_FOR_EACH_INCLUDE_BROKEN to
1393 * include broken references in the iteration. If fn ever returns a
1394 * non-zero value, stop the iteration and return that value;
1395 * otherwise, return 0.
1396 */
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001397static int do_for_each_ref(struct ref_store *refs, const char *prefix,
Michael Haggerty4c4de892016-06-18 06:15:16 +02001398 each_ref_fn fn, int trim, int flags, void *cb_data)
1399{
1400 struct ref_iterator *iter;
1401
Michael Haggerty00eebe32016-09-04 18:08:11 +02001402 if (!refs)
1403 return 0;
1404
Michael Haggertye121b9c2017-03-20 17:33:08 +01001405 iter = refs_ref_iterator_begin(refs, prefix, trim, flags);
Michael Haggerty4c4de892016-06-18 06:15:16 +02001406
1407 return do_for_each_ref_iterator(iter, fn, cb_data);
1408}
1409
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001410int refs_for_each_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
1411{
1412 return do_for_each_ref(refs, "", fn, 0, 0, cb_data);
1413}
1414
David Turner93770592016-04-07 15:02:49 -04001415int for_each_ref(each_ref_fn fn, void *cb_data)
1416{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001417 return refs_for_each_ref(get_main_ref_store(the_repository), fn, cb_data);
David Turner93770592016-04-07 15:02:49 -04001418}
1419
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001420int refs_for_each_ref_in(struct ref_store *refs, const char *prefix,
1421 each_ref_fn fn, void *cb_data)
1422{
1423 return do_for_each_ref(refs, prefix, fn, strlen(prefix), 0, cb_data);
David Turner93770592016-04-07 15:02:49 -04001424}
1425
1426int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
1427{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001428 return refs_for_each_ref_in(get_main_ref_store(the_repository), prefix, fn, cb_data);
David Turner93770592016-04-07 15:02:49 -04001429}
1430
1431int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken)
1432{
1433 unsigned int flag = 0;
1434
1435 if (broken)
1436 flag = DO_FOR_EACH_INCLUDE_BROKEN;
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001437 return do_for_each_ref(get_main_ref_store(the_repository),
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001438 prefix, fn, 0, flag, cb_data);
David Turner93770592016-04-07 15:02:49 -04001439}
1440
Nguyễn Thái Ngọc Duy073cf632017-08-23 19:36:56 +07001441int refs_for_each_fullref_in(struct ref_store *refs, const char *prefix,
1442 each_ref_fn fn, void *cb_data,
1443 unsigned int broken)
Michael Haggerty03df5672017-06-18 15:39:41 +02001444{
1445 unsigned int flag = 0;
1446
1447 if (broken)
1448 flag = DO_FOR_EACH_INCLUDE_BROKEN;
Nguyễn Thái Ngọc Duy073cf632017-08-23 19:36:56 +07001449 return do_for_each_ref(refs, prefix, fn, 0, flag, cb_data);
Michael Haggerty03df5672017-06-18 15:39:41 +02001450}
1451
Stefan Beller0d296c52018-04-11 17:21:15 -07001452int for_each_replace_ref(struct repository *r, each_ref_fn fn, void *cb_data)
David Turner93770592016-04-07 15:02:49 -04001453{
Stefan Beller0d296c52018-04-11 17:21:15 -07001454 return do_for_each_ref(get_main_ref_store(r),
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001455 git_replace_ref_base, fn,
1456 strlen(git_replace_ref_base),
Stefan Beller006f3f22017-09-12 10:31:40 -07001457 DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
David Turner93770592016-04-07 15:02:49 -04001458}
1459
1460int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
1461{
1462 struct strbuf buf = STRBUF_INIT;
1463 int ret;
1464 strbuf_addf(&buf, "%srefs/", get_git_namespace());
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001465 ret = do_for_each_ref(get_main_ref_store(the_repository),
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001466 buf.buf, fn, 0, 0, cb_data);
David Turner93770592016-04-07 15:02:49 -04001467 strbuf_release(&buf);
1468 return ret;
1469}
1470
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001471int refs_for_each_rawref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
David Turner93770592016-04-07 15:02:49 -04001472{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001473 return do_for_each_ref(refs, "", fn, 0,
David Turner93770592016-04-07 15:02:49 -04001474 DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
1475}
David Turner2d0663b2016-04-07 15:03:10 -04001476
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001477int for_each_rawref(each_ref_fn fn, void *cb_data)
1478{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001479 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 +07001480}
1481
Michael Haggerty470be512017-03-20 17:33:07 +01001482int refs_read_raw_ref(struct ref_store *ref_store,
brian m. carlson99afe912017-10-15 22:07:11 +00001483 const char *refname, struct object_id *oid,
Michael Haggerty470be512017-03-20 17:33:07 +01001484 struct strbuf *referent, unsigned int *type)
1485{
brian m. carlson99afe912017-10-15 22:07:11 +00001486 return ref_store->be->read_raw_ref(ref_store, refname, oid, referent, type);
Michael Haggerty470be512017-03-20 17:33:07 +01001487}
1488
David Turner2d0663b2016-04-07 15:03:10 -04001489/* This function needs to return a meaningful errno on failure */
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001490const char *refs_resolve_ref_unsafe(struct ref_store *refs,
Michael Haggerty3c0cb0c2017-02-09 21:53:52 +01001491 const char *refname,
1492 int resolve_flags,
brian m. carlson49e61472017-10-15 22:07:09 +00001493 struct object_id *oid, int *flags)
David Turner2d0663b2016-04-07 15:03:10 -04001494{
1495 static struct strbuf sb_refname = STRBUF_INIT;
René Scharfe54fad662017-09-23 11:41:45 +02001496 struct object_id unused_oid;
David Turner2d0663b2016-04-07 15:03:10 -04001497 int unused_flags;
1498 int symref_count;
1499
brian m. carlson49e61472017-10-15 22:07:09 +00001500 if (!oid)
1501 oid = &unused_oid;
David Turner2d0663b2016-04-07 15:03:10 -04001502 if (!flags)
1503 flags = &unused_flags;
1504
1505 *flags = 0;
1506
1507 if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
1508 if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
1509 !refname_is_safe(refname)) {
1510 errno = EINVAL;
1511 return NULL;
1512 }
1513
1514 /*
1515 * dwim_ref() uses REF_ISBROKEN to distinguish between
1516 * missing refs and refs that were present but invalid,
1517 * to complain about the latter to stderr.
1518 *
1519 * We don't know whether the ref exists, so don't set
1520 * REF_ISBROKEN yet.
1521 */
1522 *flags |= REF_BAD_NAME;
1523 }
1524
1525 for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) {
1526 unsigned int read_flags = 0;
1527
Michael Haggerty470be512017-03-20 17:33:07 +01001528 if (refs_read_raw_ref(refs, refname,
brian m. carlson99afe912017-10-15 22:07:11 +00001529 oid, &sb_refname, &read_flags)) {
David Turner2d0663b2016-04-07 15:03:10 -04001530 *flags |= read_flags;
Jeff Kinga1c1d812017-10-06 10:42:17 -04001531
1532 /* In reading mode, refs must eventually resolve */
1533 if (resolve_flags & RESOLVE_REF_READING)
David Turner2d0663b2016-04-07 15:03:10 -04001534 return NULL;
Jeff Kinga1c1d812017-10-06 10:42:17 -04001535
1536 /*
1537 * Otherwise a missing ref is OK. But the files backend
1538 * may show errors besides ENOENT if there are
1539 * similarly-named refs.
1540 */
1541 if (errno != ENOENT &&
1542 errno != EISDIR &&
1543 errno != ENOTDIR)
1544 return NULL;
1545
brian m. carlson49e61472017-10-15 22:07:09 +00001546 oidclr(oid);
David Turner2d0663b2016-04-07 15:03:10 -04001547 if (*flags & REF_BAD_NAME)
1548 *flags |= REF_ISBROKEN;
1549 return refname;
1550 }
1551
1552 *flags |= read_flags;
1553
1554 if (!(read_flags & REF_ISSYMREF)) {
1555 if (*flags & REF_BAD_NAME) {
brian m. carlson49e61472017-10-15 22:07:09 +00001556 oidclr(oid);
David Turner2d0663b2016-04-07 15:03:10 -04001557 *flags |= REF_ISBROKEN;
1558 }
1559 return refname;
1560 }
1561
1562 refname = sb_refname.buf;
1563 if (resolve_flags & RESOLVE_REF_NO_RECURSE) {
brian m. carlson49e61472017-10-15 22:07:09 +00001564 oidclr(oid);
David Turner2d0663b2016-04-07 15:03:10 -04001565 return refname;
1566 }
1567 if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
1568 if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
1569 !refname_is_safe(refname)) {
1570 errno = EINVAL;
1571 return NULL;
1572 }
1573
1574 *flags |= REF_ISBROKEN | REF_BAD_NAME;
1575 }
1576 }
1577
1578 errno = ELOOP;
1579 return NULL;
1580}
Michael Haggerty00eebe32016-09-04 18:08:11 +02001581
David Turner6fb5acf2016-09-04 18:08:41 +02001582/* backend functions */
1583int refs_init_db(struct strbuf *err)
1584{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001585 struct ref_store *refs = get_main_ref_store(the_repository);
David Turner6fb5acf2016-09-04 18:08:41 +02001586
1587 return refs->be->init_db(refs, err);
1588}
1589
Michael Haggertybd40dcd2016-09-04 18:08:21 +02001590const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
brian m. carlson49e61472017-10-15 22:07:09 +00001591 struct object_id *oid, int *flags)
Michael Haggertybd40dcd2016-09-04 18:08:21 +02001592{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001593 return refs_resolve_ref_unsafe(get_main_ref_store(the_repository), refname,
brian m. carlson49e61472017-10-15 22:07:09 +00001594 resolve_flags, oid, flags);
Michael Haggertybd40dcd2016-09-04 18:08:21 +02001595}
1596
Michael Haggertya8355bb2016-09-04 18:08:24 +02001597int resolve_gitlink_ref(const char *submodule, const char *refname,
brian m. carlsona98e6102017-10-15 22:07:07 +00001598 struct object_id *oid)
Michael Haggerty424dcc72016-09-04 18:08:22 +02001599{
Michael Haggerty424dcc72016-09-04 18:08:22 +02001600 struct ref_store *refs;
1601 int flags;
1602
Nguyễn Thái Ngọc Duy29babbe2017-08-23 19:36:54 +07001603 refs = get_submodule_ref_store(submodule);
Michael Haggerty48a84752016-09-04 18:08:23 +02001604
Michael Haggerty424dcc72016-09-04 18:08:22 +02001605 if (!refs)
1606 return -1;
1607
brian m. carlson49e61472017-10-15 22:07:09 +00001608 if (!refs_resolve_ref_unsafe(refs, refname, 0, oid, &flags) ||
brian m. carlsona98e6102017-10-15 22:07:07 +00001609 is_null_oid(oid))
Michael Haggerty424dcc72016-09-04 18:08:22 +02001610 return -1;
1611 return 0;
1612}
1613
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001614struct ref_store_hash_entry
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001615{
1616 struct hashmap_entry ent; /* must be the first member! */
1617
1618 struct ref_store *refs;
1619
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001620 /* NUL-terminated identifier of the ref store: */
1621 char name[FLEX_ARRAY];
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001622};
1623
Stefan Beller7663cdc2017-06-30 12:14:05 -07001624static int ref_store_hash_cmp(const void *unused_cmp_data,
1625 const void *entry, const void *entry_or_key,
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001626 const void *keydata)
1627{
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001628 const struct ref_store_hash_entry *e1 = entry, *e2 = entry_or_key;
1629 const char *name = keydata ? keydata : e2->name;
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001630
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001631 return strcmp(e1->name, name);
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001632}
1633
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001634static struct ref_store_hash_entry *alloc_ref_store_hash_entry(
1635 const char *name, struct ref_store *refs)
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001636{
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001637 struct ref_store_hash_entry *entry;
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001638
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001639 FLEX_ALLOC_STR(entry, name, name);
1640 hashmap_entry_init(entry, strhash(name));
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001641 entry->refs = refs;
1642 return entry;
1643}
1644
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001645/* A hashmap of ref_stores, stored by submodule name: */
1646static struct hashmap submodule_ref_stores;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001647
Nguyễn Thái Ngọc Duy17eff962017-04-24 17:01:22 +07001648/* A hashmap of ref_stores, stored by worktree id: */
1649static struct hashmap worktree_ref_stores;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001650
Michael Haggerty00eebe32016-09-04 18:08:11 +02001651/*
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001652 * Look up a ref store by name. If that ref_store hasn't been
1653 * registered yet, return NULL.
Michael Haggerty00eebe32016-09-04 18:08:11 +02001654 */
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001655static struct ref_store *lookup_ref_store_map(struct hashmap *map,
1656 const char *name)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001657{
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001658 struct ref_store_hash_entry *entry;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001659
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001660 if (!map->tablesize)
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001661 /* It's initialized on demand in register_ref_store(). */
1662 return NULL;
Michael Haggerty620a66b2017-02-10 12:16:11 +01001663
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001664 entry = hashmap_get_from_hash(map, strhash(name), name);
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001665 return entry ? entry->refs : NULL;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001666}
1667
Michael Haggertyc468da42017-02-10 12:16:12 +01001668/*
1669 * Create, record, and return a ref_store instance for the specified
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +07001670 * gitdir.
Michael Haggertyc468da42017-02-10 12:16:12 +01001671 */
Nguyễn Thái Ngọc Duy9e7ec632017-03-26 09:42:32 +07001672static struct ref_store *ref_store_init(const char *gitdir,
1673 unsigned int flags)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001674{
1675 const char *be_name = "files";
1676 struct ref_storage_be *be = find_ref_storage_backend(be_name);
Michael Haggertyba88add2017-02-10 12:16:14 +01001677 struct ref_store *refs;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001678
1679 if (!be)
Johannes Schindelin033abf92018-05-02 11:38:39 +02001680 BUG("reference backend %s is unknown", be_name);
Michael Haggerty00eebe32016-09-04 18:08:11 +02001681
Nguyễn Thái Ngọc Duy9e7ec632017-03-26 09:42:32 +07001682 refs = be->init(gitdir, flags);
Michael Haggertyba88add2017-02-10 12:16:14 +01001683 return refs;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001684}
1685
Stefan Beller64a74162018-04-11 17:21:14 -07001686struct ref_store *get_main_ref_store(struct repository *r)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001687{
Stefan Beller64a74162018-04-11 17:21:14 -07001688 if (r->refs)
1689 return r->refs;
Nguyễn Thái Ngọc Duy24c84072017-03-26 09:42:25 +07001690
Jeff King2dc417a2018-05-18 15:25:53 -07001691 if (!r->gitdir)
1692 BUG("attempting to get main_ref_store outside of repository");
1693
Stefan Beller64a74162018-04-11 17:21:14 -07001694 r->refs = ref_store_init(r->gitdir, REF_STORE_ALL_CAPS);
1695 return r->refs;
Nguyễn Thái Ngọc Duy378dc912017-03-26 09:42:28 +07001696}
1697
1698/*
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001699 * Associate a ref store with a name. It is a fatal error to call this
1700 * function twice for the same name.
Nguyễn Thái Ngọc Duy378dc912017-03-26 09:42:28 +07001701 */
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001702static void register_ref_store_map(struct hashmap *map,
1703 const char *type,
1704 struct ref_store *refs,
1705 const char *name)
Nguyễn Thái Ngọc Duy378dc912017-03-26 09:42:28 +07001706{
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001707 if (!map->tablesize)
Stefan Beller7663cdc2017-06-30 12:14:05 -07001708 hashmap_init(map, ref_store_hash_cmp, NULL, 0);
Nguyễn Thái Ngọc Duy378dc912017-03-26 09:42:28 +07001709
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001710 if (hashmap_put(map, alloc_ref_store_hash_entry(name, refs)))
Johannes Schindelin033abf92018-05-02 11:38:39 +02001711 BUG("%s ref_store '%s' initialized twice", type, name);
Nguyễn Thái Ngọc Duy24c84072017-03-26 09:42:25 +07001712}
1713
Nguyễn Thái Ngọc Duy18d00022017-03-26 09:42:33 +07001714struct ref_store *get_submodule_ref_store(const char *submodule)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001715{
Nguyễn Thái Ngọc Duy126c9e02017-03-26 09:42:27 +07001716 struct strbuf submodule_sb = STRBUF_INIT;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001717 struct ref_store *refs;
Nguyễn Thái Ngọc Duy29babbe2017-08-23 19:36:54 +07001718 char *to_free = NULL;
1719 size_t len;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001720
Nguyễn Thái Ngọc Duy82a150f2017-08-23 19:37:03 +07001721 if (!submodule)
1722 return NULL;
1723
Nguyễn Thái Ngọc Duy873ea902017-08-23 19:37:04 +07001724 len = strlen(submodule);
1725 while (len && is_dir_sep(submodule[len - 1]))
1726 len--;
1727 if (!len)
1728 return NULL;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001729
Nguyễn Thái Ngọc Duy29babbe2017-08-23 19:36:54 +07001730 if (submodule[len])
1731 /* We need to strip off one or more trailing slashes */
1732 submodule = to_free = xmemdupz(submodule, len);
Michael Haggerty00eebe32016-09-04 18:08:11 +02001733
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001734 refs = lookup_ref_store_map(&submodule_ref_stores, submodule);
Nguyễn Thái Ngọc Duy126c9e02017-03-26 09:42:27 +07001735 if (refs)
Nguyễn Thái Ngọc Duy2c616c12017-08-23 19:36:53 +07001736 goto done;
Nguyễn Thái Ngọc Duy126c9e02017-03-26 09:42:27 +07001737
1738 strbuf_addstr(&submodule_sb, submodule);
Nguyễn Thái Ngọc Duy2c616c12017-08-23 19:36:53 +07001739 if (!is_nonbare_repository_dir(&submodule_sb))
1740 goto done;
Nguyễn Thái Ngọc Duy126c9e02017-03-26 09:42:27 +07001741
Nguyễn Thái Ngọc Duy2c616c12017-08-23 19:36:53 +07001742 if (submodule_to_gitdir(&submodule_sb, submodule))
1743 goto done;
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +07001744
Nguyễn Thái Ngọc Duy9e7ec632017-03-26 09:42:32 +07001745 /* assume that add_submodule_odb() has been called */
1746 refs = ref_store_init(submodule_sb.buf,
1747 REF_STORE_READ | REF_STORE_ODB);
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001748 register_ref_store_map(&submodule_ref_stores, "submodule",
1749 refs, submodule);
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +07001750
Nguyễn Thái Ngọc Duy2c616c12017-08-23 19:36:53 +07001751done:
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +07001752 strbuf_release(&submodule_sb);
Nguyễn Thái Ngọc Duy29babbe2017-08-23 19:36:54 +07001753 free(to_free);
1754
Michael Haggerty00eebe32016-09-04 18:08:11 +02001755 return refs;
1756}
1757
Nguyễn Thái Ngọc Duy17eff962017-04-24 17:01:22 +07001758struct ref_store *get_worktree_ref_store(const struct worktree *wt)
1759{
1760 struct ref_store *refs;
1761 const char *id;
1762
1763 if (wt->is_current)
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001764 return get_main_ref_store(the_repository);
Nguyễn Thái Ngọc Duy17eff962017-04-24 17:01:22 +07001765
1766 id = wt->id ? wt->id : "/";
1767 refs = lookup_ref_store_map(&worktree_ref_stores, id);
1768 if (refs)
1769 return refs;
1770
1771 if (wt->id)
1772 refs = ref_store_init(git_common_path("worktrees/%s", wt->id),
1773 REF_STORE_ALL_CAPS);
1774 else
1775 refs = ref_store_init(get_git_common_dir(),
1776 REF_STORE_ALL_CAPS);
1777
1778 if (refs)
1779 register_ref_store_map(&worktree_ref_stores, "worktree",
1780 refs, id);
1781 return refs;
1782}
1783
Michael Haggerty620a66b2017-02-10 12:16:11 +01001784void base_ref_store_init(struct ref_store *refs,
Michael Haggertyfbfd0a22017-02-10 12:16:17 +01001785 const struct ref_storage_be *be)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001786{
Michael Haggerty620a66b2017-02-10 12:16:11 +01001787 refs->be = be;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001788}
Ronnie Sahlberg127b42a2016-09-04 18:08:16 +02001789
1790/* backend functions */
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001791int refs_pack_refs(struct ref_store *refs, unsigned int flags)
Michael Haggerty82315272016-09-04 18:08:27 +02001792{
Michael Haggerty82315272016-09-04 18:08:27 +02001793 return refs->be->pack_refs(refs, flags);
1794}
1795
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001796int refs_peel_ref(struct ref_store *refs, const char *refname,
brian m. carlsonb420d902017-10-15 22:07:02 +00001797 struct object_id *oid)
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001798{
Michael Haggertyba1c0522017-09-25 10:00:14 +02001799 int flag;
brian m. carlson34c290a2017-10-15 22:06:56 +00001800 struct object_id base;
Michael Haggertyba1c0522017-09-25 10:00:14 +02001801
1802 if (current_ref_iter && current_ref_iter->refname == refname) {
1803 struct object_id peeled;
1804
1805 if (ref_iterator_peel(current_ref_iter, &peeled))
1806 return -1;
brian m. carlsonb420d902017-10-15 22:07:02 +00001807 oidcpy(oid, &peeled);
Michael Haggertyba1c0522017-09-25 10:00:14 +02001808 return 0;
1809 }
1810
1811 if (refs_read_ref_full(refs, refname,
brian m. carlson34c290a2017-10-15 22:06:56 +00001812 RESOLVE_REF_READING, &base, &flag))
Michael Haggertyba1c0522017-09-25 10:00:14 +02001813 return -1;
1814
brian m. carlsonac2ed0d2017-10-15 22:07:10 +00001815 return peel_object(&base, oid);
Ronnie Sahlberg127b42a2016-09-04 18:08:16 +02001816}
1817
brian m. carlsonb420d902017-10-15 22:07:02 +00001818int peel_ref(const char *refname, struct object_id *oid)
Michael Haggertybd427cf2016-09-04 18:08:29 +02001819{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001820 return refs_peel_ref(get_main_ref_store(the_repository), refname, oid);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001821}
Michael Haggertybd427cf2016-09-04 18:08:29 +02001822
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001823int refs_create_symref(struct ref_store *refs,
1824 const char *ref_target,
1825 const char *refs_heads_master,
1826 const char *logmsg)
1827{
1828 return refs->be->create_symref(refs, ref_target,
1829 refs_heads_master,
1830 logmsg);
Michael Haggertybd427cf2016-09-04 18:08:29 +02001831}
1832
Michael Haggerty284689b2016-09-04 18:08:28 +02001833int create_symref(const char *ref_target, const char *refs_heads_master,
1834 const char *logmsg)
1835{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07001836 return refs_create_symref(get_main_ref_store(the_repository), ref_target,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001837 refs_heads_master, logmsg);
Michael Haggerty284689b2016-09-04 18:08:28 +02001838}
1839
Michael Haggerty2ced1052017-05-22 16:17:45 +02001840int ref_update_reject_duplicates(struct string_list *refnames,
1841 struct strbuf *err)
1842{
Michael Haggertya552e502017-05-22 16:17:46 +02001843 size_t i, n = refnames->nr;
Michael Haggerty2ced1052017-05-22 16:17:45 +02001844
1845 assert(err);
1846
Michael Haggerty8556f8d2017-05-22 16:17:47 +02001847 for (i = 1; i < n; i++) {
1848 int cmp = strcmp(refnames->items[i - 1].string,
1849 refnames->items[i].string);
1850
1851 if (!cmp) {
Michael Haggerty2ced1052017-05-22 16:17:45 +02001852 strbuf_addf(err,
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +02001853 _("multiple updates for ref '%s' not allowed"),
Michael Haggerty2ced1052017-05-22 16:17:45 +02001854 refnames->items[i].string);
1855 return 1;
Michael Haggerty8556f8d2017-05-22 16:17:47 +02001856 } else if (cmp > 0) {
Johannes Schindelin033abf92018-05-02 11:38:39 +02001857 BUG("ref_update_reject_duplicates() received unsorted list");
Michael Haggerty2ced1052017-05-22 16:17:45 +02001858 }
Michael Haggerty8556f8d2017-05-22 16:17:47 +02001859 }
Michael Haggerty2ced1052017-05-22 16:17:45 +02001860 return 0;
1861}
1862
Michael Haggerty30173b82017-05-22 16:17:44 +02001863int ref_transaction_prepare(struct ref_transaction *transaction,
1864 struct strbuf *err)
Daniel Barkalow95fc7512005-06-06 16:31:29 -04001865{
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001866 struct ref_store *refs = transaction->ref_store;
Daniel Barkalow95fc7512005-06-06 16:31:29 -04001867
Michael Haggerty8d4240d2017-05-22 16:17:43 +02001868 switch (transaction->state) {
1869 case REF_TRANSACTION_OPEN:
1870 /* Good. */
1871 break;
Michael Haggerty30173b82017-05-22 16:17:44 +02001872 case REF_TRANSACTION_PREPARED:
Johannes Schindelin033abf92018-05-02 11:38:39 +02001873 BUG("prepare called twice on reference transaction");
Michael Haggerty30173b82017-05-22 16:17:44 +02001874 break;
Michael Haggerty8d4240d2017-05-22 16:17:43 +02001875 case REF_TRANSACTION_CLOSED:
Johannes Schindelin033abf92018-05-02 11:38:39 +02001876 BUG("prepare called on a closed reference transaction");
Michael Haggerty8d4240d2017-05-22 16:17:43 +02001877 break;
1878 default:
Johannes Schindelin033abf92018-05-02 11:38:39 +02001879 BUG("unexpected reference transaction state");
Michael Haggerty8d4240d2017-05-22 16:17:43 +02001880 break;
1881 }
1882
Jeff Kingd8f44812017-04-10 18:14:12 -04001883 if (getenv(GIT_QUARANTINE_ENVIRONMENT)) {
1884 strbuf_addstr(err,
1885 _("ref updates forbidden inside quarantine environment"));
1886 return -1;
1887 }
1888
Michael Haggerty30173b82017-05-22 16:17:44 +02001889 return refs->be->transaction_prepare(refs, transaction, err);
1890}
1891
1892int ref_transaction_abort(struct ref_transaction *transaction,
1893 struct strbuf *err)
1894{
1895 struct ref_store *refs = transaction->ref_store;
1896 int ret = 0;
1897
1898 switch (transaction->state) {
1899 case REF_TRANSACTION_OPEN:
1900 /* No need to abort explicitly. */
1901 break;
1902 case REF_TRANSACTION_PREPARED:
1903 ret = refs->be->transaction_abort(refs, transaction, err);
1904 break;
1905 case REF_TRANSACTION_CLOSED:
Johannes Schindelin033abf92018-05-02 11:38:39 +02001906 BUG("abort called on a closed reference transaction");
Michael Haggerty30173b82017-05-22 16:17:44 +02001907 break;
1908 default:
Johannes Schindelin033abf92018-05-02 11:38:39 +02001909 BUG("unexpected reference transaction state");
Michael Haggerty30173b82017-05-22 16:17:44 +02001910 break;
1911 }
1912
1913 ref_transaction_free(transaction);
1914 return ret;
1915}
1916
1917int ref_transaction_commit(struct ref_transaction *transaction,
1918 struct strbuf *err)
1919{
1920 struct ref_store *refs = transaction->ref_store;
1921 int ret;
1922
1923 switch (transaction->state) {
1924 case REF_TRANSACTION_OPEN:
1925 /* Need to prepare first. */
1926 ret = ref_transaction_prepare(transaction, err);
1927 if (ret)
1928 return ret;
1929 break;
1930 case REF_TRANSACTION_PREPARED:
1931 /* Fall through to finish. */
1932 break;
1933 case REF_TRANSACTION_CLOSED:
Johannes Schindelin033abf92018-05-02 11:38:39 +02001934 BUG("commit called on a closed reference transaction");
Michael Haggerty30173b82017-05-22 16:17:44 +02001935 break;
1936 default:
Johannes Schindelin033abf92018-05-02 11:38:39 +02001937 BUG("unexpected reference transaction state");
Michael Haggerty30173b82017-05-22 16:17:44 +02001938 break;
1939 }
1940
1941 return refs->be->transaction_finish(refs, transaction, err);
Daniel Barkalow95fc7512005-06-06 16:31:29 -04001942}
Michael Haggerty62665822016-09-04 18:08:26 +02001943
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001944int refs_verify_refname_available(struct ref_store *refs,
1945 const char *refname,
Michael Haggertyb05855b2017-04-16 08:41:26 +02001946 const struct string_list *extras,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001947 const struct string_list *skip,
1948 struct strbuf *err)
Michael Haggerty62665822016-09-04 18:08:26 +02001949{
Michael Haggertyb05855b2017-04-16 08:41:26 +02001950 const char *slash;
1951 const char *extra_refname;
1952 struct strbuf dirname = STRBUF_INIT;
1953 struct strbuf referent = STRBUF_INIT;
1954 struct object_id oid;
1955 unsigned int type;
1956 struct ref_iterator *iter;
1957 int ok;
1958 int ret = -1;
1959
1960 /*
1961 * For the sake of comments in this function, suppose that
1962 * refname is "refs/foo/bar".
1963 */
1964
1965 assert(err);
1966
1967 strbuf_grow(&dirname, strlen(refname) + 1);
1968 for (slash = strchr(refname, '/'); slash; slash = strchr(slash + 1, '/')) {
1969 /* Expand dirname to the new prefix, not including the trailing slash: */
1970 strbuf_add(&dirname, refname + dirname.len, slash - refname - dirname.len);
1971
1972 /*
1973 * We are still at a leading dir of the refname (e.g.,
1974 * "refs/foo"; if there is a reference with that name,
1975 * it is a conflict, *unless* it is in skip.
1976 */
1977 if (skip && string_list_has_string(skip, dirname.buf))
1978 continue;
1979
brian m. carlson99afe912017-10-15 22:07:11 +00001980 if (!refs_read_raw_ref(refs, dirname.buf, &oid, &referent, &type)) {
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +02001981 strbuf_addf(err, _("'%s' exists; cannot create '%s'"),
Michael Haggertyb05855b2017-04-16 08:41:26 +02001982 dirname.buf, refname);
1983 goto cleanup;
1984 }
1985
1986 if (extras && string_list_has_string(extras, dirname.buf)) {
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +02001987 strbuf_addf(err, _("cannot process '%s' and '%s' at the same time"),
Michael Haggertyb05855b2017-04-16 08:41:26 +02001988 refname, dirname.buf);
1989 goto cleanup;
1990 }
1991 }
1992
1993 /*
1994 * We are at the leaf of our refname (e.g., "refs/foo/bar").
1995 * There is no point in searching for a reference with that
1996 * name, because a refname isn't considered to conflict with
1997 * itself. But we still need to check for references whose
1998 * names are in the "refs/foo/bar/" namespace, because they
1999 * *do* conflict.
2000 */
2001 strbuf_addstr(&dirname, refname + dirname.len);
2002 strbuf_addch(&dirname, '/');
2003
2004 iter = refs_ref_iterator_begin(refs, dirname.buf, 0,
2005 DO_FOR_EACH_INCLUDE_BROKEN);
2006 while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
2007 if (skip &&
2008 string_list_has_string(skip, iter->refname))
2009 continue;
2010
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +02002011 strbuf_addf(err, _("'%s' exists; cannot create '%s'"),
Michael Haggertyb05855b2017-04-16 08:41:26 +02002012 iter->refname, refname);
2013 ref_iterator_abort(iter);
2014 goto cleanup;
2015 }
2016
2017 if (ok != ITER_DONE)
Johannes Schindelin033abf92018-05-02 11:38:39 +02002018 BUG("error while iterating over references");
Michael Haggertyb05855b2017-04-16 08:41:26 +02002019
2020 extra_refname = find_descendant_ref(dirname.buf, extras, skip);
2021 if (extra_refname)
Nguyễn Thái Ngọc Duy661558f2018-07-21 09:49:35 +02002022 strbuf_addf(err, _("cannot process '%s' and '%s' at the same time"),
Michael Haggertyb05855b2017-04-16 08:41:26 +02002023 refname, extra_refname);
2024 else
2025 ret = 0;
2026
2027cleanup:
2028 strbuf_release(&referent);
2029 strbuf_release(&dirname);
2030 return ret;
Michael Haggerty62665822016-09-04 18:08:26 +02002031}
David Turnere3688bd2016-09-04 18:08:38 +02002032
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002033int refs_for_each_reflog(struct ref_store *refs, each_ref_fn fn, void *cb_data)
David Turnere3688bd2016-09-04 18:08:38 +02002034{
David Turnere3688bd2016-09-04 18:08:38 +02002035 struct ref_iterator *iter;
2036
2037 iter = refs->be->reflog_iterator_begin(refs);
2038
2039 return do_for_each_ref_iterator(iter, fn, cb_data);
2040}
2041
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002042int for_each_reflog(each_ref_fn fn, void *cb_data)
2043{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002044 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 +07002045}
2046
2047int refs_for_each_reflog_ent_reverse(struct ref_store *refs,
2048 const char *refname,
2049 each_reflog_ent_fn fn,
2050 void *cb_data)
2051{
2052 return refs->be->for_each_reflog_ent_reverse(refs, refname,
2053 fn, cb_data);
2054}
2055
David Turnere3688bd2016-09-04 18:08:38 +02002056int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn,
2057 void *cb_data)
2058{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002059 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 +07002060 refname, fn, cb_data);
2061}
David Turnere3688bd2016-09-04 18:08:38 +02002062
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002063int refs_for_each_reflog_ent(struct ref_store *refs, const char *refname,
2064 each_reflog_ent_fn fn, void *cb_data)
2065{
2066 return refs->be->for_each_reflog_ent(refs, refname, fn, cb_data);
David Turnere3688bd2016-09-04 18:08:38 +02002067}
2068
2069int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn,
2070 void *cb_data)
2071{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002072 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 +07002073 fn, cb_data);
2074}
David Turnere3688bd2016-09-04 18:08:38 +02002075
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002076int refs_reflog_exists(struct ref_store *refs, const char *refname)
2077{
2078 return refs->be->reflog_exists(refs, refname);
David Turnere3688bd2016-09-04 18:08:38 +02002079}
2080
2081int reflog_exists(const char *refname)
2082{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002083 return refs_reflog_exists(get_main_ref_store(the_repository), refname);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002084}
David Turnere3688bd2016-09-04 18:08:38 +02002085
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002086int refs_create_reflog(struct ref_store *refs, const char *refname,
2087 int force_create, struct strbuf *err)
2088{
2089 return refs->be->create_reflog(refs, refname, force_create, err);
David Turnere3688bd2016-09-04 18:08:38 +02002090}
2091
2092int safe_create_reflog(const char *refname, int force_create,
2093 struct strbuf *err)
2094{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002095 return refs_create_reflog(get_main_ref_store(the_repository), refname,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002096 force_create, err);
2097}
David Turnere3688bd2016-09-04 18:08:38 +02002098
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002099int refs_delete_reflog(struct ref_store *refs, const char *refname)
2100{
2101 return refs->be->delete_reflog(refs, refname);
David Turnere3688bd2016-09-04 18:08:38 +02002102}
2103
2104int delete_reflog(const char *refname)
2105{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002106 return refs_delete_reflog(get_main_ref_store(the_repository), refname);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002107}
David Turnere3688bd2016-09-04 18:08:38 +02002108
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002109int refs_reflog_expire(struct ref_store *refs,
brian m. carlson0155f712017-10-15 22:07:04 +00002110 const char *refname, const struct object_id *oid,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002111 unsigned int flags,
2112 reflog_expiry_prepare_fn prepare_fn,
2113 reflog_expiry_should_prune_fn should_prune_fn,
2114 reflog_expiry_cleanup_fn cleanup_fn,
2115 void *policy_cb_data)
2116{
brian m. carlson0155f712017-10-15 22:07:04 +00002117 return refs->be->reflog_expire(refs, refname, oid, flags,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002118 prepare_fn, should_prune_fn,
2119 cleanup_fn, policy_cb_data);
David Turnere3688bd2016-09-04 18:08:38 +02002120}
2121
brian m. carlson0155f712017-10-15 22:07:04 +00002122int reflog_expire(const char *refname, const struct object_id *oid,
David Turnere3688bd2016-09-04 18:08:38 +02002123 unsigned int flags,
2124 reflog_expiry_prepare_fn prepare_fn,
2125 reflog_expiry_should_prune_fn should_prune_fn,
2126 reflog_expiry_cleanup_fn cleanup_fn,
2127 void *policy_cb_data)
2128{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002129 return refs_reflog_expire(get_main_ref_store(the_repository),
brian m. carlson0155f712017-10-15 22:07:04 +00002130 refname, oid, flags,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002131 prepare_fn, should_prune_fn,
2132 cleanup_fn, policy_cb_data);
David Turnere3688bd2016-09-04 18:08:38 +02002133}
David Turnerfc681462016-09-04 18:08:39 +02002134
2135int initial_ref_transaction_commit(struct ref_transaction *transaction,
2136 struct strbuf *err)
2137{
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07002138 struct ref_store *refs = transaction->ref_store;
David Turnerfc681462016-09-04 18:08:39 +02002139
2140 return refs->be->initial_transaction_commit(refs, transaction, err);
2141}
David Turnera27dcf82016-09-04 18:08:40 +02002142
Michael Haggerty64da4192017-05-22 16:17:38 +02002143int refs_delete_refs(struct ref_store *refs, const char *msg,
2144 struct string_list *refnames, unsigned int flags)
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002145{
Michael Haggerty64da4192017-05-22 16:17:38 +02002146 return refs->be->delete_refs(refs, msg, refnames, flags);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002147}
2148
Michael Haggerty64da4192017-05-22 16:17:38 +02002149int delete_refs(const char *msg, struct string_list *refnames,
2150 unsigned int flags)
David Turnera27dcf82016-09-04 18:08:40 +02002151{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002152 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 +07002153}
David Turnera27dcf82016-09-04 18:08:40 +02002154
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002155int refs_rename_ref(struct ref_store *refs, const char *oldref,
2156 const char *newref, const char *logmsg)
2157{
2158 return refs->be->rename_ref(refs, oldref, newref, logmsg);
David Turnera27dcf82016-09-04 18:08:40 +02002159}
David Turner9b6b40d2016-09-04 18:08:42 +02002160
2161int rename_ref(const char *oldref, const char *newref, const char *logmsg)
2162{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002163 return refs_rename_ref(get_main_ref_store(the_repository), oldref, newref, logmsg);
David Turner9b6b40d2016-09-04 18:08:42 +02002164}
Sahil Dua52d59cc2017-06-18 23:19:16 +02002165
2166int refs_copy_existing_ref(struct ref_store *refs, const char *oldref,
2167 const char *newref, const char *logmsg)
2168{
2169 return refs->be->copy_ref(refs, oldref, newref, logmsg);
2170}
2171
2172int copy_existing_ref(const char *oldref, const char *newref, const char *logmsg)
2173{
Stefan Beller23a3f0c2018-04-11 17:21:09 -07002174 return refs_copy_existing_ref(get_main_ref_store(the_repository), oldref, newref, logmsg);
Sahil Dua52d59cc2017-06-18 23:19:16 +02002175}