Skip to content

Commit cc580af

Browse files
peffgitster
authored andcommitted
checkout: do not imply "-f" on unborn branches
When checkout sees that HEAD points to a non-existent ref, it currently acts as if "-f" was given; this behavior dates back to 5a03e7f, which enabled checkout from unborn branches in the shell version of "git-checkout". The reasoning given is to avoid the code path which tries to merge the tree contents. When checkout was converted to C, this code remained intact. The unfortunate side effect of this strategy is that the "force" code path will overwrite working tree and index state that may be precious to the user. Instead of enabling "force", this patch uses the normal "merge" codepath for an unborn branch, but substitutes the empty tree for the "old" commit. This means that in the absence of an index, any files in the working tree will be treated as untracked files, and a checkout which would overwrite them is aborted. Similarly, any paths in the index will be merged with an empty entry as the base, meaning that unless the new branch's content is identical to what's in the index, there will be a conflict and the checkout will be aborted. The user is then free to correct the situation or proceed with "-f" as appropriate. This patch also removes the "warning: you are on a branch yet to be born" message. Its function was to warn the user that we were enabling the "-f" option. Since we are no longer doing that, there is no reason for the user to care whether we are switching away from an unborn branch. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 57f6ec0 commit cc580af

File tree

2 files changed

+43
-9
lines changed

2 files changed

+43
-9
lines changed

builtin-checkout.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,9 @@ static int merge_working_tree(struct checkout_opts *opts,
402402
topts.dir = xcalloc(1, sizeof(*topts.dir));
403403
topts.dir->flags |= DIR_SHOW_IGNORED;
404404
topts.dir->exclude_per_dir = ".gitignore";
405-
tree = parse_tree_indirect(old->commit->object.sha1);
405+
tree = parse_tree_indirect(old->commit ?
406+
old->commit->object.sha1 :
407+
(unsigned char *)EMPTY_TREE_SHA1_BIN);
406408
init_tree_desc(&trees[0], tree->buffer, tree->size);
407409
tree = parse_tree_indirect(new->commit->object.sha1);
408410
init_tree_desc(&trees[1], tree->buffer, tree->size);
@@ -541,14 +543,6 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
541543
parse_commit(new->commit);
542544
}
543545

544-
if (!old.commit && !opts->force) {
545-
if (!opts->quiet) {
546-
warning("You appear to be on a branch yet to be born.");
547-
warning("Forcing checkout of %s.", new->name);
548-
}
549-
opts->force = 1;
550-
}
551-
552546
ret = merge_working_tree(opts, &old, new);
553547
if (ret)
554548
return ret;

t/t2015-checkout-unborn.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/sh
2+
3+
test_description='checkout from unborn branch protects contents'
4+
. ./test-lib.sh
5+
6+
test_expect_success 'setup' '
7+
mkdir parent &&
8+
(cd parent &&
9+
git init &&
10+
echo content >file &&
11+
git add file &&
12+
git commit -m base
13+
) &&
14+
git fetch parent master:origin
15+
'
16+
17+
test_expect_success 'checkout from unborn preserves untracked files' '
18+
echo precious >expect &&
19+
echo precious >file &&
20+
test_must_fail git checkout -b new origin &&
21+
test_cmp expect file
22+
'
23+
24+
test_expect_success 'checkout from unborn preserves index contents' '
25+
echo precious >expect &&
26+
echo precious >file &&
27+
git add file &&
28+
test_must_fail git checkout -b new origin &&
29+
test_cmp expect file &&
30+
git show :file >file &&
31+
test_cmp expect file
32+
'
33+
34+
test_expect_success 'checkout from unborn merges identical index contents' '
35+
echo content >file &&
36+
git add file &&
37+
git checkout -b new origin
38+
'
39+
40+
test_done

0 commit comments

Comments
 (0)