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
next prev 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.