aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/worktree.c41
-rwxr-xr-xt/t2402-worktree-list.sh37
2 files changed, 53 insertions, 25 deletions
diff --git a/builtin/worktree.c b/builtin/worktree.c
index b7f323b5e4..fbdaf2eb2e 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -975,14 +975,18 @@ static void show_worktree_porcelain(struct worktree *wt, int line_terminator)
fputc(line_terminator, stdout);
}
-static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)
+struct worktree_display {
+ char *path;
+ int width;
+};
+
+static void show_worktree(struct worktree *wt, struct worktree_display *display,
+ int path_maxwidth, int abbrev_len)
{
struct strbuf sb = STRBUF_INIT;
- int cur_path_len = strlen(wt->path);
- int path_adj = cur_path_len - utf8_strwidth(wt->path);
const char *reason;
- strbuf_addf(&sb, "%-*s ", 1 + path_maxlen + path_adj, wt->path);
+ strbuf_addf(&sb, "%s%*s", display->path, 1 + path_maxwidth - display->width, "");
if (wt->is_bare)
strbuf_addstr(&sb, "(bare)");
else {
@@ -1016,20 +1020,27 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)
strbuf_release(&sb);
}
-static void measure_widths(struct worktree **wt, int *abbrev, int *maxlen)
+static void measure_widths(struct worktree **wt, int *abbrev,
+ struct worktree_display **d, int *maxwidth)
{
- int i;
+ int i, display_alloc = 0;
+ struct worktree_display *display = NULL;
+ struct strbuf buf = STRBUF_INIT;
for (i = 0; wt[i]; i++) {
int sha1_len;
- int path_len = strlen(wt[i]->path);
+ ALLOC_GROW(display, i + 1, display_alloc);
+ quote_path(wt[i]->path, NULL, &buf, 0);
+ display[i].width = utf8_strwidth(buf.buf);
+ display[i].path = strbuf_detach(&buf, NULL);
- if (path_len > *maxlen)
- *maxlen = path_len;
+ if (display[i].width > *maxwidth)
+ *maxwidth = display[i].width;
sha1_len = strlen(repo_find_unique_abbrev(the_repository, &wt[i]->head_oid, *abbrev));
if (sha1_len > *abbrev)
*abbrev = sha1_len;
}
+ *d = display;
}
static int pathcmp(const void *a_, const void *b_)
@@ -1075,21 +1086,27 @@ static int list(int ac, const char **av, const char *prefix,
die(_("the option '%s' requires '%s'"), "-z", "--porcelain");
else {
struct worktree **worktrees = get_worktrees();
- int path_maxlen = 0, abbrev = DEFAULT_ABBREV, i;
+ int path_maxwidth = 0, abbrev = DEFAULT_ABBREV, i;
+ struct worktree_display *display = NULL;
/* sort worktrees by path but keep main worktree at top */
pathsort(worktrees + 1);
if (!porcelain)
- measure_widths(worktrees, &abbrev, &path_maxlen);
+ measure_widths(worktrees, &abbrev,
+ &display, &path_maxwidth);
for (i = 0; worktrees[i]; i++) {
if (porcelain)
show_worktree_porcelain(worktrees[i],
line_terminator);
else
- show_worktree(worktrees[i], path_maxlen, abbrev);
+ show_worktree(worktrees[i],
+ &display[i], path_maxwidth, abbrev);
}
+ for (i = 0; display && worktrees[i]; i++)
+ free(display[i].path);
+ free(display);
free_worktrees(worktrees);
}
return 0;
diff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh
index 8ef1cad7f2..e0c6abd2f5 100755
--- a/t/t2402-worktree-list.sh
+++ b/t/t2402-worktree-list.sh
@@ -29,23 +29,34 @@ test_expect_success 'rev-parse --git-path objects linked worktree' '
test_cmp expect actual
'
-test_expect_success '"list" all worktrees from main' '
- echo "$(git rev-parse --show-toplevel) $(git rev-parse --short HEAD) [$(git symbolic-ref --short HEAD)]" >expect &&
- test_when_finished "rm -rf here out actual expect && git worktree prune" &&
- git worktree add --detach here main &&
- echo "$(git -C here rev-parse --show-toplevel) $(git rev-parse --short HEAD) (detached HEAD)" >>expect &&
- git worktree list >out &&
- sed "s/ */ /g" <out >actual &&
+test_expect_success '"list" all worktrees from main core.quotepath=false' '
+ test_config core.quotepath false &&
+ echo "$(git rev-parse --show-toplevel) $(git rev-parse --short HEAD) [$(git symbolic-ref --short HEAD)]" >expect &&
+ test_when_finished "rm -rf áááá out actual expect && git worktree prune" &&
+ git worktree add --detach áááá main &&
+ echo "$(git -C áááá rev-parse --show-toplevel) $(git rev-parse --short HEAD) (detached HEAD)" >>expect &&
+ git worktree list >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '"list" all worktrees from main core.quotepath=true' '
+ test_config core.quotepath true &&
+ echo "$(git rev-parse --show-toplevel) $(git rev-parse --short HEAD) [$(git symbolic-ref --short HEAD)]" >expect &&
+ test_when_finished "rm -rf á out actual expect && git worktree prune" &&
+ git worktree add --detach á main &&
+ echo "\"$(git -C á rev-parse --show-toplevel)\" $(git rev-parse --short HEAD) (detached HEAD)" |
+ sed s/á/\\\\303\\\\241/g >>expect &&
+ git worktree list >actual &&
test_cmp expect actual
'
test_expect_success '"list" all worktrees from linked' '
- echo "$(git rev-parse --show-toplevel) $(git rev-parse --short HEAD) [$(git symbolic-ref --short HEAD)]" >expect &&
- test_when_finished "rm -rf here out actual expect && git worktree prune" &&
- git worktree add --detach here main &&
- echo "$(git -C here rev-parse --show-toplevel) $(git rev-parse --short HEAD) (detached HEAD)" >>expect &&
- git -C here worktree list >out &&
- sed "s/ */ /g" <out >actual &&
+ test_config core.quotepath false &&
+ echo "$(git rev-parse --show-toplevel) $(git rev-parse --short HEAD) [$(git symbolic-ref --short HEAD)]" >expect &&
+ test_when_finished "rm -rf áááá out actual expect && git worktree prune" &&
+ git worktree add --detach áááá main &&
+ echo "$(git -C áááá rev-parse --show-toplevel) $(git rev-parse --short HEAD) (detached HEAD)" >>expect &&
+ git -C áááá worktree list >actual &&
test_cmp expect actual
'