refs: loosen over-strict "format" check

The add_extra_ref() interface is used to add an extra-ref that is _not_ our ref for the purpose of helping auto-following of tags and reducing object transfer from remote repository, and they are typically formatted as a tagname followed by ^{} to make sure no valid refs match that pattern. In other words, these entries are deliberately formatted not to pass check-refname-format test. A recent series however added a test unconditionally to the add_ref() function that is called from add_extra_ref(). The check may be sensible for other two callsites of the add_ref() interface, but definitely is a wrong thing to do in add_extra_ref(). Disable it. Signed-off-by: Junio C Hamano <gitster@pobox.com> Acked-by: Michael Haggerty <mhagger@alum.mit.edu>

Junio C Hamano committed Nov 16, 2011 at 16:54 UTC 09116a1c31e3754cb18bb69ef057342cd7808935
2 files changed +17 -10
refs.c
+10 -10
@@ -48,7 +48,7 @@ static const char *parse_ref_line(char *line, unsigned char *sha1)
48 }
49
50 static void add_ref(const char *name, const unsigned char *sha1,
51 - int flag, struct ref_array *refs,
51 + int flag, int check_name, struct ref_array *refs,
52 struct ref_entry **new_entry)
53 {
54 int len;
@@ -59,7 +59,8 @@ static void add_ref(const char *name, const unsigned char *sha1,
59 entry = xmalloc(sizeof(struct ref_entry) + len);
60 hashcpy(entry->sha1, sha1);
61 hashclr(entry->peeled);
62 - if (check_refname_format(name, REFNAME_ALLOW_ONELEVEL|REFNAME_DOT_COMPONENT))
62 + if (check_name &&
63 + check_refname_format(name, REFNAME_ALLOW_ONELEVEL|REFNAME_DOT_COMPONENT))
64 die("Reference has invalid format: '%s'", name);
65 memcpy(entry->name, name, len);
66 entry->flag = flag;
@@ -234,7 +235,7 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
235
236 name = parse_ref_line(refline, sha1);
237 if (name) {
237 - add_ref(name, sha1, flag, array, &last);
238 + add_ref(name, sha1, flag, 1, array, &last);
239 continue;
240 }
241 if (last &&
@@ -249,7 +250,7 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
250
251 void add_extra_ref(const char *name, const unsigned char *sha1, int flag)
252 {
252 - add_ref(name, sha1, flag, &extra_refs, NULL);
253 + add_ref(name, sha1, flag, 0, &extra_refs, NULL);
254 }
255
256 void clear_extra_refs(void)
@@ -333,12 +334,11 @@ static void get_ref_dir(const char *submodule, const char *base,
334 hashclr(sha1);
335 flag |= REF_ISBROKEN;
336 }
336 - } else
337 - if (!resolve_ref(ref, sha1, 1, &flag)) {
338 - hashclr(sha1);
339 - flag |= REF_ISBROKEN;
340 - }
341 - add_ref(ref, sha1, flag, array, NULL);
337 + } else if (!resolve_ref(ref, sha1, 1, &flag)) {
338 + hashclr(sha1);
339 + flag |= REF_ISBROKEN;
340 + }
341 + add_ref(ref, sha1, flag, 1, array, NULL);
342 }
343 free(ref);
344 closedir(dir);
t/t5700-clone-reference.sh
+7
@@ -146,4 +146,11 @@ test_expect_success 'cloning with reference being subset of source (-l -s)' \
146
147 cd "$base_dir"
148
149 +test_expect_success 'clone with reference from a tagged repository' '
150 + (
151 + cd A && git tag -a -m 'tagged' HEAD
152 + ) &&
153 + git clone --reference=A A I
154 +'
155 +
156 test_done