Skip to content

Commit 323e00f

Browse files
julliardgitster
authored andcommitted
checkout: Don't crash when switching away from an invalid branch.
When using alternates, it is possible for HEAD to end up pointing to an invalid commit. git checkout should be able to recover from that situation without crashing. Signed-off-by: Alexandre Julliard <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7c181d6 commit 323e00f

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

builtin-checkout.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static int post_checkout_hook(struct commit *old, struct commit *new,
3232

3333
memset(&proc, 0, sizeof(proc));
3434
argv[0] = name;
35-
argv[1] = xstrdup(sha1_to_hex(old->object.sha1));
35+
argv[1] = xstrdup(sha1_to_hex(old ? old->object.sha1 : null_sha1));
3636
argv[2] = xstrdup(sha1_to_hex(new->object.sha1));
3737
argv[3] = changed ? "1" : "0";
3838
argv[4] = NULL;
@@ -360,10 +360,10 @@ static void update_refs_for_switch(struct checkout_opts *opts,
360360

361361
strbuf_init(&msg, 0);
362362
old_desc = old->name;
363-
if (!old_desc)
363+
if (!old_desc && old->commit)
364364
old_desc = sha1_to_hex(old->commit->object.sha1);
365365
strbuf_addf(&msg, "checkout: moving from %s to %s",
366-
old_desc, new->name);
366+
old_desc ? old_desc : "(invalid)", new->name);
367367

368368
if (new->path) {
369369
create_symref("HEAD", new->path, msg.buf);
@@ -419,7 +419,7 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
419419
* a new commit, we want to mention the old commit once more
420420
* to remind the user that it might be lost.
421421
*/
422-
if (!opts->quiet && !old.path && new->commit != old.commit)
422+
if (!opts->quiet && !old.path && old.commit && new->commit != old.commit)
423423
describe_detached_head("Previous HEAD position was", old.commit);
424424

425425
if (!old.commit) {

t/t2011-checkout-invalid-head.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/sh
2+
3+
test_description='checkout switching away from an invalid branch'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success 'setup' '
8+
echo hello >world &&
9+
git add world &&
10+
git commit -m initial
11+
'
12+
13+
test_expect_success 'checkout master from invalid HEAD' '
14+
echo 0000000000000000000000000000000000000000 >.git/HEAD &&
15+
git checkout master --
16+
'
17+
18+
test_done

0 commit comments

Comments
 (0)