I have a tree where for some reason HEAD was pointing to an invalid commit. I'm not sure how this happened, but git checkout should be able to recover from that situation without crashing. Signed-off-by: Alexandre Julliard <julliard@xxxxxxxxxx> --- builtin-checkout.c | 14 +++++++++----- t/t2011-checkout-invalid-head.sh | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) create mode 100755 t/t2011-checkout-invalid-head.sh diff --git a/builtin-checkout.c b/builtin-checkout.c index 57b94d2..7c1b8cd 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -47,7 +47,8 @@ static int post_checkout_hook(struct commit *old, struct commit *new, memset(&proc, 0, sizeof(proc)); argv[0] = name; - argv[1] = xstrdup(sha1_to_hex(old->object.sha1)); + argv[1] = old ? xstrdup(sha1_to_hex(old->object.sha1)) + : "0000000000000000000000000000000000000000"; argv[2] = xstrdup(sha1_to_hex(new->object.sha1)); argv[3] = changed ? "1" : "0"; argv[4] = NULL; @@ -492,10 +493,13 @@ static void update_refs_for_switch(struct checkout_opts *opts, } old_desc = old->name; - if (!old_desc) + if (!old_desc && old->commit) old_desc = sha1_to_hex(old->commit->object.sha1); - strbuf_addf(&msg, "checkout: moving from %s to %s", - old_desc, new->name); + if (old_desc) + strbuf_addf(&msg, "checkout: moving from %s to %s", + old_desc, new->name); + else + strbuf_addf(&msg, "checkout: moving to %s", new->name); if (new->path) { create_symref("HEAD", new->path, msg.buf); @@ -551,7 +555,7 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new) * a new commit, we want to mention the old commit once more * to remind the user that it might be lost. */ - if (!opts->quiet && !old.path && new->commit != old.commit) + if (!opts->quiet && !old.path && old.commit && new->commit != old.commit) describe_detached_head("Previous HEAD position was", old.commit); if (!old.commit) { diff --git a/t/t2011-checkout-invalid-head.sh b/t/t2011-checkout-invalid-head.sh new file mode 100755 index 0000000..764bb0a --- /dev/null +++ b/t/t2011-checkout-invalid-head.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +test_description='checkout switching away from an invalid branch' + +. ./test-lib.sh + +test_expect_success 'setup' ' + echo hello >world && + git add world && + git commit -m initial +' + +test_expect_success 'checkout master from invalid HEAD' ' + echo 0000000000000000000000000000000000000000 >.git/HEAD && + git checkout master -- +' + +test_done -- 1.6.0.3.669.g76740 -- Alexandre Julliard julliard@xxxxxxxxxx -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html