Code

Check early that a new branch is new and valid
authorDaniel Barkalow <barkalow@iabervon.org>
Sun, 21 Sep 2008 18:36:06 +0000 (14:36 -0400)
committerJunio C Hamano <gitster@pobox.com>
Mon, 22 Sep 2008 06:17:06 +0000 (23:17 -0700)
If you fail to update refs to change branches in checkout, your index
and working tree are left already updated. We don't have an easy way
to undo this, but at least we can check things that would make the
creation of a new branch fail. These checks were in the shell version,
and were lost in the C conversion.

The messages are from the shell version, and should probably be made nicer.

[jc: added test to t7201]

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-checkout.c
t/t7201-co.sh

index 08c6d8614ae2b619f520616fecd45b24fd866732..1ee23468ff27de8f8d35c15ce6b10ac11995c0f9 100644 (file)
@@ -565,6 +565,18 @@ no_reference:
                return checkout_paths(source_tree, pathspec);
        }
 
+       if (opts.new_branch) {
+               struct strbuf buf;
+               strbuf_init(&buf, 0);
+               strbuf_addstr(&buf, "refs/heads/");
+               strbuf_addstr(&buf, opts.new_branch);
+               if (!get_sha1(buf.buf, rev))
+                       die("git checkout: branch %s already exists", opts.new_branch);
+               if (check_ref_format(buf.buf))
+                       die("git checkout: we do not like '%s' as a branch name.", opts.new_branch);
+               strbuf_release(&buf);
+       }
+
        if (new.name && !new.commit) {
                die("Cannot switch branch to a non-commit.");
        }
index fbec70d3c6abff4a97aa205aa10fbf6fe336fa5f..0679abd29d907944c5c246275adfcd760f001d55 100755 (executable)
@@ -359,4 +359,14 @@ test_expect_success 'checkout an unmerged path should fail' '
        test_cmp sample file
 '
 
+test_expect_success 'failing checkout -b should not break working tree' '
+       git reset --hard master &&
+       git symbolic-ref HEAD refs/heads/master &&
+       test_must_fail git checkout -b renamer side^ &&
+       test $(git symbolic-ref HEAD) = refs/heads/master &&
+       git diff --exit-code &&
+       git diff --cached --exit-code
+
+'
+
 test_done