mirror of
https://github.com/git/git
synced 2024-10-30 04:01:21 +00:00
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>
This commit is contained in:
parent
7c181d627c
commit
323e00fd46
2 changed files with 22 additions and 4 deletions
|
@ -32,7 +32,7 @@ static int post_checkout_hook(struct commit *old, struct commit *new,
|
||||||
|
|
||||||
memset(&proc, 0, sizeof(proc));
|
memset(&proc, 0, sizeof(proc));
|
||||||
argv[0] = name;
|
argv[0] = name;
|
||||||
argv[1] = xstrdup(sha1_to_hex(old->object.sha1));
|
argv[1] = xstrdup(sha1_to_hex(old ? old->object.sha1 : null_sha1));
|
||||||
argv[2] = xstrdup(sha1_to_hex(new->object.sha1));
|
argv[2] = xstrdup(sha1_to_hex(new->object.sha1));
|
||||||
argv[3] = changed ? "1" : "0";
|
argv[3] = changed ? "1" : "0";
|
||||||
argv[4] = NULL;
|
argv[4] = NULL;
|
||||||
|
@ -360,10 +360,10 @@ static void update_refs_for_switch(struct checkout_opts *opts,
|
||||||
|
|
||||||
strbuf_init(&msg, 0);
|
strbuf_init(&msg, 0);
|
||||||
old_desc = old->name;
|
old_desc = old->name;
|
||||||
if (!old_desc)
|
if (!old_desc && old->commit)
|
||||||
old_desc = sha1_to_hex(old->commit->object.sha1);
|
old_desc = sha1_to_hex(old->commit->object.sha1);
|
||||||
strbuf_addf(&msg, "checkout: moving from %s to %s",
|
strbuf_addf(&msg, "checkout: moving from %s to %s",
|
||||||
old_desc, new->name);
|
old_desc ? old_desc : "(invalid)", new->name);
|
||||||
|
|
||||||
if (new->path) {
|
if (new->path) {
|
||||||
create_symref("HEAD", new->path, msg.buf);
|
create_symref("HEAD", new->path, msg.buf);
|
||||||
|
@ -419,7 +419,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
|
* a new commit, we want to mention the old commit once more
|
||||||
* to remind the user that it might be lost.
|
* 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);
|
describe_detached_head("Previous HEAD position was", old.commit);
|
||||||
|
|
||||||
if (!old.commit) {
|
if (!old.commit) {
|
||||||
|
|
18
t/t2011-checkout-invalid-head.sh
Executable file
18
t/t2011-checkout-invalid-head.sh
Executable file
|
@ -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
|
Loading…
Reference in a new issue