worktree list: keep the list sorted

It makes it easier to write tests for. But it should also be good for the user since locating a worktree by eye would be easier once they notice this. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Nov 28, 2016 at 16:36 UTC 4df1d4d4666eb26b420d5b386010470729846b8c
4 files changed +36 -1
builtin/worktree.c
+1 -1
@@ -447,7 +447,7 @@ static int list(int ac, const char **av, const char *prefix)
447 if (ac)
448 usage_with_options(worktree_usage, options);
449 else {
450 - struct worktree **worktrees = get_worktrees(0);
450 + struct worktree **worktrees = get_worktrees(GWT_SORT_LINKED);
451 int path_maxlen = 0, abbrev = DEFAULT_ABBREV, i;
452
453 if (!porcelain)
t/t2027-worktree-list.sh
+19
@@ -117,4 +117,23 @@ test_expect_success 'broken main worktree still at the top' '
117 )
118 '
119
120 +test_expect_success 'linked worktrees are sorted' '
121 + mkdir sorted &&
122 + git init sorted/main &&
123 + (
124 + cd sorted/main &&
125 + test_tick &&
126 + test_commit new &&
127 + git worktree add ../first &&
128 + git worktree add ../second &&
129 + git worktree list --porcelain | grep ^worktree >actual
130 + ) &&
131 + cat >expected <<-EOF &&
132 + worktree $(pwd)/sorted/main
133 + worktree $(pwd)/sorted/first
134 + worktree $(pwd)/sorted/second
135 + EOF
136 + test_cmp expected sorted/main/actual
137 +'
138 +
139 test_done
worktree.c
+14
@@ -160,6 +160,13 @@ static void mark_current_worktree(struct worktree **worktrees)
160 free(git_dir);
161 }
162
163 +static int compare_worktree(const void *a_, const void *b_)
164 +{
165 + const struct worktree *const *a = a_;
166 + const struct worktree *const *b = b_;
167 + return fspathcmp((*a)->path, (*b)->path);
168 +}
169 +
170 struct worktree **get_worktrees(unsigned flags)
171 {
172 struct worktree **list = NULL;
@@ -191,6 +198,13 @@ struct worktree **get_worktrees(unsigned flags)
198 ALLOC_GROW(list, counter + 1, alloc);
199 list[counter] = NULL;
200
201 + if (flags & GWT_SORT_LINKED)
202 + /*
203 + * don't sort the first item (main worktree), which will
204 + * always be the first
205 + */
206 + QSORT(list + 1, counter - 1, compare_worktree);
207 +
208 mark_current_worktree(list);
209 return list;
210 }
worktree.h
+2
@@ -15,6 +15,8 @@ struct worktree {
15
16 /* Functions for acting on the information about worktrees. */
17
18 +#define GWT_SORT_LINKED (1 << 0) /* keeps linked worktrees sorted */
19 +
20 /*
21 * Get the worktrees. The primary worktree will always be the first returned,
22 * and linked worktrees will be pointed to by 'next' in each subsequent