@matheusbsbs / matheus-bagliano / commits / 9f0ea7e828
Fork 0

Resolve value supplied for no-colon push refspecs

When pushing a refspec like "HEAD", we used to treat it as "HEAD:HEAD", which didn't work without rewriting. Instead, we should resolve the ref. If it's a symref, further require it to point to a branch, to avoid doing anything especially unexpected. Also remove the rewriting previously added in builtin-push. Since the code for "HEAD" uses the regular refspec parsing, it automatically handles "+HEAD" without anything special. [jc: added a further test to make sure that "remote.*.push = HEAD" works] Signed-off-by: Daniel Barkalow <barkalow@iabervon.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Daniel Barkalow committed Feb 20, 2008 at 12:54 UTC 9f0ea7e8283da126c8e1d5e0c3b39c39200258ad
3 files changed +52 -10
builtin-push.c
-9
@@ -44,15 +44,6 @@ static void set_refspecs(const char **refs, int nr)
44 strcat(tag, refs[i]);
45 ref = tag;
46 }
47 - if (!strcmp("HEAD", ref)) {
48 - unsigned char sha1_dummy[20];
49 - ref = resolve_ref(ref, sha1_dummy, 1, NULL);
50 - if (!ref)
51 - die("HEAD cannot be resolved.");
52 - if (prefixcmp(ref, "refs/heads/"))
53 - die("HEAD cannot be resolved to branch.");
54 - ref = xstrdup(ref + 11);
55 - }
47 add_refspec(ref);
48 }
49 }
remote.c
+9 -1
@@ -643,9 +643,17 @@ static int match_explicit(struct ref *src, struct ref *dst,
643 errs = 1;
644
645 if (!dst_value) {
646 + unsigned char sha1[20];
647 + int flag;
648 +
649 if (!matched_src)
650 return errs;
648 - dst_value = matched_src->name;
651 + dst_value = resolve_ref(matched_src->name, sha1, 1, &flag);
652 + if (!dst_value ||
653 + ((flag & REF_ISSYMREF) &&
654 + prefixcmp(dst_value, "refs/heads/")))
655 + die("%s cannot be resolved to branch.",
656 + matched_src->name);
657 }
658
659 switch (count_refspec_match(dst_value, dst, &matched_dst)) {
t/t5516-fetch-push.sh
+43
@@ -271,6 +271,49 @@ test_expect_success 'push with HEAD nonexisting at remote' '
271 check_push_result $the_commit heads/local
272 '
273
274 +test_expect_success 'push with +HEAD' '
275 +
276 + mk_test heads/master &&
277 + git checkout master &&
278 + git branch -D local &&
279 + git checkout -b local &&
280 + git push testrepo master local &&
281 + check_push_result $the_commit heads/master &&
282 + check_push_result $the_commit heads/local &&
283 +
284 + # Without force rewinding should fail
285 + git reset --hard HEAD^ &&
286 + ! git push testrepo HEAD &&
287 + check_push_result $the_commit heads/local &&
288 +
289 + # With force rewinding should succeed
290 + git push testrepo +HEAD &&
291 + check_push_result $the_first_commit heads/local
292 +
293 +'
294 +
295 +test_expect_success 'push with config remote.*.push = HEAD' '
296 +
297 + mk_test heads/local &&
298 + git checkout master &&
299 + git branch -f local $the_commit &&
300 + (
301 + cd testrepo &&
302 + git checkout local &&
303 + git reset --hard $the_first_commit
304 + ) &&
305 + git config remote.there.url testrepo &&
306 + git config remote.there.push HEAD &&
307 + git config branch.master.remote there &&
308 + git push &&
309 + check_push_result $the_commit heads/master &&
310 + check_push_result $the_first_commit heads/local
311 +'
312 +
313 +# clean up the cruft left with the previous one
314 +git config --remove-section remote.there
315 +git config --remove-section branch.master
316 +
317 test_expect_success 'push with dry-run' '
318
319 mk_test heads/master &&