From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alexandre Julliard Subject: [PATCH] checkout: Don't crash when switching away from an invalid branch. Date: Sat, 08 Nov 2008 13:03:59 +0100 Message-ID: <87fxm2a0gg.fsf@wine.dyndns.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii To: git@vger.kernel.org X-From: git-owner@vger.kernel.org Sat Nov 08 13:05:50 2008 connect(): Connection refused Return-path: Envelope-to: gcvg-git-2@gmane.org Received: from vger.kernel.org ([209.132.176.167]) by lo.gmane.org with esmtp (Exim 4.50) id 1KymZI-0000mp-Cl for gcvg-git-2@gmane.org; Sat, 08 Nov 2008 13:05:47 +0100 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753135AbYKHMES (ORCPT ); Sat, 8 Nov 2008 07:04:18 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753125AbYKHMES (ORCPT ); Sat, 8 Nov 2008 07:04:18 -0500 Received: from mail.codeweavers.com ([216.251.189.131]:50344 "EHLO mail.codeweavers.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753122AbYKHMER (ORCPT ); Sat, 8 Nov 2008 07:04:17 -0500 Received: from adsl-84-226-9-85.adslplus.ch ([84.226.9.85] helo=wine.dyndns.org) by mail.codeweavers.com with esmtpsa (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.63) (envelope-from ) id 1KymXu-0003Xq-2Y for git@vger.kernel.org; Sat, 08 Nov 2008 06:04:16 -0600 Received: by wine.dyndns.org (Postfix, from userid 1000) id D94B71E73B5; Sat, 8 Nov 2008 13:03:59 +0100 (CET) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux) X-Spam-Score: -3.4 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Archived-At: 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 --- builtin-checkout.c | 8 ++++---- t/t2011-checkout-invalid-head.sh | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) create mode 100755 t/t2011-checkout-invalid-head.sh diff --git a/builtin-checkout.c b/builtin-checkout.c index 57b94d2..06904c3 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -47,7 +47,7 @@ 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] = xstrdup(sha1_to_hex(old ? old->object.sha1 : null_sha1)); argv[2] = xstrdup(sha1_to_hex(new->object.sha1)); argv[3] = changed ? "1" : "0"; argv[4] = NULL; @@ -492,10 +492,10 @@ 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); + old_desc ? old_desc : "(invalid)", new->name); if (new->path) { create_symref("HEAD", new->path, msg.buf); @@ -551,7 +551,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@winehq.org