All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
	"Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 03/11] get_worktrees() must return main worktree as first item even on error
Date: Thu,  2 Feb 2017 15:49:59 +0700	[thread overview]
Message-ID: <20170202085007.21418-4-pclouds@gmail.com> (raw)
In-Reply-To: <20170202085007.21418-1-pclouds@gmail.com>

This is required by git-worktree.txt, stating that the main worktree is
the first line (especially in --porcelain mode when we can't just change
behavior at will).

There's only one case when get_worktrees() may skip main worktree, when
parse_ref() fails. Update the code so that we keep first item as main
worktree and return something sensible in this case:

 - In user-friendly mode, since we're not constraint by anything,
   returning "(error)" should do the job (we already show "(detached
   HEAD)" which is not machine-friendly). Actually errors should be
   printed on stderr by parse_ref() (*)

 - In plumbing mode, we do not show neither 'bare', 'detached' or
   'branch ...', which is possible by the format description if I read
   it right.

Careful readers may realize that when the local variable "head_ref" in
get_main_worktree() is emptied, add_head_info() will do nothing to
wt->head_sha1. But that's ok because head_sha1 is zero-ized in the
previous patch.

(*) Well, it does not. But it's supposed to be a stop gap implementation
    until we can reuse refs code to parse "ref: " stuff in HEAD, from
    resolve_refs_unsafe(). Now may be the time since refs refactoring is
    mostly done.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/worktree.c       |  6 ++++--
 t/t2027-worktree-list.sh | 21 +++++++++++++++++++++
 worktree.c               | 10 +++-------
 3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index 8a654e4ad3..b835b91f63 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -388,7 +388,7 @@ static void show_worktree_porcelain(struct worktree *wt)
 		printf("HEAD %s\n", sha1_to_hex(wt->head_sha1));
 		if (wt->is_detached)
 			printf("detached\n");
-		else
+		else if (wt->head_ref)
 			printf("branch %s\n", wt->head_ref);
 	}
 	printf("\n");
@@ -408,8 +408,10 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)
 				find_unique_abbrev(wt->head_sha1, DEFAULT_ABBREV));
 		if (wt->is_detached)
 			strbuf_addstr(&sb, "(detached HEAD)");
-		else
+		else if (wt->head_ref)
 			strbuf_addf(&sb, "[%s]", shorten_unambiguous_ref(wt->head_ref, 0));
+		else
+			strbuf_addstr(&sb, "(error)");
 	}
 	printf("%s\n", sb.buf);
 
diff --git a/t/t2027-worktree-list.sh b/t/t2027-worktree-list.sh
index 1b1b65a6b0..98b5f340e5 100755
--- a/t/t2027-worktree-list.sh
+++ b/t/t2027-worktree-list.sh
@@ -96,4 +96,25 @@ test_expect_success 'bare repo cleanup' '
 	rm -rf bare1
 '
 
+test_expect_success 'broken main worktree still at the top' '
+	git init broken-main &&
+	(
+		cd broken-main &&
+		test_commit new &&
+		git worktree add linked &&
+		cat >expected <<-EOF &&
+		worktree $(pwd)
+		HEAD $_z40
+
+		EOF
+		cd linked &&
+		echo "worktree $(pwd)" >expected &&
+		echo "ref: .broken" >../.git/HEAD &&
+		git worktree list --porcelain | head -n 3 >actual &&
+		test_cmp ../expected actual &&
+		git worktree list | head -n 1 >actual.2 &&
+		grep -F "(error)" actual.2
+	)
+'
+
 test_done
diff --git a/worktree.c b/worktree.c
index f7c1b5e24d..3145522536 100644
--- a/worktree.c
+++ b/worktree.c
@@ -88,16 +88,13 @@ static struct worktree *get_main_worktree(void)
 
 	strbuf_addf(&path, "%s/HEAD", get_git_common_dir());
 
-	if (parse_ref(path.buf, &head_ref, &is_detached) < 0)
-		goto done;
-
 	worktree = xcalloc(1, sizeof(*worktree));
 	worktree->path = strbuf_detach(&worktree_path, NULL);
 	worktree->is_bare = is_bare;
 	worktree->is_detached = is_detached;
-	add_head_info(&head_ref, worktree);
+	if (!parse_ref(path.buf, &head_ref, &is_detached))
+		add_head_info(&head_ref, worktree);
 
-done:
 	strbuf_release(&path);
 	strbuf_release(&worktree_path);
 	strbuf_release(&head_ref);
@@ -173,8 +170,7 @@ struct worktree **get_worktrees(void)
 
 	list = xmalloc(alloc * sizeof(struct worktree *));
 
-	if ((list[counter] = get_main_worktree()))
-		counter++;
+	list[counter++] = get_main_worktree();
 
 	strbuf_addf(&path, "%s/worktrees", get_git_common_dir());
 	dir = opendir(path.buf);
-- 
2.11.0.157.gd943d85


  parent reply	other threads:[~2017-02-02  8:50 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-02  8:49 [PATCH 00/11] nd/worktree-move update Nguyễn Thái Ngọc Duy
2017-02-02  8:49 ` [PATCH 01/11] worktree.c: zero new 'struct worktree' on allocation Nguyễn Thái Ngọc Duy
2017-02-02  8:49 ` [PATCH 02/11] worktree: reorder an if statement Nguyễn Thái Ngọc Duy
2017-02-02  8:49 ` Nguyễn Thái Ngọc Duy [this message]
2017-02-02  8:50 ` [PATCH 04/11] worktree.c: get_worktrees() takes a new flag argument Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 05/11] worktree list: keep the list sorted Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 06/11] worktree.c: add validate_worktree() Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 07/11] worktree.c: add update_worktree_location() Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 08/11] worktree move: new command Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 09/11] worktree move: accept destination as directory Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 10/11] worktree move: refuse to move worktrees with submodules Nguyễn Thái Ngọc Duy
2017-02-02  8:50 ` [PATCH 11/11] worktree remove: new command Nguyễn Thái Ngọc Duy
2017-02-02  9:16 ` [PATCH 00/11] nd/worktree-move update Johannes Schindelin
2017-02-02  9:27   ` Duy Nguyen
2017-02-02  9:43     ` Johannes Schindelin
2017-02-02  9:50       ` Duy Nguyen
2017-02-02 10:37         ` Johannes Schindelin
2017-02-02 11:22           ` Duy Nguyen
2017-02-02 11:31             ` Johannes Schindelin
2017-02-02 12:33               ` Johannes Schindelin
2017-02-02 20:21                 ` Junio C Hamano
2017-02-03  8:59                   ` Duy Nguyen
2017-02-03 18:25                     ` Junio C Hamano
2017-02-03 18:56                       ` Junio C Hamano
2017-02-04 11:57                       ` Duy Nguyen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170202085007.21418-4-pclouds@gmail.com \
    --to=pclouds@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.