@matheusbsbs / matheus-bagliano / commits / 21b5b1e8dc
Fork 0

branch/checkout --track: Ensure that upstream branch is indeed a branch

When creating a new branch using the --track option, we must make sure that we don't try to set an upstream that does not make sense to follow (using 'git pull') or update (using 'git push'). The current code checks against using HEAD as upstream (since tracking a symref doesn't make sense). However, tracking a tag doesn't make sense either. Indeed, tracking _any_ ref that is not a (local or remote) branch doesn't make sense, and should be disallowed. This patch achieves this by checking that the ref we're trying to --track resides within refs/heads/* or refs/remotes/*. This new check replaces the previous check against HEAD. A couple of testcases are also added, verifying that we cannot create branches with tags as upstreams. Finally, some selftests relying on using a non-branch as an upstream have been reworked or removed: - t6040: Reverse the meaning of two tests that depend on the ability to use (lightweight and annotated) tags as upstreams. These two tests were originally added in commits 1be570f and 57ffc5f, and this patch reverts the intention of those two commits. - t7201: Remove part of a test (introduced in 9188ed8) relying on a non-branch as upstream. Signed-off-by: Johan Herland <johan@herland.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johan Herland committed Feb 17, 2011 at 00:12 UTC 21b5b1e8dc9bed2b518defe29d69ebc27da4b68f
4 files changed +39 -18
branch.c
+8 -3
@@ -175,9 +175,14 @@ void create_branch(const char *head,
175 die("Cannot setup tracking information; starting point is not a branch.");
176 break;
177 case 1:
178 - /* Unique completion -- good, only if it is a real ref */
179 - if (explicit_tracking && !strcmp(real_ref, "HEAD"))
180 - die("Cannot setup tracking information; starting point is not a branch.");
178 + /* Unique completion -- good, only if it is a real branch */
179 + if (prefixcmp(real_ref, "refs/heads/") &&
180 + prefixcmp(real_ref, "refs/remotes/")) {
181 + if (explicit_tracking)
182 + die("Cannot setup tracking information; starting point is not a branch.");
183 + else
184 + real_ref = NULL;
185 + }
186 break;
187 default:
188 die("Ambiguous object name: '%s'.", start_name);
t/t3200-branch.sh
+14
@@ -212,6 +212,11 @@ test_expect_success \
212 'branch from non-branch HEAD w/--track causes failure' \
213 'test_must_fail git branch --track my10 HEAD^'
214
215 +test_expect_success \
216 + 'branch from tag w/--track causes failure' \
217 + 'git tag foobar &&
218 + test_must_fail git branch --track my11 foobar'
219 +
220 # Keep this test last, as it changes the current branch
221 cat >expect <<EOF
222 0000000000000000000000000000000000000000 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master
@@ -477,6 +482,15 @@ test_expect_success 'autosetuprebase always on an untracked remote branch' '
482 test "z$(git config branch.myr20.rebase)" = z
483 '
484
485 +test_expect_success 'autosetuprebase always on detached HEAD' '
486 + git config branch.autosetupmerge always &&
487 + test_when_finished git checkout master &&
488 + git checkout HEAD^0 &&
489 + git branch my11 &&
490 + test -z "$(git config branch.my11.remote)" &&
491 + test -z "$(git config branch.my11.merge)"
492 +'
493 +
494 test_expect_success 'detect misconfigured autosetuprebase (bad value)' '
495 git config branch.autosetuprebase garbage &&
496 test_must_fail git branch
t/t6040-tracking-info.sh
+8 -8
@@ -74,20 +74,20 @@ test_expect_success 'status' '
74 grep "have 1 and 1 different" actual
75 '
76
77 -test_expect_success 'status when tracking lightweight tags' '
77 +test_expect_success 'fail to track lightweight tags' '
78 git checkout master &&
79 git tag light &&
80 - git branch --track lighttrack light >actual &&
81 - grep "set up to track" actual &&
82 - git checkout lighttrack
80 + test_must_fail git branch --track lighttrack light >actual &&
81 + test_must_fail grep "set up to track" actual &&
82 + test_must_fail git checkout lighttrack
83 '
84
85 -test_expect_success 'status when tracking annotated tags' '
85 +test_expect_success 'fail to track annotated tags' '
86 git checkout master &&
87 git tag -m heavy heavy &&
88 - git branch --track heavytrack heavy >actual &&
89 - grep "set up to track" actual &&
90 - git checkout heavytrack
88 + test_must_fail git branch --track heavytrack heavy >actual &&
89 + test_must_fail grep "set up to track" actual &&
90 + test_must_fail git checkout heavytrack
91 '
92
93 test_expect_success 'setup tracking with branch --set-upstream on existing branch' '
t/t7201-co.sh
+9 -7
@@ -408,6 +408,15 @@ test_expect_success 'checkout w/--track from non-branch HEAD fails' '
408 test "z$(git rev-parse master^0)" = "z$(git rev-parse HEAD)"
409 '
410
411 +test_expect_success 'checkout w/--track from tag fails' '
412 + git checkout master^0 &&
413 + test_must_fail git symbolic-ref HEAD &&
414 + test_must_fail git checkout --track -b track frotz &&
415 + test_must_fail git rev-parse --verify track &&
416 + test_must_fail git symbolic-ref HEAD &&
417 + test "z$(git rev-parse master^0)" = "z$(git rev-parse HEAD)"
418 +'
419 +
420 test_expect_success 'detach a symbolic link HEAD' '
421 git checkout master &&
422 git config --bool core.prefersymlinkrefs yes &&
@@ -423,7 +432,6 @@ test_expect_success 'detach a symbolic link HEAD' '
432 test_expect_success \
433 'checkout with --track fakes a sensible -b <name>' '
434 git update-ref refs/remotes/origin/koala/bear renamer &&
426 - git update-ref refs/new/koala/bear renamer &&
435
436 git checkout --track origin/koala/bear &&
437 test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
@@ -439,12 +447,6 @@ test_expect_success \
447
448 git checkout --track remotes/origin/koala/bear &&
449 test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
442 - test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
443 -
444 - git checkout master && git branch -D koala/bear &&
445 -
446 - git checkout --track refs/new/koala/bear &&
447 - test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
450 test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)"
451 '
452