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>
This commit is contained in:
Nguyễn Thái Ngọc Duy 2016-06-13 19:18:26 +07:00 коммит произвёл Junio C Hamano
Родитель 6d308627ca
Коммит 080739ba1d
2 изменённых файлов: 34 добавлений и 0 удалений

Просмотреть файл

@ -129,6 +129,11 @@ OPTIONS
<worktree>::
Working trees can be identified by path, either relative or
absolute.
+
If the last path components in the working tree's path is unique among
working trees, it can be used to identify worktrees. For example if
you only have to working trees at "/abc/def/ghi" and "/abc/def/ggg",
then "ghi" or "def/ghi" is enough to point to the former working tree.
DETAILS
-------

Просмотреть файл

@ -219,12 +219,41 @@ const char *get_worktree_git_dir(const struct worktree *wt)
return git_common_path("worktrees/%s", wt->id);
}
static struct worktree *find_worktree_by_suffix(struct worktree **list,
const char *suffix)
{
struct worktree *found = NULL;
int nr_found = 0, suffixlen;
suffixlen = strlen(suffix);
if (!suffixlen)
return NULL;
for (; *list && nr_found < 2; list++) {
const char *path = (*list)->path;
int pathlen = strlen(path);
int start = pathlen - suffixlen;
/* suffix must start at directory boundary */
if ((!start || (start > 0 && is_dir_sep(path[start - 1]))) &&
!fspathcmp(suffix, path + start)) {
found = *list;
nr_found++;
}
}
return nr_found == 1 ? found : NULL;
}
struct worktree *find_worktree(struct worktree **list,
const char *prefix,
const char *arg)
{
struct worktree *wt;
char *path;
if ((wt = find_worktree_by_suffix(list, arg)))
return wt;
arg = prefix_filename(prefix, strlen(prefix), arg);
path = xstrdup(real_path(arg));
for (; *list; list++)