blob: 8b7a77fe5eedb08c0b034b1cf3bb4ef40efa9834 [file] [log] [blame]
Michael Haggerty7bd9bcf2015-11-09 14:34:01 +01001/*
2 * The backend-independent part of the reference module.
3 */
4
Daniel Barkalow95fc7512005-06-06 16:31:29 -04005#include "cache.h"
Brandon Williamsb2141fc2017-06-14 11:07:36 -07006#include "config.h"
Michael Haggerty7d4558c2017-02-10 12:16:15 +01007#include "hashmap.h"
Michael Haggerty697cc8e2014-10-01 12:28:42 +02008#include "lockfile.h"
Michael Haggertyb05855b2017-04-16 08:41:26 +02009#include "iterator.h"
Junio C Hamano85023572006-12-19 14:34:12 -080010#include "refs.h"
Michael Haggerty4cb77002015-11-10 12:42:36 +010011#include "refs/refs-internal.h"
Junio C Hamanocf0adba2006-11-19 13:22:44 -080012#include "object.h"
13#include "tag.h"
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +070014#include "submodule.h"
Nguyễn Thái Ngọc Duy17eff962017-04-24 17:01:22 +070015#include "worktree.h"
Stefan Beller3581d792014-12-12 09:57:02 +010016
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020017/*
Ronnie Sahlberg3dce4442016-09-04 18:08:10 +020018 * List of all available backends
19 */
20static struct ref_storage_be *refs_backends = &refs_be_files;
21
22static struct ref_storage_be *find_ref_storage_backend(const char *name)
23{
24 struct ref_storage_be *be;
25 for (be = refs_backends; be; be = be->next)
26 if (!strcmp(be->name, name))
27 return be;
28 return NULL;
29}
30
31int ref_storage_backend_exists(const char *name)
32{
33 return find_ref_storage_backend(name) != NULL;
34}
35
36/*
David Turnerdde8a902014-06-03 23:38:10 -040037 * How to handle various characters in refnames:
38 * 0: An acceptable character for refs
Junio C Hamano5e650222014-07-28 10:41:53 -070039 * 1: End-of-component
40 * 2: ., look for a preceding . to reject .. in refs
41 * 3: {, look for a preceding @ to reject @{ in refs
Jacob Keller53a85552015-07-22 14:05:32 -070042 * 4: A bad character: ASCII control characters, and
Jacob Kellercd377f42015-07-22 14:05:33 -070043 * ":", "?", "[", "\", "^", "~", SP, or TAB
44 * 5: *, reject unless REFNAME_REFSPEC_PATTERN is set
David Turnerdde8a902014-06-03 23:38:10 -040045 */
46static unsigned char refname_disposition[256] = {
Junio C Hamano5e650222014-07-28 10:41:53 -070047 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
48 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
Jacob Kellercd377f42015-07-22 14:05:33 -070049 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 1,
Junio C Hamano5e650222014-07-28 10:41:53 -070050 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4,
David Turnerdde8a902014-06-03 23:38:10 -040051 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Junio C Hamano5e650222014-07-28 10:41:53 -070052 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 0,
53 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4
David Turnerdde8a902014-06-03 23:38:10 -040055};
56
57/*
58 * Try to read one refname component from the front of refname.
59 * Return the length of the component found, or -1 if the component is
60 * not legal. It is legal if it is something reasonable to have under
61 * ".git/refs/"; We do not like it if:
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020062 *
63 * - any path component of it begins with ".", or
64 * - it has double dots "..", or
Jacob Keller53a85552015-07-22 14:05:32 -070065 * - it has ASCII control characters, or
Jacob Kellercd377f42015-07-22 14:05:33 -070066 * - it has ":", "?", "[", "\", "^", "~", SP, or TAB anywhere, or
67 * - it has "*" anywhere unless REFNAME_REFSPEC_PATTERN is set, or
Jacob Keller53a85552015-07-22 14:05:32 -070068 * - it ends with a "/", or
69 * - it ends with ".lock", or
70 * - it contains a "@{" portion
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020071 */
Jacob Kellercd377f42015-07-22 14:05:33 -070072static int check_refname_component(const char *refname, int *flags)
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020073{
74 const char *cp;
75 char last = '\0';
76
77 for (cp = refname; ; cp++) {
David Turnerdde8a902014-06-03 23:38:10 -040078 int ch = *cp & 255;
79 unsigned char disp = refname_disposition[ch];
80 switch (disp) {
Junio C Hamano5e650222014-07-28 10:41:53 -070081 case 1:
David Turnerdde8a902014-06-03 23:38:10 -040082 goto out;
Junio C Hamano5e650222014-07-28 10:41:53 -070083 case 2:
David Turnerdde8a902014-06-03 23:38:10 -040084 if (last == '.')
85 return -1; /* Refname contains "..". */
Michael Haggertybc5fd6d2012-04-10 07:30:13 +020086 break;
Junio C Hamano5e650222014-07-28 10:41:53 -070087 case 3:
David Turnerdde8a902014-06-03 23:38:10 -040088 if (last == '@')
89 return -1; /* Refname contains "@{". */
90 break;
Junio C Hamano5e650222014-07-28 10:41:53 -070091 case 4:
David Turnerdde8a902014-06-03 23:38:10 -040092 return -1;
Jacob Kellercd377f42015-07-22 14:05:33 -070093 case 5:
94 if (!(*flags & REFNAME_REFSPEC_PATTERN))
95 return -1; /* refspec can't be a pattern */
96
97 /*
98 * Unset the pattern flag so that we only accept
99 * a single asterisk for one side of refspec.
100 */
101 *flags &= ~ REFNAME_REFSPEC_PATTERN;
102 break;
David Turnerdde8a902014-06-03 23:38:10 -0400103 }
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200104 last = ch;
105 }
David Turnerdde8a902014-06-03 23:38:10 -0400106out:
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200107 if (cp == refname)
Michael Haggertydac529e2012-04-10 07:30:22 +0200108 return 0; /* Component has zero length. */
Jonathan Niederf3cc52d2014-09-26 12:22:22 -0700109 if (refname[0] == '.')
110 return -1; /* Component starts with '.'. */
Michael Haggerty7108ad22014-10-01 12:28:15 +0200111 if (cp - refname >= LOCK_SUFFIX_LEN &&
112 !memcmp(cp - LOCK_SUFFIX_LEN, LOCK_SUFFIX, LOCK_SUFFIX_LEN))
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200113 return -1; /* Refname ends with ".lock". */
114 return cp - refname;
115}
116
Junio C Hamano5e650222014-07-28 10:41:53 -0700117int check_refname_format(const char *refname, int flags)
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200118{
119 int component_len, component_count = 0;
120
Felipe Contreras9ba89f42013-09-02 01:34:30 -0500121 if (!strcmp(refname, "@"))
122 /* Refname is a single character '@'. */
123 return -1;
124
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200125 while (1) {
126 /* We are at the start of a path component. */
Jacob Kellercd377f42015-07-22 14:05:33 -0700127 component_len = check_refname_component(refname, &flags);
128 if (component_len <= 0)
129 return -1;
130
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200131 component_count++;
132 if (refname[component_len] == '\0')
133 break;
134 /* Skip to next component. */
135 refname += component_len + 1;
136 }
137
138 if (refname[component_len - 1] == '.')
139 return -1; /* Refname ends with '.'. */
140 if (!(flags & REFNAME_ALLOW_ONELEVEL) && component_count < 2)
141 return -1; /* Refname has only one component. */
142 return 0;
143}
144
Michael Haggerty4cb77002015-11-10 12:42:36 +0100145int refname_is_safe(const char *refname)
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700146{
Michael Haggerty39950fe2016-04-27 12:39:11 +0200147 const char *rest;
148
149 if (skip_prefix(refname, "refs/", &rest)) {
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700150 char *buf;
151 int result;
Michael Haggertye40f3552016-04-27 12:40:39 +0200152 size_t restlen = strlen(rest);
153
154 /* rest must not be empty, or start or end with "/" */
155 if (!restlen || *rest == '/' || rest[restlen - 1] == '/')
156 return 0;
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700157
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700158 /*
159 * Does the refname try to escape refs/?
160 * For example: refs/foo/../bar is safe but refs/foo/../../bar
161 * is not.
162 */
Michael Haggertye40f3552016-04-27 12:40:39 +0200163 buf = xmallocz(restlen);
164 result = !normalize_path_copy(buf, rest) && !strcmp(buf, rest);
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700165 free(buf);
166 return result;
167 }
Michael Haggerty35db25c2016-04-27 12:42:27 +0200168
169 do {
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700170 if (!isupper(*refname) && *refname != '_')
171 return 0;
172 refname++;
Michael Haggerty35db25c2016-04-27 12:42:27 +0200173 } while (*refname);
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -0700174 return 1;
175}
176
Michael Haggerty67be7c52017-06-23 09:01:37 +0200177/*
178 * Return true if refname, which has the specified oid and flags, can
179 * be resolved to an object in the database. If the referred-to object
180 * does not exist, emit a warning and return false.
181 */
182int ref_resolves_to_object(const char *refname,
183 const struct object_id *oid,
184 unsigned int flags)
185{
186 if (flags & REF_ISBROKEN)
187 return 0;
188 if (!has_sha1_file(oid->hash)) {
189 error("%s does not point to a valid object!", refname);
190 return 0;
191 }
192 return 1;
193}
194
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700195char *refs_resolve_refdup(struct ref_store *refs,
196 const char *refname, int resolve_flags,
brian m. carlson0f2dc722017-10-15 22:06:55 +0000197 struct object_id *oid, int *flags)
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700198{
199 const char *result;
200
201 result = refs_resolve_ref_unsafe(refs, refname, resolve_flags,
brian m. carlson49e61472017-10-15 22:07:09 +0000202 oid, flags);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700203 return xstrdup_or_null(result);
204}
205
Michael Haggertyfb58c8d2015-06-22 16:03:05 +0200206char *resolve_refdup(const char *refname, int resolve_flags,
brian m. carlson0f2dc722017-10-15 22:06:55 +0000207 struct object_id *oid, int *flags)
Nguyễn Thái Ngọc Duy96ec7b12011-12-13 21:17:48 +0700208{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700209 return refs_resolve_refdup(get_main_ref_store(),
210 refname, resolve_flags,
brian m. carlson0f2dc722017-10-15 22:06:55 +0000211 oid, flags);
Nguyễn Thái Ngọc Duy96ec7b12011-12-13 21:17:48 +0700212}
213
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200214/* The argument to filter_refs */
215struct ref_filter {
216 const char *pattern;
217 each_ref_fn *fn;
218 void *cb_data;
219};
220
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700221int refs_read_ref_full(struct ref_store *refs, const char *refname,
brian m. carlson34c290a2017-10-15 22:06:56 +0000222 int resolve_flags, struct object_id *oid, int *flags)
Linus Torvalds8a65ff72005-07-02 20:23:36 -0700223{
brian m. carlson49e61472017-10-15 22:07:09 +0000224 if (refs_resolve_ref_unsafe(refs, refname, resolve_flags, oid, flags))
Junio C Hamanoa876ed82005-09-30 14:08:25 -0700225 return 0;
226 return -1;
Linus Torvalds8a65ff72005-07-02 20:23:36 -0700227}
228
brian m. carlson34c290a2017-10-15 22:06:56 +0000229int 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 +0700230{
231 return refs_read_ref_full(get_main_ref_store(), refname,
brian m. carlson34c290a2017-10-15 22:06:56 +0000232 resolve_flags, oid, flags);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700233}
234
brian m. carlson34c290a2017-10-15 22:06:56 +0000235int read_ref(const char *refname, struct object_id *oid)
Nguyễn Thái Ngọc Duyc6893322011-11-13 17:22:14 +0700236{
brian m. carlson34c290a2017-10-15 22:06:56 +0000237 return read_ref_full(refname, RESOLVE_REF_READING, oid, NULL);
Nguyễn Thái Ngọc Duyc6893322011-11-13 17:22:14 +0700238}
239
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200240int ref_exists(const char *refname)
Junio C Hamanoef06b912006-11-18 22:13:33 -0800241{
René Scharfe744c0402017-09-23 11:45:04 +0200242 return !!resolve_ref_unsafe(refname, RESOLVE_REF_READING, NULL, NULL);
Junio C Hamanoef06b912006-11-18 22:13:33 -0800243}
244
Rafael Ascensão65516f52017-11-21 21:33:41 +0000245static int match_ref_pattern(const char *refname,
246 const struct string_list_item *item)
247{
248 int matched = 0;
249 if (item->util == NULL) {
250 if (!wildmatch(item->string, refname, 0))
251 matched = 1;
252 } else {
253 const char *rest;
254 if (skip_prefix(refname, item->string, &rest) &&
255 (!*rest || *rest == '/'))
256 matched = 1;
257 }
258 return matched;
259}
260
261int ref_filter_match(const char *refname,
262 const struct string_list *include_patterns,
263 const struct string_list *exclude_patterns)
264{
265 struct string_list_item *item;
266
267 if (exclude_patterns && exclude_patterns->nr) {
268 for_each_string_list_item(item, exclude_patterns) {
269 if (match_ref_pattern(refname, item))
270 return 0;
271 }
272 }
273
274 if (include_patterns && include_patterns->nr) {
275 int found = 0;
276 for_each_string_list_item(item, include_patterns) {
277 if (match_ref_pattern(refname, item)) {
278 found = 1;
279 break;
280 }
281 }
282
283 if (!found)
284 return 0;
285 }
286 return 1;
287}
288
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000289static int filter_refs(const char *refname, const struct object_id *oid,
Michael Haggerty4e675d12015-05-25 18:39:21 +0000290 int flags, void *data)
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200291{
292 struct ref_filter *filter = (struct ref_filter *)data;
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000293
Ævar Arnfjörð Bjarmason55d34262017-06-22 21:38:08 +0000294 if (wildmatch(filter->pattern, refname, 0))
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200295 return 0;
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000296 return filter->fn(refname, oid, flags, filter->cb_data);
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200297}
298
brian m. carlsonac2ed0d2017-10-15 22:07:10 +0000299enum peel_status peel_object(const struct object_id *name, struct object_id *oid)
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200300{
brian m. carlsonac2ed0d2017-10-15 22:07:10 +0000301 struct object *o = lookup_unknown_object(name->hash);
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200302
303 if (o->type == OBJ_NONE) {
brian m. carlsonabef9022018-03-12 02:27:46 +0000304 int type = oid_object_info(name, NULL);
Jeff King8ff226a2014-07-13 02:42:03 -0400305 if (type < 0 || !object_as_type(o, type, 0))
Michael Haggerty68cf8702013-04-22 21:52:20 +0200306 return PEEL_INVALID;
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200307 }
308
309 if (o->type != OBJ_TAG)
Michael Haggerty68cf8702013-04-22 21:52:20 +0200310 return PEEL_NON_TAG;
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200311
312 o = deref_tag_noverify(o);
313 if (!o)
Michael Haggerty68cf8702013-04-22 21:52:20 +0200314 return PEEL_INVALID;
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200315
brian m. carlsonac2ed0d2017-10-15 22:07:10 +0000316 oidcpy(oid, &o->oid);
Michael Haggerty68cf8702013-04-22 21:52:20 +0200317 return PEEL_PEELED;
Michael Haggertycb2ae1c2013-04-22 21:52:19 +0200318}
319
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200320struct warn_if_dangling_data {
321 FILE *fp;
322 const char *refname;
Jens Lindströme6bea662014-05-23 12:30:25 +0200323 const struct string_list *refnames;
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200324 const char *msg_fmt;
325};
326
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000327static int warn_if_dangling_symref(const char *refname, const struct object_id *oid,
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200328 int flags, void *cb_data)
329{
330 struct warn_if_dangling_data *d = cb_data;
331 const char *resolves_to;
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200332
333 if (!(flags & REF_ISSYMREF))
334 return 0;
335
René Scharfe744c0402017-09-23 11:45:04 +0200336 resolves_to = resolve_ref_unsafe(refname, 0, NULL, NULL);
Jens Lindströme6bea662014-05-23 12:30:25 +0200337 if (!resolves_to
338 || (d->refname
339 ? strcmp(resolves_to, d->refname)
340 : !string_list_has_string(d->refnames, resolves_to))) {
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200341 return 0;
Jens Lindströme6bea662014-05-23 12:30:25 +0200342 }
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200343
344 fprintf(d->fp, d->msg_fmt, refname);
Junio C Hamano1be65ed2012-05-02 13:51:35 -0700345 fputc('\n', d->fp);
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200346 return 0;
347}
348
349void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
350{
351 struct warn_if_dangling_data data;
352
353 data.fp = fp;
354 data.refname = refname;
Jens Lindströme6bea662014-05-23 12:30:25 +0200355 data.refnames = NULL;
356 data.msg_fmt = msg_fmt;
357 for_each_rawref(warn_if_dangling_symref, &data);
358}
359
360void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list *refnames)
361{
362 struct warn_if_dangling_data data;
363
364 data.fp = fp;
365 data.refname = NULL;
366 data.refnames = refnames;
Michael Haggertybc5fd6d2012-04-10 07:30:13 +0200367 data.msg_fmt = msg_fmt;
368 for_each_rawref(warn_if_dangling_symref, &data);
369}
370
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700371int refs_for_each_tag_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
372{
373 return refs_for_each_ref_in(refs, "refs/tags/", fn, cb_data);
374}
375
Junio C Hamanocb5d7092006-09-20 21:47:42 -0700376int for_each_tag_ref(each_ref_fn fn, void *cb_data)
Seana62be772006-05-13 21:43:00 -0400377{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700378 return refs_for_each_tag_ref(get_main_ref_store(), fn, cb_data);
Seana62be772006-05-13 21:43:00 -0400379}
380
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700381int refs_for_each_branch_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
382{
383 return refs_for_each_ref_in(refs, "refs/heads/", fn, cb_data);
Heiko Voigt9ef6aeb2010-07-07 15:39:12 +0200384}
385
Junio C Hamanocb5d7092006-09-20 21:47:42 -0700386int for_each_branch_ref(each_ref_fn fn, void *cb_data)
Seana62be772006-05-13 21:43:00 -0400387{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700388 return refs_for_each_branch_ref(get_main_ref_store(), fn, cb_data);
Seana62be772006-05-13 21:43:00 -0400389}
390
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700391int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
392{
393 return refs_for_each_ref_in(refs, "refs/remotes/", fn, cb_data);
Heiko Voigt9ef6aeb2010-07-07 15:39:12 +0200394}
395
Junio C Hamanocb5d7092006-09-20 21:47:42 -0700396int for_each_remote_ref(each_ref_fn fn, void *cb_data)
Seana62be772006-05-13 21:43:00 -0400397{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +0700398 return refs_for_each_remote_ref(get_main_ref_store(), fn, cb_data);
Junio C Hamanof8948e22009-02-08 23:27:10 -0800399}
400
Josh Tripletta1bea2c2011-07-05 10:54:44 -0700401int head_ref_namespaced(each_ref_fn fn, void *cb_data)
402{
403 struct strbuf buf = STRBUF_INIT;
404 int ret = 0;
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000405 struct object_id oid;
Josh Tripletta1bea2c2011-07-05 10:54:44 -0700406 int flag;
407
408 strbuf_addf(&buf, "%sHEAD", get_git_namespace());
brian m. carlson34c290a2017-10-15 22:06:56 +0000409 if (!read_ref_full(buf.buf, RESOLVE_REF_READING, &oid, &flag))
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000410 ret = fn(buf.buf, &oid, flag, cb_data);
Josh Tripletta1bea2c2011-07-05 10:54:44 -0700411 strbuf_release(&buf);
412
413 return ret;
414}
415
Rafael Ascensão65516f52017-11-21 21:33:41 +0000416void normalize_glob_ref(struct string_list_item *item, const char *prefix,
417 const char *pattern)
418{
419 struct strbuf normalized_pattern = STRBUF_INIT;
420
421 if (*pattern == '/')
422 BUG("pattern must not start with '/'");
423
424 if (prefix) {
425 strbuf_addstr(&normalized_pattern, prefix);
426 }
427 else if (!starts_with(pattern, "refs/"))
428 strbuf_addstr(&normalized_pattern, "refs/");
429 strbuf_addstr(&normalized_pattern, pattern);
430 strbuf_strip_suffix(&normalized_pattern, "/");
431
432 item->string = strbuf_detach(&normalized_pattern, NULL);
433 item->util = has_glob_specials(pattern) ? NULL : item->string;
434 strbuf_release(&normalized_pattern);
435}
436
Ilari Liusvaarab09fe972010-01-20 11:48:26 +0200437int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
438 const char *prefix, void *cb_data)
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200439{
440 struct strbuf real_pattern = STRBUF_INIT;
441 struct ref_filter filter;
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200442 int ret;
443
Christian Couder59556542013-11-30 21:55:40 +0100444 if (!prefix && !starts_with(pattern, "refs/"))
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200445 strbuf_addstr(&real_pattern, "refs/");
Ilari Liusvaarab09fe972010-01-20 11:48:26 +0200446 else if (prefix)
447 strbuf_addstr(&real_pattern, prefix);
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200448 strbuf_addstr(&real_pattern, pattern);
449
Thomas Rast894a9d32010-03-12 18:04:26 +0100450 if (!has_glob_specials(pattern)) {
Junio C Hamano9517e6b2010-02-03 21:23:18 -0800451 /* Append implied '/' '*' if not present. */
Jeff King00b6c172015-09-24 17:08:35 -0400452 strbuf_complete(&real_pattern, '/');
Ilari Liusvaarad08bae72010-01-20 11:48:25 +0200453 /* No need to check for '*', there is none. */
454 strbuf_addch(&real_pattern, '*');
455 }
456
457 filter.pattern = real_pattern.buf;
458 filter.fn = fn;
459 filter.cb_data = cb_data;
460 ret = for_each_ref(filter_refs, &filter);
461
462 strbuf_release(&real_pattern);
463 return ret;
464}
465
Ilari Liusvaarab09fe972010-01-20 11:48:26 +0200466int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
467{
468 return for_each_glob_ref_in(fn, pattern, NULL, cb_data);
469}
470
Felipe Contreras4577e482009-05-14 00:22:04 +0300471const char *prettify_refname(const char *name)
Daniel Barkalowa9c37a72009-03-08 21:06:05 -0400472{
SZEDER Gábor3e5b36c2017-03-23 16:50:12 +0100473 if (skip_prefix(name, "refs/heads/", &name) ||
474 skip_prefix(name, "refs/tags/", &name) ||
475 skip_prefix(name, "refs/remotes/", &name))
476 ; /* nothing */
477 return name;
Daniel Barkalowa9c37a72009-03-08 21:06:05 -0400478}
479
Michael Haggerty54457fe2014-01-14 04:16:07 +0100480static const char *ref_rev_parse_rules[] = {
Steffen Prohaska79803322007-11-11 15:01:46 +0100481 "%.*s",
482 "refs/%.*s",
483 "refs/tags/%.*s",
484 "refs/heads/%.*s",
485 "refs/remotes/%.*s",
486 "refs/remotes/%.*s/HEAD",
487 NULL
488};
489
Michael Haggerty54457fe2014-01-14 04:16:07 +0100490int refname_match(const char *abbrev_name, const char *full_name)
Steffen Prohaska79803322007-11-11 15:01:46 +0100491{
492 const char **p;
493 const int abbrev_name_len = strlen(abbrev_name);
494
Michael Haggerty54457fe2014-01-14 04:16:07 +0100495 for (p = ref_rev_parse_rules; *p; p++) {
Steffen Prohaska79803322007-11-11 15:01:46 +0100496 if (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name))) {
497 return 1;
498 }
499 }
500
501 return 0;
502}
503
Michael Haggerty19b68b12011-12-12 06:38:12 +0100504/*
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700505 * *string and *len will only be substituted, and *string returned (for
506 * later free()ing) if the string passed in is a magic short-hand form
507 * to name a branch.
508 */
509static char *substitute_branch_name(const char **string, int *len)
510{
511 struct strbuf buf = STRBUF_INIT;
Jeff King0e9f62d2017-03-02 03:23:01 -0500512 int ret = interpret_branch_name(*string, *len, &buf, 0);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700513
514 if (ret == *len) {
515 size_t size;
516 *string = strbuf_detach(&buf, &size);
517 *len = size;
518 return (char *)*string;
519 }
520
521 return NULL;
522}
523
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000524int dwim_ref(const char *str, int len, struct object_id *oid, char **ref)
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700525{
526 char *last_branch = substitute_branch_name(&str, &len);
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000527 int refs_found = expand_ref(str, len, oid, ref);
Nguyễn Thái Ngọc Duy41da7112016-06-12 17:54:02 +0700528 free(last_branch);
529 return refs_found;
530}
531
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000532int 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 +0700533{
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700534 const char **p, *r;
535 int refs_found = 0;
Jeff King6cd4a892017-03-28 15:46:33 -0400536 struct strbuf fullref = STRBUF_INIT;
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700537
538 *ref = NULL;
539 for (p = ref_rev_parse_rules; *p; p++) {
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000540 struct object_id oid_from_ref;
541 struct object_id *this_result;
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700542 int flag;
543
brian m. carlsoncca5fa62017-10-15 22:06:57 +0000544 this_result = refs_found ? &oid_from_ref : oid;
Jeff King6cd4a892017-03-28 15:46:33 -0400545 strbuf_reset(&fullref);
546 strbuf_addf(&fullref, *p, len, str);
547 r = resolve_ref_unsafe(fullref.buf, RESOLVE_REF_READING,
brian m. carlson49e61472017-10-15 22:07:09 +0000548 this_result, &flag);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700549 if (r) {
550 if (!refs_found++)
551 *ref = xstrdup(r);
552 if (!warn_ambiguous_refs)
553 break;
Jeff King6cd4a892017-03-28 15:46:33 -0400554 } else if ((flag & REF_ISSYMREF) && strcmp(fullref.buf, "HEAD")) {
555 warning("ignoring dangling symref %s.", fullref.buf);
556 } else if ((flag & REF_ISBROKEN) && strchr(fullref.buf, '/')) {
557 warning("ignoring broken ref %s.", fullref.buf);
Junio C Hamano55956352011-10-19 13:55:49 -0700558 }
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700559 }
Jeff King6cd4a892017-03-28 15:46:33 -0400560 strbuf_release(&fullref);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700561 return refs_found;
562}
563
brian m. carlson334dc522017-10-15 22:06:59 +0000564int dwim_log(const char *str, int len, struct object_id *oid, char **log)
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700565{
566 char *last_branch = substitute_branch_name(&str, &len);
567 const char **p;
568 int logs_found = 0;
Jeff King6cd4a892017-03-28 15:46:33 -0400569 struct strbuf path = STRBUF_INIT;
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700570
571 *log = NULL;
572 for (p = ref_rev_parse_rules; *p; p++) {
brian m. carlson334dc522017-10-15 22:06:59 +0000573 struct object_id hash;
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700574 const char *ref, *it;
575
Jeff King6cd4a892017-03-28 15:46:33 -0400576 strbuf_reset(&path);
577 strbuf_addf(&path, *p, len, str);
578 ref = resolve_ref_unsafe(path.buf, RESOLVE_REF_READING,
brian m. carlson49e61472017-10-15 22:07:09 +0000579 &hash, NULL);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700580 if (!ref)
581 continue;
Jeff King6cd4a892017-03-28 15:46:33 -0400582 if (reflog_exists(path.buf))
583 it = path.buf;
584 else if (strcmp(ref, path.buf) && reflog_exists(ref))
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700585 it = ref;
586 else
587 continue;
588 if (!logs_found++) {
589 *log = xstrdup(it);
brian m. carlson334dc522017-10-15 22:06:59 +0000590 oidcpy(oid, &hash);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700591 }
592 if (!warn_ambiguous_refs)
593 break;
594 }
Jeff King6cd4a892017-03-28 15:46:33 -0400595 strbuf_release(&path);
Junio C Hamanoff74f7f2011-10-12 10:35:38 -0700596 free(last_branch);
597 return logs_found;
598}
599
David Turner266b1822015-07-31 02:06:18 -0400600static int is_per_worktree_ref(const char *refname)
601{
David Turnerce414b32015-08-31 22:13:11 -0400602 return !strcmp(refname, "HEAD") ||
603 starts_with(refname, "refs/bisect/");
David Turner266b1822015-07-31 02:06:18 -0400604}
605
606static int is_pseudoref_syntax(const char *refname)
607{
608 const char *c;
609
610 for (c = refname; *c; c++) {
611 if (!isupper(*c) && *c != '-' && *c != '_')
612 return 0;
613 }
614
615 return 1;
616}
617
618enum ref_type ref_type(const char *refname)
619{
620 if (is_per_worktree_ref(refname))
621 return REF_TYPE_PER_WORKTREE;
622 if (is_pseudoref_syntax(refname))
623 return REF_TYPE_PSEUDOREF;
624 return REF_TYPE_NORMAL;
625}
626
Michael Haggerty4ff0f012017-08-21 13:51:34 +0200627long get_files_ref_lock_timeout_ms(void)
628{
629 static int configured = 0;
630
631 /* The default timeout is 100 ms: */
632 static int timeout_ms = 100;
633
634 if (!configured) {
635 git_config_get_int("core.filesreflocktimeout", &timeout_ms);
636 configured = 1;
637 }
638
639 return timeout_ms;
640}
641
brian m. carlsonae077772017-10-15 22:06:51 +0000642static int write_pseudoref(const char *pseudoref, const struct object_id *oid,
643 const struct object_id *old_oid, struct strbuf *err)
David Turner74ec19d2015-07-31 02:06:19 -0400644{
645 const char *filename;
646 int fd;
647 static struct lock_file lock;
648 struct strbuf buf = STRBUF_INIT;
649 int ret = -1;
650
brian m. carlson6ee18212017-10-15 22:06:52 +0000651 if (!oid)
652 return 0;
653
brian m. carlsonae077772017-10-15 22:06:51 +0000654 strbuf_addf(&buf, "%s\n", oid_to_hex(oid));
David Turner74ec19d2015-07-31 02:06:19 -0400655
656 filename = git_path("%s", pseudoref);
Michael Haggerty4ff0f012017-08-21 13:51:34 +0200657 fd = hold_lock_file_for_update_timeout(&lock, filename,
658 LOCK_DIE_ON_ERROR,
659 get_files_ref_lock_timeout_ms());
David Turner74ec19d2015-07-31 02:06:19 -0400660 if (fd < 0) {
Michael Haggerty0568c8e2016-04-27 15:21:36 +0200661 strbuf_addf(err, "could not open '%s' for writing: %s",
David Turner74ec19d2015-07-31 02:06:19 -0400662 filename, strerror(errno));
Rene Scharfeaeb014f2017-08-30 19:58:12 +0200663 goto done;
David Turner74ec19d2015-07-31 02:06:19 -0400664 }
665
brian m. carlsonae077772017-10-15 22:06:51 +0000666 if (old_oid) {
667 struct object_id actual_old_oid;
David Turner2c3aed12015-07-15 18:05:28 -0400668
brian m. carlson34c290a2017-10-15 22:06:56 +0000669 if (read_ref(pseudoref, &actual_old_oid))
David Turner2c3aed12015-07-15 18:05:28 -0400670 die("could not read ref '%s'", pseudoref);
brian m. carlsonae077772017-10-15 22:06:51 +0000671 if (oidcmp(&actual_old_oid, old_oid)) {
Michael Haggerty0568c8e2016-04-27 15:21:36 +0200672 strbuf_addf(err, "unexpected sha1 when writing '%s'", pseudoref);
David Turner74ec19d2015-07-31 02:06:19 -0400673 rollback_lock_file(&lock);
674 goto done;
675 }
676 }
677
Jeff King06f46f22017-09-13 13:16:03 -0400678 if (write_in_full(fd, buf.buf, buf.len) < 0) {
Michael Haggerty0568c8e2016-04-27 15:21:36 +0200679 strbuf_addf(err, "could not write to '%s'", filename);
David Turner74ec19d2015-07-31 02:06:19 -0400680 rollback_lock_file(&lock);
681 goto done;
682 }
683
684 commit_lock_file(&lock);
685 ret = 0;
686done:
687 strbuf_release(&buf);
688 return ret;
689}
690
brian m. carlson2616a5e2017-10-15 22:06:50 +0000691static int delete_pseudoref(const char *pseudoref, const struct object_id *old_oid)
David Turner74ec19d2015-07-31 02:06:19 -0400692{
693 static struct lock_file lock;
694 const char *filename;
695
696 filename = git_path("%s", pseudoref);
697
brian m. carlson2616a5e2017-10-15 22:06:50 +0000698 if (old_oid && !is_null_oid(old_oid)) {
David Turner74ec19d2015-07-31 02:06:19 -0400699 int fd;
brian m. carlson2616a5e2017-10-15 22:06:50 +0000700 struct object_id actual_old_oid;
David Turner74ec19d2015-07-31 02:06:19 -0400701
Michael Haggerty4ff0f012017-08-21 13:51:34 +0200702 fd = hold_lock_file_for_update_timeout(
703 &lock, filename, LOCK_DIE_ON_ERROR,
704 get_files_ref_lock_timeout_ms());
David Turner74ec19d2015-07-31 02:06:19 -0400705 if (fd < 0)
706 die_errno(_("Could not open '%s' for writing"), filename);
brian m. carlson34c290a2017-10-15 22:06:56 +0000707 if (read_ref(pseudoref, &actual_old_oid))
David Turner2c3aed12015-07-15 18:05:28 -0400708 die("could not read ref '%s'", pseudoref);
brian m. carlson2616a5e2017-10-15 22:06:50 +0000709 if (oidcmp(&actual_old_oid, old_oid)) {
David Turner74ec19d2015-07-31 02:06:19 -0400710 warning("Unexpected sha1 when deleting %s", pseudoref);
711 rollback_lock_file(&lock);
712 return -1;
713 }
714
715 unlink(filename);
716 rollback_lock_file(&lock);
717 } else {
718 unlink(filename);
719 }
720
721 return 0;
722}
723
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700724int refs_delete_ref(struct ref_store *refs, const char *msg,
725 const char *refname,
brian m. carlson2616a5e2017-10-15 22:06:50 +0000726 const struct object_id *old_oid,
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700727 unsigned int flags)
Junio C Hamanoc0277d12006-09-30 15:02:00 -0700728{
Ronnie Sahlberg7521cc42014-04-30 09:22:45 -0700729 struct ref_transaction *transaction;
730 struct strbuf err = STRBUF_INIT;
Junio C Hamanoc0277d12006-09-30 15:02:00 -0700731
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700732 if (ref_type(refname) == REF_TYPE_PSEUDOREF) {
733 assert(refs == get_main_ref_store());
brian m. carlson2616a5e2017-10-15 22:06:50 +0000734 return delete_pseudoref(refname, old_oid);
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700735 }
David Turner74ec19d2015-07-31 02:06:19 -0400736
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700737 transaction = ref_store_transaction_begin(refs, &err);
Ronnie Sahlberg7521cc42014-04-30 09:22:45 -0700738 if (!transaction ||
brian m. carlson89f3bbd2017-10-15 22:06:53 +0000739 ref_transaction_delete(transaction, refname, old_oid,
Kyle Meyer755b49a2017-02-20 20:10:32 -0500740 flags, msg, &err) ||
Ronnie Sahlbergdb7516a2014-04-30 12:22:42 -0700741 ref_transaction_commit(transaction, &err)) {
Ronnie Sahlberg7521cc42014-04-30 09:22:45 -0700742 error("%s", err.buf);
743 ref_transaction_free(transaction);
744 strbuf_release(&err);
Junio C Hamanoc0277d12006-09-30 15:02:00 -0700745 return 1;
Ronnie Sahlberg7521cc42014-04-30 09:22:45 -0700746 }
747 ref_transaction_free(transaction);
748 strbuf_release(&err);
749 return 0;
Shawn Pearce4bd18c42006-05-17 05:55:02 -0400750}
751
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700752int delete_ref(const char *msg, const char *refname,
brian m. carlson2616a5e2017-10-15 22:06:50 +0000753 const struct object_id *old_oid, unsigned int flags)
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700754{
755 return refs_delete_ref(get_main_ref_store(), msg, refname,
brian m. carlson2616a5e2017-10-15 22:06:50 +0000756 old_oid, flags);
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700757}
758
Michael Haggerty4cb77002015-11-10 12:42:36 +0100759int copy_reflog_msg(char *buf, const char *msg)
Junio C Hamano0ec29a42007-07-28 17:17:17 -0700760{
761 char *cp = buf;
762 char c;
763 int wasspace = 1;
764
765 *cp++ = '\t';
766 while ((c = *msg++)) {
767 if (wasspace && isspace(c))
768 continue;
769 wasspace = isspace(c);
770 if (wasspace)
771 c = ' ';
772 *cp++ = c;
773 }
774 while (buf < cp && isspace(cp[-1]))
775 cp--;
776 *cp++ = '\n';
777 return cp - buf;
778}
779
Michael Haggerty4cb77002015-11-10 12:42:36 +0100780int should_autocreate_reflog(const char *refname)
David Turner4e2bef52015-07-21 17:04:51 -0400781{
Cornelius Weig341fb282017-01-27 11:09:47 +0100782 switch (log_all_ref_updates) {
783 case LOG_REFS_ALWAYS:
784 return 1;
785 case LOG_REFS_NORMAL:
786 return starts_with(refname, "refs/heads/") ||
787 starts_with(refname, "refs/remotes/") ||
788 starts_with(refname, "refs/notes/") ||
789 !strcmp(refname, "HEAD");
790 default:
David Turner4e2bef52015-07-21 17:04:51 -0400791 return 0;
Cornelius Weig341fb282017-01-27 11:09:47 +0100792 }
David Turner4e2bef52015-07-21 17:04:51 -0400793}
794
Ronnie Sahlberge7e0f262014-07-15 16:02:38 -0700795int is_branch(const char *refname)
Linus Torvaldsc3b0dec2008-01-15 15:50:17 -0800796{
Christian Couder59556542013-11-30 21:55:40 +0100797 return !strcmp(refname, "HEAD") || starts_with(refname, "refs/heads/");
Linus Torvaldsc3b0dec2008-01-15 15:50:17 -0800798}
799
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700800struct read_ref_at_cb {
801 const char *refname;
Johannes Schindelindddbad72017-04-26 21:29:31 +0200802 timestamp_t at_time;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700803 int cnt;
804 int reccnt;
brian m. carlson8eb36d92017-10-15 22:07:03 +0000805 struct object_id *oid;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700806 int found_it;
807
brian m. carlson8eb36d92017-10-15 22:07:03 +0000808 struct object_id ooid;
809 struct object_id noid;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700810 int tz;
Johannes Schindelindddbad72017-04-26 21:29:31 +0200811 timestamp_t date;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700812 char **msg;
Johannes Schindelindddbad72017-04-26 21:29:31 +0200813 timestamp_t *cutoff_time;
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700814 int *cutoff_tz;
815 int *cutoff_cnt;
816};
817
brian m. carlson9461d272017-02-21 23:47:32 +0000818static int read_ref_at_ent(struct object_id *ooid, struct object_id *noid,
Johannes Schindelindddbad72017-04-26 21:29:31 +0200819 const char *email, timestamp_t timestamp, int tz,
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700820 const char *message, void *cb_data)
Junio C Hamano16d7cc92007-01-19 01:19:05 -0800821{
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700822 struct read_ref_at_cb *cb = cb_data;
823
824 cb->reccnt++;
825 cb->tz = tz;
826 cb->date = timestamp;
827
828 if (timestamp <= cb->at_time || cb->cnt == 0) {
829 if (cb->msg)
830 *cb->msg = xstrdup(message);
831 if (cb->cutoff_time)
832 *cb->cutoff_time = timestamp;
833 if (cb->cutoff_tz)
834 *cb->cutoff_tz = tz;
835 if (cb->cutoff_cnt)
836 *cb->cutoff_cnt = cb->reccnt - 1;
837 /*
Michael Haggerty78fb4572017-11-05 09:42:09 +0100838 * we have not yet updated cb->[n|o]oid so they still
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700839 * hold the values for the previous record.
840 */
brian m. carlson8eb36d92017-10-15 22:07:03 +0000841 if (!is_null_oid(&cb->ooid)) {
842 oidcpy(cb->oid, noid);
843 if (oidcmp(&cb->ooid, noid))
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700844 warning("Log for ref %s has gap after %s.",
Jeff Kinga5481a62015-06-25 12:55:02 -0400845 cb->refname, show_date(cb->date, cb->tz, DATE_MODE(RFC2822)));
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700846 }
847 else if (cb->date == cb->at_time)
brian m. carlson8eb36d92017-10-15 22:07:03 +0000848 oidcpy(cb->oid, noid);
849 else if (oidcmp(noid, cb->oid))
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700850 warning("Log for ref %s unexpectedly ended on %s.",
851 cb->refname, show_date(cb->date, cb->tz,
Jeff Kinga5481a62015-06-25 12:55:02 -0400852 DATE_MODE(RFC2822)));
brian m. carlson8eb36d92017-10-15 22:07:03 +0000853 oidcpy(&cb->ooid, ooid);
854 oidcpy(&cb->noid, noid);
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700855 cb->found_it = 1;
856 return 1;
857 }
brian m. carlson8eb36d92017-10-15 22:07:03 +0000858 oidcpy(&cb->ooid, ooid);
859 oidcpy(&cb->noid, noid);
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700860 if (cb->cnt > 0)
861 cb->cnt--;
862 return 0;
863}
864
brian m. carlson9461d272017-02-21 23:47:32 +0000865static int read_ref_at_ent_oldest(struct object_id *ooid, struct object_id *noid,
Johannes Schindelindddbad72017-04-26 21:29:31 +0200866 const char *email, timestamp_t timestamp,
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700867 int tz, const char *message, void *cb_data)
868{
869 struct read_ref_at_cb *cb = cb_data;
870
871 if (cb->msg)
872 *cb->msg = xstrdup(message);
873 if (cb->cutoff_time)
874 *cb->cutoff_time = timestamp;
875 if (cb->cutoff_tz)
876 *cb->cutoff_tz = tz;
877 if (cb->cutoff_cnt)
878 *cb->cutoff_cnt = cb->reccnt;
brian m. carlson8eb36d92017-10-15 22:07:03 +0000879 oidcpy(cb->oid, ooid);
880 if (is_null_oid(cb->oid))
881 oidcpy(cb->oid, noid);
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700882 /* We just want the first entry */
883 return 1;
Junio C Hamano16d7cc92007-01-19 01:19:05 -0800884}
885
Johannes Schindelindddbad72017-04-26 21:29:31 +0200886int read_ref_at(const char *refname, unsigned int flags, timestamp_t at_time, int cnt,
brian m. carlson8eb36d92017-10-15 22:07:03 +0000887 struct object_id *oid, char **msg,
Johannes Schindelindddbad72017-04-26 21:29:31 +0200888 timestamp_t *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
Shawn Pearced556fae2006-05-17 05:56:09 -0400889{
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700890 struct read_ref_at_cb cb;
Shawn Pearced556fae2006-05-17 05:56:09 -0400891
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700892 memset(&cb, 0, sizeof(cb));
893 cb.refname = refname;
894 cb.at_time = at_time;
895 cb.cnt = cnt;
896 cb.msg = msg;
897 cb.cutoff_time = cutoff_time;
898 cb.cutoff_tz = cutoff_tz;
899 cb.cutoff_cnt = cutoff_cnt;
brian m. carlson8eb36d92017-10-15 22:07:03 +0000900 cb.oid = oid;
Shawn Pearced556fae2006-05-17 05:56:09 -0400901
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700902 for_each_reflog_ent_reverse(refname, read_ref_at_ent, &cb);
Shawn Pearced556fae2006-05-17 05:56:09 -0400903
David Aguilarc41a87d2014-09-18 20:45:37 -0700904 if (!cb.reccnt) {
brian m. carlson321c89b2017-07-13 23:49:29 +0000905 if (flags & GET_OID_QUIETLY)
David Aguilarc41a87d2014-09-18 20:45:37 -0700906 exit(128);
907 else
908 die("Log for %s is empty.", refname);
909 }
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700910 if (cb.found_it)
911 return 0;
Junio C Hamano16d7cc92007-01-19 01:19:05 -0800912
Ronnie Sahlberg4207ed22014-06-03 09:09:59 -0700913 for_each_reflog_ent(refname, read_ref_at_ent_oldest, &cb);
914
Junio C Hamano16d7cc92007-01-19 01:19:05 -0800915 return 1;
Shawn Pearced556fae2006-05-17 05:56:09 -0400916}
Junio C Hamano2ff81662006-12-18 01:18:16 -0800917
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700918struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs,
919 struct strbuf *err)
Michael Haggertycaa40462014-04-07 15:48:10 +0200920{
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700921 struct ref_transaction *tr;
Jonathan Nieder5a603b02014-08-28 16:42:37 -0700922 assert(err);
923
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +0700924 tr = xcalloc(1, sizeof(struct ref_transaction));
925 tr->ref_store = refs;
926 return tr;
927}
928
929struct ref_transaction *ref_transaction_begin(struct strbuf *err)
930{
931 return ref_store_transaction_begin(get_main_ref_store(), err);
Michael Haggertycaa40462014-04-07 15:48:10 +0200932}
933
Ronnie Sahlberg026bd1d2014-06-20 07:42:42 -0700934void ref_transaction_free(struct ref_transaction *transaction)
Michael Haggertycaa40462014-04-07 15:48:10 +0200935{
Michael Haggerty43a2dfd2017-05-22 16:17:37 +0200936 size_t i;
Michael Haggertycaa40462014-04-07 15:48:10 +0200937
Ronnie Sahlberg1b072552014-06-20 07:42:45 -0700938 if (!transaction)
939 return;
940
Michael Haggerty30173b82017-05-22 16:17:44 +0200941 switch (transaction->state) {
942 case REF_TRANSACTION_OPEN:
943 case REF_TRANSACTION_CLOSED:
944 /* OK */
945 break;
946 case REF_TRANSACTION_PREPARED:
947 die("BUG: free called on a prepared reference transaction");
948 break;
949 default:
950 die("BUG: unexpected reference transaction state");
951 break;
952 }
953
Ronnie Sahlbergdb7516a2014-04-30 12:22:42 -0700954 for (i = 0; i < transaction->nr; i++) {
955 free(transaction->updates[i]->msg);
Michael Haggerty88615912014-04-07 15:48:14 +0200956 free(transaction->updates[i]);
Ronnie Sahlbergdb7516a2014-04-30 12:22:42 -0700957 }
Michael Haggertycaa40462014-04-07 15:48:10 +0200958 free(transaction->updates);
959 free(transaction);
960}
961
Michael Haggerty71564512016-04-25 11:39:54 +0200962struct ref_update *ref_transaction_add_update(
963 struct ref_transaction *transaction,
964 const char *refname, unsigned int flags,
brian m. carlson89f3bbd2017-10-15 22:06:53 +0000965 const struct object_id *new_oid,
966 const struct object_id *old_oid,
Michael Haggerty71564512016-04-25 11:39:54 +0200967 const char *msg)
Michael Haggertycaa40462014-04-07 15:48:10 +0200968{
Jeff King96ffc062016-02-22 17:44:32 -0500969 struct ref_update *update;
Michael Haggerty71564512016-04-25 11:39:54 +0200970
971 if (transaction->state != REF_TRANSACTION_OPEN)
972 die("BUG: update called for transaction that is not open");
973
Jeff King96ffc062016-02-22 17:44:32 -0500974 FLEX_ALLOC_STR(update, refname, refname);
Michael Haggertycaa40462014-04-07 15:48:10 +0200975 ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc);
976 transaction->updates[transaction->nr++] = update;
Michael Haggerty71564512016-04-25 11:39:54 +0200977
978 update->flags = flags;
979
980 if (flags & REF_HAVE_NEW)
brian m. carlson89f3bbd2017-10-15 22:06:53 +0000981 oidcpy(&update->new_oid, new_oid);
Michael Haggerty71564512016-04-25 11:39:54 +0200982 if (flags & REF_HAVE_OLD)
brian m. carlson89f3bbd2017-10-15 22:06:53 +0000983 oidcpy(&update->old_oid, old_oid);
Junio C Hamano13092a92016-10-12 11:20:23 -0700984 update->msg = xstrdup_or_null(msg);
Michael Haggertycaa40462014-04-07 15:48:10 +0200985 return update;
986}
987
Ronnie Sahlberg8e348002014-06-20 07:43:00 -0700988int ref_transaction_update(struct ref_transaction *transaction,
989 const char *refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +0000990 const struct object_id *new_oid,
991 const struct object_id *old_oid,
Michael Haggerty1d147bd2015-02-17 18:00:15 +0100992 unsigned int flags, const char *msg,
Ronnie Sahlberg8e348002014-06-20 07:43:00 -0700993 struct strbuf *err)
Michael Haggertycaa40462014-04-07 15:48:10 +0200994{
Jonathan Nieder5a603b02014-08-28 16:42:37 -0700995 assert(err);
996
brian m. carlson89f3bbd2017-10-15 22:06:53 +0000997 if ((new_oid && !is_null_oid(new_oid)) ?
Michael Haggerty8a679de2016-04-27 15:54:45 +0200998 check_refname_format(refname, REFNAME_ALLOW_ONELEVEL) :
999 !refname_is_safe(refname)) {
Michael Haggerty0568c8e2016-04-27 15:21:36 +02001000 strbuf_addf(err, "refusing to update ref with bad name '%s'",
Ronnie Sahlbergd0f810f2014-09-03 11:45:43 -07001001 refname);
1002 return -1;
1003 }
1004
Michael Haggertya9bbbce2017-11-05 09:42:03 +01001005 if (flags & ~REF_TRANSACTION_UPDATE_ALLOWED_FLAGS)
1006 BUG("illegal flags 0x%x passed to ref_transaction_update()", flags);
Thomas Gummererc788c542017-09-12 23:59:21 +01001007
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001008 flags |= (new_oid ? REF_HAVE_NEW : 0) | (old_oid ? REF_HAVE_OLD : 0);
Michael Haggerty71564512016-04-25 11:39:54 +02001009
1010 ref_transaction_add_update(transaction, refname, flags,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001011 new_oid, old_oid, msg);
Ronnie Sahlberg8e348002014-06-20 07:43:00 -07001012 return 0;
Michael Haggertycaa40462014-04-07 15:48:10 +02001013}
1014
Ronnie Sahlbergb416af52014-04-16 15:26:44 -07001015int ref_transaction_create(struct ref_transaction *transaction,
1016 const char *refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001017 const struct object_id *new_oid,
Michael Haggertyfec14ec2015-02-17 18:00:13 +01001018 unsigned int flags, const char *msg,
Ronnie Sahlbergb416af52014-04-16 15:26:44 -07001019 struct strbuf *err)
Michael Haggertycaa40462014-04-07 15:48:10 +02001020{
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001021 if (!new_oid || is_null_oid(new_oid))
1022 die("BUG: create called without valid new_oid");
1023 return ref_transaction_update(transaction, refname, new_oid,
1024 &null_oid, flags, msg, err);
Michael Haggertycaa40462014-04-07 15:48:10 +02001025}
1026
Ronnie Sahlberg8c8bdc02014-04-16 15:27:45 -07001027int ref_transaction_delete(struct ref_transaction *transaction,
1028 const char *refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001029 const struct object_id *old_oid,
Michael Haggertyfb5a6bb2015-02-17 18:00:16 +01001030 unsigned int flags, const char *msg,
Ronnie Sahlberg8c8bdc02014-04-16 15:27:45 -07001031 struct strbuf *err)
Michael Haggertycaa40462014-04-07 15:48:10 +02001032{
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001033 if (old_oid && is_null_oid(old_oid))
1034 die("BUG: delete called with old_oid set to zeros");
Michael Haggerty1d147bd2015-02-17 18:00:15 +01001035 return ref_transaction_update(transaction, refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001036 &null_oid, old_oid,
Michael Haggerty1d147bd2015-02-17 18:00:15 +01001037 flags, msg, err);
Michael Haggertycaa40462014-04-07 15:48:10 +02001038}
1039
Michael Haggerty16180332015-02-17 18:00:21 +01001040int ref_transaction_verify(struct ref_transaction *transaction,
1041 const char *refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001042 const struct object_id *old_oid,
Michael Haggerty16180332015-02-17 18:00:21 +01001043 unsigned int flags,
1044 struct strbuf *err)
1045{
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001046 if (!old_oid)
1047 die("BUG: verify called with old_oid set to NULL");
Michael Haggerty16180332015-02-17 18:00:21 +01001048 return ref_transaction_update(transaction, refname,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001049 NULL, old_oid,
Michael Haggerty16180332015-02-17 18:00:21 +01001050 flags, NULL, err);
1051}
1052
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001053int refs_update_ref(struct ref_store *refs, const char *msg,
brian m. carlsonae077772017-10-15 22:06:51 +00001054 const char *refname, const struct object_id *new_oid,
1055 const struct object_id *old_oid, unsigned int flags,
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001056 enum action_on_err onerr)
Brad King4738a332013-09-04 11:22:40 -04001057{
David Turner74ec19d2015-07-31 02:06:19 -04001058 struct ref_transaction *t = NULL;
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001059 struct strbuf err = STRBUF_INIT;
David Turner74ec19d2015-07-31 02:06:19 -04001060 int ret = 0;
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001061
David Turner74ec19d2015-07-31 02:06:19 -04001062 if (ref_type(refname) == REF_TYPE_PSEUDOREF) {
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001063 assert(refs == get_main_ref_store());
brian m. carlsonae077772017-10-15 22:06:51 +00001064 ret = write_pseudoref(refname, new_oid, old_oid, &err);
David Turner74ec19d2015-07-31 02:06:19 -04001065 } else {
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001066 t = ref_store_transaction_begin(refs, &err);
David Turner74ec19d2015-07-31 02:06:19 -04001067 if (!t ||
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001068 ref_transaction_update(t, refname, new_oid, old_oid,
David Turner74ec19d2015-07-31 02:06:19 -04001069 flags, msg, &err) ||
1070 ref_transaction_commit(t, &err)) {
1071 ret = 1;
1072 ref_transaction_free(t);
1073 }
1074 }
1075 if (ret) {
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001076 const char *str = "update_ref failed for ref '%s': %s";
1077
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001078 switch (onerr) {
1079 case UPDATE_REFS_MSG_ON_ERR:
1080 error(str, refname, err.buf);
1081 break;
1082 case UPDATE_REFS_DIE_ON_ERR:
1083 die(str, refname, err.buf);
1084 break;
1085 case UPDATE_REFS_QUIET_ON_ERR:
1086 break;
1087 }
1088 strbuf_release(&err);
Brad King4738a332013-09-04 11:22:40 -04001089 return 1;
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001090 }
1091 strbuf_release(&err);
David Turner74ec19d2015-07-31 02:06:19 -04001092 if (t)
1093 ref_transaction_free(t);
Ronnie Sahlbergb4d75ac2014-04-24 16:36:55 -07001094 return 0;
Brad King4738a332013-09-04 11:22:40 -04001095}
1096
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001097int update_ref(const char *msg, const char *refname,
brian m. carlsonae077772017-10-15 22:06:51 +00001098 const struct object_id *new_oid,
1099 const struct object_id *old_oid,
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001100 unsigned int flags, enum action_on_err onerr)
1101{
brian m. carlsonae077772017-10-15 22:06:51 +00001102 return refs_update_ref(get_main_ref_store(), msg, refname, new_oid,
1103 old_oid, flags, onerr);
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001104}
1105
Michael Haggertydfefa932011-12-12 06:38:09 +01001106char *shorten_unambiguous_ref(const char *refname, int strict)
Jeff King7c2b3022009-04-07 03:14:20 -04001107{
1108 int i;
1109 static char **scanf_fmts;
1110 static int nr_rules;
1111 char *short_name;
Jeff King6cd4a892017-03-28 15:46:33 -04001112 struct strbuf resolved_buf = STRBUF_INIT;
Jeff King7c2b3022009-04-07 03:14:20 -04001113
Jeff King7c2b3022009-04-07 03:14:20 -04001114 if (!nr_rules) {
Michael Haggerty43466632014-01-08 15:43:39 +01001115 /*
1116 * Pre-generate scanf formats from ref_rev_parse_rules[].
1117 * Generate a format suitable for scanf from a
1118 * ref_rev_parse_rules rule by interpolating "%s" at the
1119 * location of the "%.*s".
1120 */
Jeff King7c2b3022009-04-07 03:14:20 -04001121 size_t total_len = 0;
Michael Haggerty84d56332014-01-08 15:43:38 +01001122 size_t offset = 0;
Jeff King7c2b3022009-04-07 03:14:20 -04001123
1124 /* the rule list is NULL terminated, count them first */
Jeff Kinga4165852013-10-24 04:45:13 -04001125 for (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++)
Michael Haggerty7902fe02014-01-08 15:43:40 +01001126 /* -2 for strlen("%.*s") - strlen("%s"); +1 for NUL */
1127 total_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 + 1;
Jeff King7c2b3022009-04-07 03:14:20 -04001128
René Scharfe50492f72016-07-30 20:18:31 +02001129 scanf_fmts = xmalloc(st_add(st_mult(sizeof(char *), nr_rules), total_len));
Jeff King7c2b3022009-04-07 03:14:20 -04001130
Michael Haggerty84d56332014-01-08 15:43:38 +01001131 offset = 0;
Jeff King7c2b3022009-04-07 03:14:20 -04001132 for (i = 0; i < nr_rules; i++) {
Michael Haggerty43466632014-01-08 15:43:39 +01001133 assert(offset < total_len);
Michael Haggerty84d56332014-01-08 15:43:38 +01001134 scanf_fmts[i] = (char *)&scanf_fmts[nr_rules] + offset;
Michael Haggerty43466632014-01-08 15:43:39 +01001135 offset += snprintf(scanf_fmts[i], total_len - offset,
1136 ref_rev_parse_rules[i], 2, "%s") + 1;
Jeff King7c2b3022009-04-07 03:14:20 -04001137 }
1138 }
1139
1140 /* bail out if there are no rules */
1141 if (!nr_rules)
Michael Haggertydfefa932011-12-12 06:38:09 +01001142 return xstrdup(refname);
Jeff King7c2b3022009-04-07 03:14:20 -04001143
Michael Haggertydfefa932011-12-12 06:38:09 +01001144 /* buffer for scanf result, at most refname must fit */
1145 short_name = xstrdup(refname);
Jeff King7c2b3022009-04-07 03:14:20 -04001146
1147 /* skip first rule, it will always match */
1148 for (i = nr_rules - 1; i > 0 ; --i) {
1149 int j;
Bert Wesarg6e7b3302009-04-13 12:25:46 +02001150 int rules_to_fail = i;
Jeff King7c2b3022009-04-07 03:14:20 -04001151 int short_name_len;
1152
Michael Haggertydfefa932011-12-12 06:38:09 +01001153 if (1 != sscanf(refname, scanf_fmts[i], short_name))
Jeff King7c2b3022009-04-07 03:14:20 -04001154 continue;
1155
1156 short_name_len = strlen(short_name);
1157
1158 /*
Bert Wesarg6e7b3302009-04-13 12:25:46 +02001159 * in strict mode, all (except the matched one) rules
1160 * must fail to resolve to a valid non-ambiguous ref
1161 */
1162 if (strict)
1163 rules_to_fail = nr_rules;
1164
1165 /*
Jeff King7c2b3022009-04-07 03:14:20 -04001166 * check if the short name resolves to a valid ref,
1167 * but use only rules prior to the matched one
1168 */
Bert Wesarg6e7b3302009-04-13 12:25:46 +02001169 for (j = 0; j < rules_to_fail; j++) {
Jeff King7c2b3022009-04-07 03:14:20 -04001170 const char *rule = ref_rev_parse_rules[j];
Jeff King7c2b3022009-04-07 03:14:20 -04001171
Bert Wesarg6e7b3302009-04-13 12:25:46 +02001172 /* skip matched rule */
1173 if (i == j)
1174 continue;
1175
Jeff King7c2b3022009-04-07 03:14:20 -04001176 /*
1177 * the short name is ambiguous, if it resolves
1178 * (with this previous rule) to a valid ref
1179 * read_ref() returns 0 on success
1180 */
Jeff King6cd4a892017-03-28 15:46:33 -04001181 strbuf_reset(&resolved_buf);
1182 strbuf_addf(&resolved_buf, rule,
1183 short_name_len, short_name);
1184 if (ref_exists(resolved_buf.buf))
Jeff King7c2b3022009-04-07 03:14:20 -04001185 break;
1186 }
1187
1188 /*
1189 * short name is non-ambiguous if all previous rules
1190 * haven't resolved to a valid ref
1191 */
Jeff King6cd4a892017-03-28 15:46:33 -04001192 if (j == rules_to_fail) {
1193 strbuf_release(&resolved_buf);
Jeff King7c2b3022009-04-07 03:14:20 -04001194 return short_name;
Jeff King6cd4a892017-03-28 15:46:33 -04001195 }
Jeff King7c2b3022009-04-07 03:14:20 -04001196 }
1197
Jeff King6cd4a892017-03-28 15:46:33 -04001198 strbuf_release(&resolved_buf);
Jeff King7c2b3022009-04-07 03:14:20 -04001199 free(short_name);
Michael Haggertydfefa932011-12-12 06:38:09 +01001200 return xstrdup(refname);
Jeff King7c2b3022009-04-07 03:14:20 -04001201}
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001202
1203static struct string_list *hide_refs;
1204
1205int parse_hide_refs_config(const char *var, const char *value, const char *section)
1206{
Jeff Kingad8c7cd2017-02-24 16:08:16 -05001207 const char *key;
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001208 if (!strcmp("transfer.hiderefs", var) ||
Jeff Kingad8c7cd2017-02-24 16:08:16 -05001209 (!parse_config_key(var, section, NULL, NULL, &key) &&
1210 !strcmp(key, "hiderefs"))) {
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001211 char *ref;
1212 int len;
1213
1214 if (!value)
1215 return config_error_nonbool(var);
1216 ref = xstrdup(value);
1217 len = strlen(ref);
1218 while (len && ref[len - 1] == '/')
1219 ref[--len] = '\0';
1220 if (!hide_refs) {
1221 hide_refs = xcalloc(1, sizeof(*hide_refs));
1222 hide_refs->strdup_strings = 1;
1223 }
1224 string_list_append(hide_refs, ref);
1225 }
1226 return 0;
1227}
1228
Lukas Fleischer78a766a2015-11-03 08:58:16 +01001229int ref_is_hidden(const char *refname, const char *refname_full)
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001230{
Jeff King2bc31d12015-07-28 16:23:26 -04001231 int i;
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001232
1233 if (!hide_refs)
1234 return 0;
Jeff King2bc31d12015-07-28 16:23:26 -04001235 for (i = hide_refs->nr - 1; i >= 0; i--) {
1236 const char *match = hide_refs->items[i].string;
Lukas Fleischer78a766a2015-11-03 08:58:16 +01001237 const char *subject;
Jeff King2bc31d12015-07-28 16:23:26 -04001238 int neg = 0;
Christian Couder7a40a952017-07-22 06:39:12 +02001239 const char *p;
Jeff King2bc31d12015-07-28 16:23:26 -04001240
1241 if (*match == '!') {
1242 neg = 1;
1243 match++;
1244 }
1245
Lukas Fleischer78a766a2015-11-03 08:58:16 +01001246 if (*match == '^') {
1247 subject = refname_full;
1248 match++;
1249 } else {
1250 subject = refname;
1251 }
1252
1253 /* refname can be NULL when namespaces are used. */
Christian Couder7a40a952017-07-22 06:39:12 +02001254 if (subject &&
1255 skip_prefix(subject, match, &p) &&
1256 (!*p || *p == '/'))
Jeff King2bc31d12015-07-28 16:23:26 -04001257 return !neg;
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001258 }
1259 return 0;
1260}
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001261
David Turner08451222015-11-10 12:42:40 +01001262const char *find_descendant_ref(const char *dirname,
1263 const struct string_list *extras,
1264 const struct string_list *skip)
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001265{
David Turner08451222015-11-10 12:42:40 +01001266 int pos;
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001267
David Turner08451222015-11-10 12:42:40 +01001268 if (!extras)
1269 return NULL;
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001270
1271 /*
David Turner08451222015-11-10 12:42:40 +01001272 * Look at the place where dirname would be inserted into
1273 * extras. If there is an entry at that position that starts
1274 * with dirname (remember, dirname includes the trailing
1275 * slash) and is not in skip, then we have a conflict.
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001276 */
David Turner08451222015-11-10 12:42:40 +01001277 for (pos = string_list_find_insert_index(extras, dirname, 0);
1278 pos < extras->nr; pos++) {
1279 const char *extra_refname = extras->items[pos].string;
1280
1281 if (!starts_with(extra_refname, dirname))
1282 break;
1283
1284 if (!skip || !string_list_has_string(skip, extra_refname))
1285 return extra_refname;
Michael Haggerty4a32b2e2015-05-11 17:25:15 +02001286 }
David Turner08451222015-11-10 12:42:40 +01001287 return NULL;
1288}
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001289
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001290int refs_rename_ref_available(struct ref_store *refs,
1291 const char *old_refname,
1292 const char *new_refname)
David Turner08451222015-11-10 12:42:40 +01001293{
1294 struct string_list skip = STRING_LIST_INIT_NODUP;
1295 struct strbuf err = STRBUF_INIT;
David Turnerff3a2992016-09-04 18:08:08 +02001296 int ok;
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001297
David Turnerff3a2992016-09-04 18:08:08 +02001298 string_list_insert(&skip, old_refname);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001299 ok = !refs_verify_refname_available(refs, new_refname,
1300 NULL, &skip, &err);
David Turnerff3a2992016-09-04 18:08:08 +02001301 if (!ok)
David Turner08451222015-11-10 12:42:40 +01001302 error("%s", err.buf);
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001303
David Turner08451222015-11-10 12:42:40 +01001304 string_list_clear(&skip, 0);
1305 strbuf_release(&err);
David Turnerff3a2992016-09-04 18:08:08 +02001306 return ok;
Michael Haggertyfa5b1832014-12-12 09:56:59 +01001307}
David Turner2bf68ed2016-04-07 15:02:48 -04001308
Nguyễn Thái Ngọc Duy62f0b392017-08-23 19:36:55 +07001309int refs_head_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
David Turner2bf68ed2016-04-07 15:02:48 -04001310{
1311 struct object_id oid;
1312 int flag;
1313
Nguyễn Thái Ngọc Duy62f0b392017-08-23 19:36:55 +07001314 if (!refs_read_ref_full(refs, "HEAD", RESOLVE_REF_READING,
brian m. carlson34c290a2017-10-15 22:06:56 +00001315 &oid, &flag))
David Turner2bf68ed2016-04-07 15:02:48 -04001316 return fn("HEAD", &oid, flag, cb_data);
1317
1318 return 0;
1319}
1320
1321int head_ref(each_ref_fn fn, void *cb_data)
1322{
Nguyễn Thái Ngọc Duy62f0b392017-08-23 19:36:55 +07001323 return refs_head_ref(get_main_ref_store(), fn, cb_data);
David Turner2bf68ed2016-04-07 15:02:48 -04001324}
David Turner93770592016-04-07 15:02:49 -04001325
Michael Haggertye121b9c2017-03-20 17:33:08 +01001326struct ref_iterator *refs_ref_iterator_begin(
1327 struct ref_store *refs,
1328 const char *prefix, int trim, int flags)
1329{
1330 struct ref_iterator *iter;
1331
Michael Haggerty0a0865b2017-05-22 16:17:52 +02001332 if (ref_paranoia < 0)
1333 ref_paranoia = git_env_bool("GIT_REF_PARANOIA", 0);
1334 if (ref_paranoia)
1335 flags |= DO_FOR_EACH_INCLUDE_BROKEN;
1336
Michael Haggertye121b9c2017-03-20 17:33:08 +01001337 iter = refs->be->iterator_begin(refs, prefix, flags);
Michael Haggertyc7599712017-05-22 16:17:36 +02001338
1339 /*
1340 * `iterator_begin()` already takes care of prefix, but we
1341 * might need to do some trimming:
1342 */
1343 if (trim)
1344 iter = prefix_ref_iterator_begin(iter, "", trim);
Michael Haggertye121b9c2017-03-20 17:33:08 +01001345
Michael Haggerty8738a8a2017-09-13 19:15:55 +02001346 /* Sanity check for subclasses: */
1347 if (!iter->ordered)
1348 BUG("reference iterator is not ordered");
1349
Michael Haggertye121b9c2017-03-20 17:33:08 +01001350 return iter;
1351}
1352
Michael Haggerty4c4de892016-06-18 06:15:16 +02001353/*
1354 * Call fn for each reference in the specified submodule for which the
1355 * refname begins with prefix. If trim is non-zero, then trim that
1356 * many characters off the beginning of each refname before passing
1357 * the refname to fn. flags can be DO_FOR_EACH_INCLUDE_BROKEN to
1358 * include broken references in the iteration. If fn ever returns a
1359 * non-zero value, stop the iteration and return that value;
1360 * otherwise, return 0.
1361 */
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001362static int do_for_each_ref(struct ref_store *refs, const char *prefix,
Michael Haggerty4c4de892016-06-18 06:15:16 +02001363 each_ref_fn fn, int trim, int flags, void *cb_data)
1364{
1365 struct ref_iterator *iter;
1366
Michael Haggerty00eebe32016-09-04 18:08:11 +02001367 if (!refs)
1368 return 0;
1369
Michael Haggertye121b9c2017-03-20 17:33:08 +01001370 iter = refs_ref_iterator_begin(refs, prefix, trim, flags);
Michael Haggerty4c4de892016-06-18 06:15:16 +02001371
1372 return do_for_each_ref_iterator(iter, fn, cb_data);
1373}
1374
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001375int refs_for_each_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
1376{
1377 return do_for_each_ref(refs, "", fn, 0, 0, cb_data);
1378}
1379
David Turner93770592016-04-07 15:02:49 -04001380int for_each_ref(each_ref_fn fn, void *cb_data)
1381{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001382 return refs_for_each_ref(get_main_ref_store(), fn, cb_data);
David Turner93770592016-04-07 15:02:49 -04001383}
1384
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001385int refs_for_each_ref_in(struct ref_store *refs, const char *prefix,
1386 each_ref_fn fn, void *cb_data)
1387{
1388 return do_for_each_ref(refs, prefix, fn, strlen(prefix), 0, cb_data);
David Turner93770592016-04-07 15:02:49 -04001389}
1390
1391int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
1392{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001393 return refs_for_each_ref_in(get_main_ref_store(), prefix, fn, cb_data);
David Turner93770592016-04-07 15:02:49 -04001394}
1395
1396int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken)
1397{
1398 unsigned int flag = 0;
1399
1400 if (broken)
1401 flag = DO_FOR_EACH_INCLUDE_BROKEN;
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001402 return do_for_each_ref(get_main_ref_store(),
1403 prefix, fn, 0, flag, cb_data);
David Turner93770592016-04-07 15:02:49 -04001404}
1405
Nguyễn Thái Ngọc Duy073cf632017-08-23 19:36:56 +07001406int refs_for_each_fullref_in(struct ref_store *refs, const char *prefix,
1407 each_ref_fn fn, void *cb_data,
1408 unsigned int broken)
Michael Haggerty03df5672017-06-18 15:39:41 +02001409{
1410 unsigned int flag = 0;
1411
1412 if (broken)
1413 flag = DO_FOR_EACH_INCLUDE_BROKEN;
Nguyễn Thái Ngọc Duy073cf632017-08-23 19:36:56 +07001414 return do_for_each_ref(refs, prefix, fn, 0, flag, cb_data);
Michael Haggerty03df5672017-06-18 15:39:41 +02001415}
1416
David Turner93770592016-04-07 15:02:49 -04001417int for_each_replace_ref(each_ref_fn fn, void *cb_data)
1418{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001419 return do_for_each_ref(get_main_ref_store(),
1420 git_replace_ref_base, fn,
1421 strlen(git_replace_ref_base),
Stefan Beller006f3f22017-09-12 10:31:40 -07001422 DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
David Turner93770592016-04-07 15:02:49 -04001423}
1424
1425int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
1426{
1427 struct strbuf buf = STRBUF_INIT;
1428 int ret;
1429 strbuf_addf(&buf, "%srefs/", get_git_namespace());
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001430 ret = do_for_each_ref(get_main_ref_store(),
1431 buf.buf, fn, 0, 0, cb_data);
David Turner93770592016-04-07 15:02:49 -04001432 strbuf_release(&buf);
1433 return ret;
1434}
1435
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001436int refs_for_each_rawref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
David Turner93770592016-04-07 15:02:49 -04001437{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001438 return do_for_each_ref(refs, "", fn, 0,
David Turner93770592016-04-07 15:02:49 -04001439 DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
1440}
David Turner2d0663b2016-04-07 15:03:10 -04001441
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001442int for_each_rawref(each_ref_fn fn, void *cb_data)
1443{
1444 return refs_for_each_rawref(get_main_ref_store(), fn, cb_data);
1445}
1446
Michael Haggerty470be512017-03-20 17:33:07 +01001447int refs_read_raw_ref(struct ref_store *ref_store,
brian m. carlson99afe912017-10-15 22:07:11 +00001448 const char *refname, struct object_id *oid,
Michael Haggerty470be512017-03-20 17:33:07 +01001449 struct strbuf *referent, unsigned int *type)
1450{
brian m. carlson99afe912017-10-15 22:07:11 +00001451 return ref_store->be->read_raw_ref(ref_store, refname, oid, referent, type);
Michael Haggerty470be512017-03-20 17:33:07 +01001452}
1453
David Turner2d0663b2016-04-07 15:03:10 -04001454/* This function needs to return a meaningful errno on failure */
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001455const char *refs_resolve_ref_unsafe(struct ref_store *refs,
Michael Haggerty3c0cb0c2017-02-09 21:53:52 +01001456 const char *refname,
1457 int resolve_flags,
brian m. carlson49e61472017-10-15 22:07:09 +00001458 struct object_id *oid, int *flags)
David Turner2d0663b2016-04-07 15:03:10 -04001459{
1460 static struct strbuf sb_refname = STRBUF_INIT;
René Scharfe54fad662017-09-23 11:41:45 +02001461 struct object_id unused_oid;
David Turner2d0663b2016-04-07 15:03:10 -04001462 int unused_flags;
1463 int symref_count;
1464
brian m. carlson49e61472017-10-15 22:07:09 +00001465 if (!oid)
1466 oid = &unused_oid;
David Turner2d0663b2016-04-07 15:03:10 -04001467 if (!flags)
1468 flags = &unused_flags;
1469
1470 *flags = 0;
1471
1472 if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
1473 if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
1474 !refname_is_safe(refname)) {
1475 errno = EINVAL;
1476 return NULL;
1477 }
1478
1479 /*
1480 * dwim_ref() uses REF_ISBROKEN to distinguish between
1481 * missing refs and refs that were present but invalid,
1482 * to complain about the latter to stderr.
1483 *
1484 * We don't know whether the ref exists, so don't set
1485 * REF_ISBROKEN yet.
1486 */
1487 *flags |= REF_BAD_NAME;
1488 }
1489
1490 for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) {
1491 unsigned int read_flags = 0;
1492
Michael Haggerty470be512017-03-20 17:33:07 +01001493 if (refs_read_raw_ref(refs, refname,
brian m. carlson99afe912017-10-15 22:07:11 +00001494 oid, &sb_refname, &read_flags)) {
David Turner2d0663b2016-04-07 15:03:10 -04001495 *flags |= read_flags;
Jeff Kinga1c1d812017-10-06 10:42:17 -04001496
1497 /* In reading mode, refs must eventually resolve */
1498 if (resolve_flags & RESOLVE_REF_READING)
David Turner2d0663b2016-04-07 15:03:10 -04001499 return NULL;
Jeff Kinga1c1d812017-10-06 10:42:17 -04001500
1501 /*
1502 * Otherwise a missing ref is OK. But the files backend
1503 * may show errors besides ENOENT if there are
1504 * similarly-named refs.
1505 */
1506 if (errno != ENOENT &&
1507 errno != EISDIR &&
1508 errno != ENOTDIR)
1509 return NULL;
1510
brian m. carlson49e61472017-10-15 22:07:09 +00001511 oidclr(oid);
David Turner2d0663b2016-04-07 15:03:10 -04001512 if (*flags & REF_BAD_NAME)
1513 *flags |= REF_ISBROKEN;
1514 return refname;
1515 }
1516
1517 *flags |= read_flags;
1518
1519 if (!(read_flags & REF_ISSYMREF)) {
1520 if (*flags & REF_BAD_NAME) {
brian m. carlson49e61472017-10-15 22:07:09 +00001521 oidclr(oid);
David Turner2d0663b2016-04-07 15:03:10 -04001522 *flags |= REF_ISBROKEN;
1523 }
1524 return refname;
1525 }
1526
1527 refname = sb_refname.buf;
1528 if (resolve_flags & RESOLVE_REF_NO_RECURSE) {
brian m. carlson49e61472017-10-15 22:07:09 +00001529 oidclr(oid);
David Turner2d0663b2016-04-07 15:03:10 -04001530 return refname;
1531 }
1532 if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
1533 if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
1534 !refname_is_safe(refname)) {
1535 errno = EINVAL;
1536 return NULL;
1537 }
1538
1539 *flags |= REF_ISBROKEN | REF_BAD_NAME;
1540 }
1541 }
1542
1543 errno = ELOOP;
1544 return NULL;
1545}
Michael Haggerty00eebe32016-09-04 18:08:11 +02001546
David Turner6fb5acf2016-09-04 18:08:41 +02001547/* backend functions */
1548int refs_init_db(struct strbuf *err)
1549{
Nguyễn Thái Ngọc Duy077be782017-03-26 09:42:29 +07001550 struct ref_store *refs = get_main_ref_store();
David Turner6fb5acf2016-09-04 18:08:41 +02001551
1552 return refs->be->init_db(refs, err);
1553}
1554
Michael Haggertybd40dcd2016-09-04 18:08:21 +02001555const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
brian m. carlson49e61472017-10-15 22:07:09 +00001556 struct object_id *oid, int *flags)
Michael Haggertybd40dcd2016-09-04 18:08:21 +02001557{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001558 return refs_resolve_ref_unsafe(get_main_ref_store(), refname,
brian m. carlson49e61472017-10-15 22:07:09 +00001559 resolve_flags, oid, flags);
Michael Haggertybd40dcd2016-09-04 18:08:21 +02001560}
1561
Michael Haggertya8355bb2016-09-04 18:08:24 +02001562int resolve_gitlink_ref(const char *submodule, const char *refname,
brian m. carlsona98e6102017-10-15 22:07:07 +00001563 struct object_id *oid)
Michael Haggerty424dcc72016-09-04 18:08:22 +02001564{
Michael Haggerty424dcc72016-09-04 18:08:22 +02001565 struct ref_store *refs;
1566 int flags;
1567
Nguyễn Thái Ngọc Duy29babbe2017-08-23 19:36:54 +07001568 refs = get_submodule_ref_store(submodule);
Michael Haggerty48a84752016-09-04 18:08:23 +02001569
Michael Haggerty424dcc72016-09-04 18:08:22 +02001570 if (!refs)
1571 return -1;
1572
brian m. carlson49e61472017-10-15 22:07:09 +00001573 if (!refs_resolve_ref_unsafe(refs, refname, 0, oid, &flags) ||
brian m. carlsona98e6102017-10-15 22:07:07 +00001574 is_null_oid(oid))
Michael Haggerty424dcc72016-09-04 18:08:22 +02001575 return -1;
1576 return 0;
1577}
1578
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001579struct ref_store_hash_entry
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001580{
1581 struct hashmap_entry ent; /* must be the first member! */
1582
1583 struct ref_store *refs;
1584
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001585 /* NUL-terminated identifier of the ref store: */
1586 char name[FLEX_ARRAY];
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001587};
1588
Stefan Beller7663cdc2017-06-30 12:14:05 -07001589static int ref_store_hash_cmp(const void *unused_cmp_data,
1590 const void *entry, const void *entry_or_key,
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001591 const void *keydata)
1592{
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001593 const struct ref_store_hash_entry *e1 = entry, *e2 = entry_or_key;
1594 const char *name = keydata ? keydata : e2->name;
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001595
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001596 return strcmp(e1->name, name);
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001597}
1598
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001599static struct ref_store_hash_entry *alloc_ref_store_hash_entry(
1600 const char *name, struct ref_store *refs)
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001601{
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001602 struct ref_store_hash_entry *entry;
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001603
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001604 FLEX_ALLOC_STR(entry, name, name);
1605 hashmap_entry_init(entry, strhash(name));
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001606 entry->refs = refs;
1607 return entry;
1608}
1609
Michael Haggerty00eebe32016-09-04 18:08:11 +02001610/* A pointer to the ref_store for the main repository: */
1611static struct ref_store *main_ref_store;
1612
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001613/* A hashmap of ref_stores, stored by submodule name: */
1614static struct hashmap submodule_ref_stores;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001615
Nguyễn Thái Ngọc Duy17eff962017-04-24 17:01:22 +07001616/* A hashmap of ref_stores, stored by worktree id: */
1617static struct hashmap worktree_ref_stores;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001618
Michael Haggerty00eebe32016-09-04 18:08:11 +02001619/*
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001620 * Look up a ref store by name. If that ref_store hasn't been
1621 * registered yet, return NULL.
Michael Haggerty00eebe32016-09-04 18:08:11 +02001622 */
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001623static struct ref_store *lookup_ref_store_map(struct hashmap *map,
1624 const char *name)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001625{
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001626 struct ref_store_hash_entry *entry;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001627
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001628 if (!map->tablesize)
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001629 /* It's initialized on demand in register_ref_store(). */
1630 return NULL;
Michael Haggerty620a66b2017-02-10 12:16:11 +01001631
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001632 entry = hashmap_get_from_hash(map, strhash(name), name);
Michael Haggerty7d4558c2017-02-10 12:16:15 +01001633 return entry ? entry->refs : NULL;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001634}
1635
Michael Haggertyc468da42017-02-10 12:16:12 +01001636/*
1637 * Create, record, and return a ref_store instance for the specified
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +07001638 * gitdir.
Michael Haggertyc468da42017-02-10 12:16:12 +01001639 */
Nguyễn Thái Ngọc Duy9e7ec632017-03-26 09:42:32 +07001640static struct ref_store *ref_store_init(const char *gitdir,
1641 unsigned int flags)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001642{
1643 const char *be_name = "files";
1644 struct ref_storage_be *be = find_ref_storage_backend(be_name);
Michael Haggertyba88add2017-02-10 12:16:14 +01001645 struct ref_store *refs;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001646
1647 if (!be)
1648 die("BUG: reference backend %s is unknown", be_name);
1649
Nguyễn Thái Ngọc Duy9e7ec632017-03-26 09:42:32 +07001650 refs = be->init(gitdir, flags);
Michael Haggertyba88add2017-02-10 12:16:14 +01001651 return refs;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001652}
1653
Nguyễn Thái Ngọc Duy077be782017-03-26 09:42:29 +07001654struct ref_store *get_main_ref_store(void)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001655{
Nguyễn Thái Ngọc Duy24c84072017-03-26 09:42:25 +07001656 if (main_ref_store)
1657 return main_ref_store;
1658
Nguyễn Thái Ngọc Duy0d8a8142017-04-24 17:01:21 +07001659 main_ref_store = ref_store_init(get_git_dir(), REF_STORE_ALL_CAPS);
Nguyễn Thái Ngọc Duy378dc912017-03-26 09:42:28 +07001660 return main_ref_store;
1661}
1662
1663/*
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001664 * Associate a ref store with a name. It is a fatal error to call this
1665 * function twice for the same name.
Nguyễn Thái Ngọc Duy378dc912017-03-26 09:42:28 +07001666 */
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001667static void register_ref_store_map(struct hashmap *map,
1668 const char *type,
1669 struct ref_store *refs,
1670 const char *name)
Nguyễn Thái Ngọc Duy378dc912017-03-26 09:42:28 +07001671{
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001672 if (!map->tablesize)
Stefan Beller7663cdc2017-06-30 12:14:05 -07001673 hashmap_init(map, ref_store_hash_cmp, NULL, 0);
Nguyễn Thái Ngọc Duy378dc912017-03-26 09:42:28 +07001674
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001675 if (hashmap_put(map, alloc_ref_store_hash_entry(name, refs)))
1676 die("BUG: %s ref_store '%s' initialized twice", type, name);
Nguyễn Thái Ngọc Duy24c84072017-03-26 09:42:25 +07001677}
1678
Nguyễn Thái Ngọc Duy18d00022017-03-26 09:42:33 +07001679struct ref_store *get_submodule_ref_store(const char *submodule)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001680{
Nguyễn Thái Ngọc Duy126c9e02017-03-26 09:42:27 +07001681 struct strbuf submodule_sb = STRBUF_INIT;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001682 struct ref_store *refs;
Nguyễn Thái Ngọc Duy29babbe2017-08-23 19:36:54 +07001683 char *to_free = NULL;
1684 size_t len;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001685
Nguyễn Thái Ngọc Duy82a150f2017-08-23 19:37:03 +07001686 if (!submodule)
1687 return NULL;
1688
Nguyễn Thái Ngọc Duy873ea902017-08-23 19:37:04 +07001689 len = strlen(submodule);
1690 while (len && is_dir_sep(submodule[len - 1]))
1691 len--;
1692 if (!len)
1693 return NULL;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001694
Nguyễn Thái Ngọc Duy29babbe2017-08-23 19:36:54 +07001695 if (submodule[len])
1696 /* We need to strip off one or more trailing slashes */
1697 submodule = to_free = xmemdupz(submodule, len);
Michael Haggerty00eebe32016-09-04 18:08:11 +02001698
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001699 refs = lookup_ref_store_map(&submodule_ref_stores, submodule);
Nguyễn Thái Ngọc Duy126c9e02017-03-26 09:42:27 +07001700 if (refs)
Nguyễn Thái Ngọc Duy2c616c12017-08-23 19:36:53 +07001701 goto done;
Nguyễn Thái Ngọc Duy126c9e02017-03-26 09:42:27 +07001702
1703 strbuf_addstr(&submodule_sb, submodule);
Nguyễn Thái Ngọc Duy2c616c12017-08-23 19:36:53 +07001704 if (!is_nonbare_repository_dir(&submodule_sb))
1705 goto done;
Nguyễn Thái Ngọc Duy126c9e02017-03-26 09:42:27 +07001706
Nguyễn Thái Ngọc Duy2c616c12017-08-23 19:36:53 +07001707 if (submodule_to_gitdir(&submodule_sb, submodule))
1708 goto done;
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +07001709
Nguyễn Thái Ngọc Duy9e7ec632017-03-26 09:42:32 +07001710 /* assume that add_submodule_odb() has been called */
1711 refs = ref_store_init(submodule_sb.buf,
1712 REF_STORE_READ | REF_STORE_ODB);
Nguyễn Thái Ngọc Duy0c064d92017-04-04 17:21:20 +07001713 register_ref_store_map(&submodule_ref_stores, "submodule",
1714 refs, submodule);
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +07001715
Nguyễn Thái Ngọc Duy2c616c12017-08-23 19:36:53 +07001716done:
Nguyễn Thái Ngọc Duy5d0bc902017-03-26 09:42:31 +07001717 strbuf_release(&submodule_sb);
Nguyễn Thái Ngọc Duy29babbe2017-08-23 19:36:54 +07001718 free(to_free);
1719
Michael Haggerty00eebe32016-09-04 18:08:11 +02001720 return refs;
1721}
1722
Nguyễn Thái Ngọc Duy17eff962017-04-24 17:01:22 +07001723struct ref_store *get_worktree_ref_store(const struct worktree *wt)
1724{
1725 struct ref_store *refs;
1726 const char *id;
1727
1728 if (wt->is_current)
1729 return get_main_ref_store();
1730
1731 id = wt->id ? wt->id : "/";
1732 refs = lookup_ref_store_map(&worktree_ref_stores, id);
1733 if (refs)
1734 return refs;
1735
1736 if (wt->id)
1737 refs = ref_store_init(git_common_path("worktrees/%s", wt->id),
1738 REF_STORE_ALL_CAPS);
1739 else
1740 refs = ref_store_init(get_git_common_dir(),
1741 REF_STORE_ALL_CAPS);
1742
1743 if (refs)
1744 register_ref_store_map(&worktree_ref_stores, "worktree",
1745 refs, id);
1746 return refs;
1747}
1748
Michael Haggerty620a66b2017-02-10 12:16:11 +01001749void base_ref_store_init(struct ref_store *refs,
Michael Haggertyfbfd0a22017-02-10 12:16:17 +01001750 const struct ref_storage_be *be)
Michael Haggerty00eebe32016-09-04 18:08:11 +02001751{
Michael Haggerty620a66b2017-02-10 12:16:11 +01001752 refs->be = be;
Michael Haggerty00eebe32016-09-04 18:08:11 +02001753}
Ronnie Sahlberg127b42a2016-09-04 18:08:16 +02001754
1755/* backend functions */
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001756int refs_pack_refs(struct ref_store *refs, unsigned int flags)
Michael Haggerty82315272016-09-04 18:08:27 +02001757{
Michael Haggerty82315272016-09-04 18:08:27 +02001758 return refs->be->pack_refs(refs, flags);
1759}
1760
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001761int refs_peel_ref(struct ref_store *refs, const char *refname,
brian m. carlsonb420d902017-10-15 22:07:02 +00001762 struct object_id *oid)
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001763{
Michael Haggertyba1c0522017-09-25 10:00:14 +02001764 int flag;
brian m. carlson34c290a2017-10-15 22:06:56 +00001765 struct object_id base;
Michael Haggertyba1c0522017-09-25 10:00:14 +02001766
1767 if (current_ref_iter && current_ref_iter->refname == refname) {
1768 struct object_id peeled;
1769
1770 if (ref_iterator_peel(current_ref_iter, &peeled))
1771 return -1;
brian m. carlsonb420d902017-10-15 22:07:02 +00001772 oidcpy(oid, &peeled);
Michael Haggertyba1c0522017-09-25 10:00:14 +02001773 return 0;
1774 }
1775
1776 if (refs_read_ref_full(refs, refname,
brian m. carlson34c290a2017-10-15 22:06:56 +00001777 RESOLVE_REF_READING, &base, &flag))
Michael Haggertyba1c0522017-09-25 10:00:14 +02001778 return -1;
1779
brian m. carlsonac2ed0d2017-10-15 22:07:10 +00001780 return peel_object(&base, oid);
Ronnie Sahlberg127b42a2016-09-04 18:08:16 +02001781}
1782
brian m. carlsonb420d902017-10-15 22:07:02 +00001783int peel_ref(const char *refname, struct object_id *oid)
Michael Haggertybd427cf2016-09-04 18:08:29 +02001784{
brian m. carlsonb420d902017-10-15 22:07:02 +00001785 return refs_peel_ref(get_main_ref_store(), refname, oid);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001786}
Michael Haggertybd427cf2016-09-04 18:08:29 +02001787
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001788int refs_create_symref(struct ref_store *refs,
1789 const char *ref_target,
1790 const char *refs_heads_master,
1791 const char *logmsg)
1792{
1793 return refs->be->create_symref(refs, ref_target,
1794 refs_heads_master,
1795 logmsg);
Michael Haggertybd427cf2016-09-04 18:08:29 +02001796}
1797
Michael Haggerty284689b2016-09-04 18:08:28 +02001798int create_symref(const char *ref_target, const char *refs_heads_master,
1799 const char *logmsg)
1800{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001801 return refs_create_symref(get_main_ref_store(), ref_target,
1802 refs_heads_master, logmsg);
Michael Haggerty284689b2016-09-04 18:08:28 +02001803}
1804
Michael Haggerty2ced1052017-05-22 16:17:45 +02001805int ref_update_reject_duplicates(struct string_list *refnames,
1806 struct strbuf *err)
1807{
Michael Haggertya552e502017-05-22 16:17:46 +02001808 size_t i, n = refnames->nr;
Michael Haggerty2ced1052017-05-22 16:17:45 +02001809
1810 assert(err);
1811
Michael Haggerty8556f8d2017-05-22 16:17:47 +02001812 for (i = 1; i < n; i++) {
1813 int cmp = strcmp(refnames->items[i - 1].string,
1814 refnames->items[i].string);
1815
1816 if (!cmp) {
Michael Haggerty2ced1052017-05-22 16:17:45 +02001817 strbuf_addf(err,
1818 "multiple updates for ref '%s' not allowed.",
1819 refnames->items[i].string);
1820 return 1;
Michael Haggerty8556f8d2017-05-22 16:17:47 +02001821 } else if (cmp > 0) {
1822 die("BUG: ref_update_reject_duplicates() received unsorted list");
Michael Haggerty2ced1052017-05-22 16:17:45 +02001823 }
Michael Haggerty8556f8d2017-05-22 16:17:47 +02001824 }
Michael Haggerty2ced1052017-05-22 16:17:45 +02001825 return 0;
1826}
1827
Michael Haggerty30173b82017-05-22 16:17:44 +02001828int ref_transaction_prepare(struct ref_transaction *transaction,
1829 struct strbuf *err)
Daniel Barkalow95fc7512005-06-06 16:31:29 -04001830{
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07001831 struct ref_store *refs = transaction->ref_store;
Daniel Barkalow95fc7512005-06-06 16:31:29 -04001832
Michael Haggerty8d4240d2017-05-22 16:17:43 +02001833 switch (transaction->state) {
1834 case REF_TRANSACTION_OPEN:
1835 /* Good. */
1836 break;
Michael Haggerty30173b82017-05-22 16:17:44 +02001837 case REF_TRANSACTION_PREPARED:
1838 die("BUG: prepare called twice on reference transaction");
1839 break;
Michael Haggerty8d4240d2017-05-22 16:17:43 +02001840 case REF_TRANSACTION_CLOSED:
1841 die("BUG: prepare called on a closed reference transaction");
1842 break;
1843 default:
1844 die("BUG: unexpected reference transaction state");
1845 break;
1846 }
1847
Jeff Kingd8f44812017-04-10 18:14:12 -04001848 if (getenv(GIT_QUARANTINE_ENVIRONMENT)) {
1849 strbuf_addstr(err,
1850 _("ref updates forbidden inside quarantine environment"));
1851 return -1;
1852 }
1853
Michael Haggerty30173b82017-05-22 16:17:44 +02001854 return refs->be->transaction_prepare(refs, transaction, err);
1855}
1856
1857int ref_transaction_abort(struct ref_transaction *transaction,
1858 struct strbuf *err)
1859{
1860 struct ref_store *refs = transaction->ref_store;
1861 int ret = 0;
1862
1863 switch (transaction->state) {
1864 case REF_TRANSACTION_OPEN:
1865 /* No need to abort explicitly. */
1866 break;
1867 case REF_TRANSACTION_PREPARED:
1868 ret = refs->be->transaction_abort(refs, transaction, err);
1869 break;
1870 case REF_TRANSACTION_CLOSED:
1871 die("BUG: abort called on a closed reference transaction");
1872 break;
1873 default:
1874 die("BUG: unexpected reference transaction state");
1875 break;
1876 }
1877
1878 ref_transaction_free(transaction);
1879 return ret;
1880}
1881
1882int ref_transaction_commit(struct ref_transaction *transaction,
1883 struct strbuf *err)
1884{
1885 struct ref_store *refs = transaction->ref_store;
1886 int ret;
1887
1888 switch (transaction->state) {
1889 case REF_TRANSACTION_OPEN:
1890 /* Need to prepare first. */
1891 ret = ref_transaction_prepare(transaction, err);
1892 if (ret)
1893 return ret;
1894 break;
1895 case REF_TRANSACTION_PREPARED:
1896 /* Fall through to finish. */
1897 break;
1898 case REF_TRANSACTION_CLOSED:
1899 die("BUG: commit called on a closed reference transaction");
1900 break;
1901 default:
1902 die("BUG: unexpected reference transaction state");
1903 break;
1904 }
1905
1906 return refs->be->transaction_finish(refs, transaction, err);
Daniel Barkalow95fc7512005-06-06 16:31:29 -04001907}
Michael Haggerty62665822016-09-04 18:08:26 +02001908
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001909int refs_verify_refname_available(struct ref_store *refs,
1910 const char *refname,
Michael Haggertyb05855b2017-04-16 08:41:26 +02001911 const struct string_list *extras,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001912 const struct string_list *skip,
1913 struct strbuf *err)
Michael Haggerty62665822016-09-04 18:08:26 +02001914{
Michael Haggertyb05855b2017-04-16 08:41:26 +02001915 const char *slash;
1916 const char *extra_refname;
1917 struct strbuf dirname = STRBUF_INIT;
1918 struct strbuf referent = STRBUF_INIT;
1919 struct object_id oid;
1920 unsigned int type;
1921 struct ref_iterator *iter;
1922 int ok;
1923 int ret = -1;
1924
1925 /*
1926 * For the sake of comments in this function, suppose that
1927 * refname is "refs/foo/bar".
1928 */
1929
1930 assert(err);
1931
1932 strbuf_grow(&dirname, strlen(refname) + 1);
1933 for (slash = strchr(refname, '/'); slash; slash = strchr(slash + 1, '/')) {
1934 /* Expand dirname to the new prefix, not including the trailing slash: */
1935 strbuf_add(&dirname, refname + dirname.len, slash - refname - dirname.len);
1936
1937 /*
1938 * We are still at a leading dir of the refname (e.g.,
1939 * "refs/foo"; if there is a reference with that name,
1940 * it is a conflict, *unless* it is in skip.
1941 */
1942 if (skip && string_list_has_string(skip, dirname.buf))
1943 continue;
1944
brian m. carlson99afe912017-10-15 22:07:11 +00001945 if (!refs_read_raw_ref(refs, dirname.buf, &oid, &referent, &type)) {
Michael Haggertyb05855b2017-04-16 08:41:26 +02001946 strbuf_addf(err, "'%s' exists; cannot create '%s'",
1947 dirname.buf, refname);
1948 goto cleanup;
1949 }
1950
1951 if (extras && string_list_has_string(extras, dirname.buf)) {
1952 strbuf_addf(err, "cannot process '%s' and '%s' at the same time",
1953 refname, dirname.buf);
1954 goto cleanup;
1955 }
1956 }
1957
1958 /*
1959 * We are at the leaf of our refname (e.g., "refs/foo/bar").
1960 * There is no point in searching for a reference with that
1961 * name, because a refname isn't considered to conflict with
1962 * itself. But we still need to check for references whose
1963 * names are in the "refs/foo/bar/" namespace, because they
1964 * *do* conflict.
1965 */
1966 strbuf_addstr(&dirname, refname + dirname.len);
1967 strbuf_addch(&dirname, '/');
1968
1969 iter = refs_ref_iterator_begin(refs, dirname.buf, 0,
1970 DO_FOR_EACH_INCLUDE_BROKEN);
1971 while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
1972 if (skip &&
1973 string_list_has_string(skip, iter->refname))
1974 continue;
1975
1976 strbuf_addf(err, "'%s' exists; cannot create '%s'",
1977 iter->refname, refname);
1978 ref_iterator_abort(iter);
1979 goto cleanup;
1980 }
1981
1982 if (ok != ITER_DONE)
1983 die("BUG: error while iterating over references");
1984
1985 extra_refname = find_descendant_ref(dirname.buf, extras, skip);
1986 if (extra_refname)
1987 strbuf_addf(err, "cannot process '%s' and '%s' at the same time",
1988 refname, extra_refname);
1989 else
1990 ret = 0;
1991
1992cleanup:
1993 strbuf_release(&referent);
1994 strbuf_release(&dirname);
1995 return ret;
Michael Haggerty62665822016-09-04 18:08:26 +02001996}
David Turnere3688bd2016-09-04 18:08:38 +02001997
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07001998int refs_for_each_reflog(struct ref_store *refs, each_ref_fn fn, void *cb_data)
David Turnere3688bd2016-09-04 18:08:38 +02001999{
David Turnere3688bd2016-09-04 18:08:38 +02002000 struct ref_iterator *iter;
2001
2002 iter = refs->be->reflog_iterator_begin(refs);
2003
2004 return do_for_each_ref_iterator(iter, fn, cb_data);
2005}
2006
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002007int for_each_reflog(each_ref_fn fn, void *cb_data)
2008{
2009 return refs_for_each_reflog(get_main_ref_store(), fn, cb_data);
2010}
2011
2012int refs_for_each_reflog_ent_reverse(struct ref_store *refs,
2013 const char *refname,
2014 each_reflog_ent_fn fn,
2015 void *cb_data)
2016{
2017 return refs->be->for_each_reflog_ent_reverse(refs, refname,
2018 fn, cb_data);
2019}
2020
David Turnere3688bd2016-09-04 18:08:38 +02002021int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn,
2022 void *cb_data)
2023{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002024 return refs_for_each_reflog_ent_reverse(get_main_ref_store(),
2025 refname, fn, cb_data);
2026}
David Turnere3688bd2016-09-04 18:08:38 +02002027
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002028int refs_for_each_reflog_ent(struct ref_store *refs, const char *refname,
2029 each_reflog_ent_fn fn, void *cb_data)
2030{
2031 return refs->be->for_each_reflog_ent(refs, refname, fn, cb_data);
David Turnere3688bd2016-09-04 18:08:38 +02002032}
2033
2034int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn,
2035 void *cb_data)
2036{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002037 return refs_for_each_reflog_ent(get_main_ref_store(), refname,
2038 fn, cb_data);
2039}
David Turnere3688bd2016-09-04 18:08:38 +02002040
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002041int refs_reflog_exists(struct ref_store *refs, const char *refname)
2042{
2043 return refs->be->reflog_exists(refs, refname);
David Turnere3688bd2016-09-04 18:08:38 +02002044}
2045
2046int reflog_exists(const char *refname)
2047{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002048 return refs_reflog_exists(get_main_ref_store(), refname);
2049}
David Turnere3688bd2016-09-04 18:08:38 +02002050
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002051int refs_create_reflog(struct ref_store *refs, const char *refname,
2052 int force_create, struct strbuf *err)
2053{
2054 return refs->be->create_reflog(refs, refname, force_create, err);
David Turnere3688bd2016-09-04 18:08:38 +02002055}
2056
2057int safe_create_reflog(const char *refname, int force_create,
2058 struct strbuf *err)
2059{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002060 return refs_create_reflog(get_main_ref_store(), refname,
2061 force_create, err);
2062}
David Turnere3688bd2016-09-04 18:08:38 +02002063
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002064int refs_delete_reflog(struct ref_store *refs, const char *refname)
2065{
2066 return refs->be->delete_reflog(refs, refname);
David Turnere3688bd2016-09-04 18:08:38 +02002067}
2068
2069int delete_reflog(const char *refname)
2070{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002071 return refs_delete_reflog(get_main_ref_store(), refname);
2072}
David Turnere3688bd2016-09-04 18:08:38 +02002073
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002074int refs_reflog_expire(struct ref_store *refs,
brian m. carlson0155f712017-10-15 22:07:04 +00002075 const char *refname, const struct object_id *oid,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002076 unsigned int flags,
2077 reflog_expiry_prepare_fn prepare_fn,
2078 reflog_expiry_should_prune_fn should_prune_fn,
2079 reflog_expiry_cleanup_fn cleanup_fn,
2080 void *policy_cb_data)
2081{
brian m. carlson0155f712017-10-15 22:07:04 +00002082 return refs->be->reflog_expire(refs, refname, oid, flags,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002083 prepare_fn, should_prune_fn,
2084 cleanup_fn, policy_cb_data);
David Turnere3688bd2016-09-04 18:08:38 +02002085}
2086
brian m. carlson0155f712017-10-15 22:07:04 +00002087int reflog_expire(const char *refname, const struct object_id *oid,
David Turnere3688bd2016-09-04 18:08:38 +02002088 unsigned int flags,
2089 reflog_expiry_prepare_fn prepare_fn,
2090 reflog_expiry_should_prune_fn should_prune_fn,
2091 reflog_expiry_cleanup_fn cleanup_fn,
2092 void *policy_cb_data)
2093{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002094 return refs_reflog_expire(get_main_ref_store(),
brian m. carlson0155f712017-10-15 22:07:04 +00002095 refname, oid, flags,
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002096 prepare_fn, should_prune_fn,
2097 cleanup_fn, policy_cb_data);
David Turnere3688bd2016-09-04 18:08:38 +02002098}
David Turnerfc681462016-09-04 18:08:39 +02002099
2100int initial_ref_transaction_commit(struct ref_transaction *transaction,
2101 struct strbuf *err)
2102{
Nguyễn Thái Ngọc Duyc0fe4e82017-03-26 09:42:35 +07002103 struct ref_store *refs = transaction->ref_store;
David Turnerfc681462016-09-04 18:08:39 +02002104
2105 return refs->be->initial_transaction_commit(refs, transaction, err);
2106}
David Turnera27dcf82016-09-04 18:08:40 +02002107
Michael Haggerty64da4192017-05-22 16:17:38 +02002108int refs_delete_refs(struct ref_store *refs, const char *msg,
2109 struct string_list *refnames, unsigned int flags)
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002110{
Michael Haggerty64da4192017-05-22 16:17:38 +02002111 return refs->be->delete_refs(refs, msg, refnames, flags);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002112}
2113
Michael Haggerty64da4192017-05-22 16:17:38 +02002114int delete_refs(const char *msg, struct string_list *refnames,
2115 unsigned int flags)
David Turnera27dcf82016-09-04 18:08:40 +02002116{
Michael Haggerty64da4192017-05-22 16:17:38 +02002117 return refs_delete_refs(get_main_ref_store(), msg, refnames, flags);
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002118}
David Turnera27dcf82016-09-04 18:08:40 +02002119
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002120int refs_rename_ref(struct ref_store *refs, const char *oldref,
2121 const char *newref, const char *logmsg)
2122{
2123 return refs->be->rename_ref(refs, oldref, newref, logmsg);
David Turnera27dcf82016-09-04 18:08:40 +02002124}
David Turner9b6b40d2016-09-04 18:08:42 +02002125
2126int rename_ref(const char *oldref, const char *newref, const char *logmsg)
2127{
Nguyễn Thái Ngọc Duy7d2df052017-03-26 09:42:34 +07002128 return refs_rename_ref(get_main_ref_store(), oldref, newref, logmsg);
David Turner9b6b40d2016-09-04 18:08:42 +02002129}
Sahil Dua52d59cc2017-06-18 23:19:16 +02002130
2131int refs_copy_existing_ref(struct ref_store *refs, const char *oldref,
2132 const char *newref, const char *logmsg)
2133{
2134 return refs->be->copy_ref(refs, oldref, newref, logmsg);
2135}
2136
2137int copy_existing_ref(const char *oldref, const char *newref, const char *logmsg)
2138{
2139 return refs_copy_existing_ref(get_main_ref_store(), oldref, newref, logmsg);
2140}