worktree.c: find_worktree() search by path suffix
This allows the user to do something like "worktree lock foo" or "worktree lock to/foo" instead of "worktree lock /long/path/to/foo" if it's unambiguous. With completion support it could be quite convenient. While this base name search can be done in the same worktree iteration loop, the code is split into a separate function for clarity. Suggested-by: Eric Sunshine <sunshine@sunshineco.com> 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
Jun 13, 2016 at 19:18 UTC
080739ba1db7897dde53427937acc011ea98a006
2 files changed
+34
Documentation/git-worktree.txt
+5
@@ -129,6 +129,11 @@ OPTIONS
129
<worktree>::
130
Working trees can be identified by path, either relative or
131
absolute.
132
++
133
+If the last path components in the working tree's path is unique among
134
+working trees, it can be used to identify worktrees. For example if
135
+you only have to working trees at "/abc/def/ghi" and "/abc/def/ggg",
136
+then "ghi" or "def/ghi" is enough to point to the former working tree.
137
138
DETAILS
139
-------
worktree.c
+29
@@ -219,12 +219,41 @@ const char *get_worktree_git_dir(const struct worktree *wt)
219
return git_common_path("worktrees/%s", wt->id);
220
}
221
222
+static struct worktree *find_worktree_by_suffix(struct worktree **list,
223
+ const char *suffix)
224
+{
225
+ struct worktree *found = NULL;
226
+ int nr_found = 0, suffixlen;
227
+
228
+ suffixlen = strlen(suffix);
229
+ if (!suffixlen)
230
+ return NULL;
231
+
232
+ for (; *list && nr_found < 2; list++) {
233
+ const char *path = (*list)->path;
234
+ int pathlen = strlen(path);
235
+ int start = pathlen - suffixlen;
236
+
237
+ /* suffix must start at directory boundary */
238
+ if ((!start || (start > 0 && is_dir_sep(path[start - 1]))) &&
239
+ !fspathcmp(suffix, path + start)) {
240
+ found = *list;
241
+ nr_found++;
242
+ }
243
+ }
244
+ return nr_found == 1 ? found : NULL;
245
+}
246
+
247
struct worktree *find_worktree(struct worktree **list,
248
const char *prefix,
249
const char *arg)
250
{
251
+ struct worktree *wt;
252
char *path;
253
254
+ if ((wt = find_worktree_by_suffix(list, arg)))
255
+ return wt;
256
+
257
arg = prefix_filename(prefix, strlen(prefix), arg);
258
path = xstrdup(real_path(arg));
259
for (; *list; list++)