@matheusbsbs / matheus-bagliano / commits / 323e00fd46
Fork 0

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 <julliard@winehq.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Alexandre Julliard committed Nov 8, 2008 at 13:03 UTC 323e00fd46afb9293b25ee85f061ce11a2f95ca6
2 files changed +22 -4
builtin-checkout.c
+4 -4
@@ -32,7 +32,7 @@ static int post_checkout_hook(struct commit *old, struct commit *new,
32
33 memset(&proc, 0, sizeof(proc));
34 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));
36 argv[2] = xstrdup(sha1_to_hex(new->object.sha1));
37 argv[3] = changed ? "1" : "0";
38 argv[4] = NULL;
@@ -360,10 +360,10 @@ static void update_refs_for_switch(struct checkout_opts *opts,
360
361 strbuf_init(&msg, 0);
362 old_desc = old->name;
363 - if (!old_desc)
363 + if (!old_desc && old->commit)
364 old_desc = sha1_to_hex(old->commit->object.sha1);
365 strbuf_addf(&msg, "checkout: moving from %s to %s",
366 - old_desc, new->name);
366 + old_desc ? old_desc : "(invalid)", new->name);
367
368 if (new->path) {
369 create_symref("HEAD", new->path, msg.buf);
@@ -419,7 +419,7 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
419 * a new commit, we want to mention the old commit once more
420 * to remind the user that it might be lost.
421 */
422 - if (!opts->quiet && !old.path && new->commit != old.commit)
422 + if (!opts->quiet && !old.path && old.commit && new->commit != old.commit)
423 describe_detached_head("Previous HEAD position was", old.commit);
424
425 if (!old.commit) {
t/t2011-checkout-invalid-head.sh new
+18
@@ -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