{"thread":{"id":"16227","subject":"[PATCH] checkout: Don't crash when switching away from an invalid branch.","startedAt":"2008-11-08T12:03:59Z","lastAt":"2008-11-08T12:03:59Z","messageCount":1,"participants":["Alexandre Julliard"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"95212","messageId":"87fxm2a0gg.fsf@wine.dyndns.org","threadId":"16227","inReplyTo":null,"subject":"[PATCH] checkout: Don't crash when switching away from an invalid branch.","fromName":"Alexandre Julliard","fromEmail":"julliard@winehq.org","sentAt":"2008-11-08T12:03:59Z","receivedAt":"2008-11-08T12:03:59Z","isPatch":true,"sender":{"key":"julliard@winehq.org","avatar":null},"body":"When using alternates, it is possible for HEAD to end up pointing to\nan invalid commit. git checkout should be able to recover from that\nsituation without crashing.\n\nSigned-off-by: Alexandre Julliard <julliard@winehq.org>\n---\n builtin-checkout.c               |    8 ++++----\n t/t2011-checkout-invalid-head.sh |   18 ++++++++++++++++++\n 2 files changed, 22 insertions(+), 4 deletions(-)\n create mode 100755 t/t2011-checkout-invalid-head.sh\n\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex 57b94d2..06904c3 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -47,7 +47,7 @@ static int post_checkout_hook(struct commit *old, struct commit *new,\n \n \tmemset(&proc, 0, sizeof(proc));\n \targv[0] = name;\n-\targv[1] = xstrdup(sha1_to_hex(old->object.sha1));\n+\targv[1] = xstrdup(sha1_to_hex(old ? old->object.sha1 : null_sha1));\n \targv[2] = xstrdup(sha1_to_hex(new->object.sha1));\n \targv[3] = changed ? \"1\" : \"0\";\n \targv[4] = NULL;\n@@ -492,10 +492,10 @@ static void update_refs_for_switch(struct checkout_opts *opts,\n \t}\n \n \told_desc = old->name;\n-\tif (!old_desc)\n+\tif (!old_desc && old->commit)\n \t\told_desc = sha1_to_hex(old->commit->object.sha1);\n \tstrbuf_addf(&msg, \"checkout: moving from %s to %s\",\n-\t\t    old_desc, new->name);\n+\t\t    old_desc ? old_desc : \"(invalid)\", new->name);\n \n \tif (new->path) {\n \t\tcreate_symref(\"HEAD\", new->path, msg.buf);\n@@ -551,7 +551,7 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)\n \t * a new commit, we want to mention the old commit once more\n \t * to remind the user that it might be lost.\n \t */\n-\tif (!opts->quiet && !old.path && new->commit != old.commit)\n+\tif (!opts->quiet && !old.path && old.commit && new->commit != old.commit)\n \t\tdescribe_detached_head(\"Previous HEAD position was\", old.commit);\n \n \tif (!old.commit) {\ndiff --git a/t/t2011-checkout-invalid-head.sh b/t/t2011-checkout-invalid-head.sh\nnew file mode 100755\nindex 0000000..764bb0a\n--- /dev/null\n+++ b/t/t2011-checkout-invalid-head.sh\n@@ -0,0 +1,18 @@\n+#!/bin/sh\n+\n+test_description='checkout switching away from an invalid branch'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'setup' '\n+\techo hello >world &&\n+\tgit add world &&\n+\tgit commit -m initial\n+'\n+\n+test_expect_success 'checkout master from invalid HEAD' '\n+\techo 0000000000000000000000000000000000000000 >.git/HEAD &&\n+\tgit checkout master --\n+'\n+\n+test_done\n-- \n1.6.0.3.669.g76740\n\n-- \nAlexandre Julliard\njulliard@winehq.org\n"}]}