refactor "ref->merge" flag
Each "struct ref" has a boolean flag that is set by the fetch code to determine whether the ref should be marked as "not-for-merge" or not when we write it out to FETCH_HEAD. It would be useful to turn this boolean into a tri-state, with the third state meaning "do not bother writing it out to FETCH_HEAD at all". That would let us add extra refs to the set of refs to be stored (e.g., to store copies of things we fetched) without impacting FETCH_HEAD. This patch turns it into an enum that covers the tri-state case, and hopefully makes the code more explicit and easier to read. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committed
May 11, 2013 at 18:15 UTC
900f2814b8da951a450f5762dabb1b248dd77abc
2 files changed
+48
-23
builtin/fetch.c
+35
-22
@@ -119,7 +119,7 @@ static void add_merge_config(struct ref **head,
119
120
for (rm = *head; rm; rm = rm->next) {
121
if (branch_merge_matches(branch, i, rm->name)) {
122
- rm->merge = 1;
122
+ rm->fetch_head_status = FETCH_HEAD_MERGE;
123
break;
124
}
125
}
@@ -140,7 +140,7 @@ static void add_merge_config(struct ref **head,
140
refspec.src = branch->merge[i]->src;
141
get_fetch_map(remote_refs, &refspec, tail, 1);
142
for (rm = *old_tail; rm; rm = rm->next)
143
- rm->merge = 1;
143
+ rm->fetch_head_status = FETCH_HEAD_MERGE;
144
}
145
}
146
@@ -167,7 +167,7 @@ static struct ref *get_ref_map(struct transport *transport,
167
}
168
/* Merge everything on the command line, but not --tags */
169
for (rm = ref_map; rm; rm = rm->next)
170
- rm->merge = 1;
170
+ rm->fetch_head_status = FETCH_HEAD_MERGE;
171
if (tags == TAGS_SET)
172
get_fetch_map(remote_refs, tag_refspec, &tail, 0);
173
} else {
@@ -186,7 +186,7 @@ static struct ref *get_ref_map(struct transport *transport,
186
*autotags = 1;
187
if (!i && !has_merge && ref_map &&
188
!remote->fetch[0].pattern)
189
- ref_map->merge = 1;
189
+ ref_map->fetch_head_status = FETCH_HEAD_MERGE;
190
}
191
/*
192
* if the remote we're fetching from is the same
@@ -202,7 +202,7 @@ static struct ref *get_ref_map(struct transport *transport,
202
ref_map = get_remote_ref(remote_refs, "HEAD");
203
if (!ref_map)
204
die(_("Couldn't find remote ref HEAD"));
205
- ref_map->merge = 1;
205
+ ref_map->fetch_head_status = FETCH_HEAD_MERGE;
206
tail = &ref_map->next;
207
}
208
}
@@ -389,7 +389,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
389
const char *what, *kind;
390
struct ref *rm;
391
char *url, *filename = dry_run ? "/dev/null" : git_path("FETCH_HEAD");
392
- int want_merge;
392
+ int want_status;
393
394
fp = fopen(filename, "a");
395
if (!fp)
@@ -407,19 +407,22 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
407
}
408
409
/*
410
- * The first pass writes objects to be merged and then the
411
- * second pass writes the rest, in order to allow using
412
- * FETCH_HEAD as a refname to refer to the ref to be merged.
410
+ * We do a pass for each fetch_head_status type in their enum order, so
411
+ * merged entries are written before not-for-merge. That lets readers
412
+ * use FETCH_HEAD as a refname to refer to the ref to be merged.
413
*/
414
- for (want_merge = 1; 0 <= want_merge; want_merge--) {
414
+ for (want_status = FETCH_HEAD_MERGE;
415
+ want_status <= FETCH_HEAD_IGNORE;
416
+ want_status++) {
417
for (rm = ref_map; rm; rm = rm->next) {
418
struct ref *ref = NULL;
419
+ const char *merge_status_marker = "";
420
421
commit = lookup_commit_reference_gently(rm->old_sha1, 1);
422
if (!commit)
420
- rm->merge = 0;
423
+ rm->fetch_head_status = FETCH_HEAD_NOT_FOR_MERGE;
424
422
- if (rm->merge != want_merge)
425
+ if (rm->fetch_head_status != want_status)
426
continue;
427
428
if (rm->peer_ref) {
@@ -465,16 +468,26 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
468
strbuf_addf(¬e, "%s ", kind);
469
strbuf_addf(¬e, "'%s' of ", what);
470
}
468
- fprintf(fp, "%s\t%s\t%s",
469
- sha1_to_hex(rm->old_sha1),
470
- rm->merge ? "" : "not-for-merge",
471
- note.buf);
472
- for (i = 0; i < url_len; ++i)
473
- if ('\n' == url[i])
474
- fputs("\\n", fp);
475
- else
476
- fputc(url[i], fp);
477
- fputc('\n', fp);
471
+ switch (rm->fetch_head_status) {
472
+ case FETCH_HEAD_NOT_FOR_MERGE:
473
+ merge_status_marker = "not-for-merge";
474
+ /* fall-through */
475
+ case FETCH_HEAD_MERGE:
476
+ fprintf(fp, "%s\t%s\t%s",
477
+ sha1_to_hex(rm->old_sha1),
478
+ merge_status_marker,
479
+ note.buf);
480
+ for (i = 0; i < url_len; ++i)
481
+ if ('\n' == url[i])
482
+ fputs("\\n", fp);
483
+ else
484
+ fputc(url[i], fp);
485
+ fputc('\n', fp);
486
+ break;
487
+ default:
488
+ /* do not write anything to FETCH_HEAD */
489
+ break;
490
+ }
491
492
strbuf_reset(¬e);
493
if (ref) {
cache.h
+13
-1
@@ -1024,9 +1024,21 @@ struct ref {
1024
unsigned int
1025
force:1,
1026
forced_update:1,
1027
- merge:1,
1027
deletion:1,
1028
matched:1;
1029
+
1030
+ /*
1031
+ * Order is important here, as we write to FETCH_HEAD
1032
+ * in numeric order. And the default NOT_FOR_MERGE
1033
+ * should be 0, so that xcalloc'd structures get it
1034
+ * by default.
1035
+ */
1036
+ enum {
1037
+ FETCH_HEAD_MERGE = -1,
1038
+ FETCH_HEAD_NOT_FOR_MERGE = 0,
1039
+ FETCH_HEAD_IGNORE = 1
1040
+ } fetch_head_status;
1041
+
1042
enum {
1043
REF_STATUS_NONE = 0,
1044
REF_STATUS_OK,