summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2016-06-13 19:18:26 +0700
committerJunio C Hamano <gitster@pobox.com>2016-07-08 15:31:04 -0700
commit080739ba1db7897dde53427937acc011ea98a006 (patch)
treec7f83399881e31826cc3ea6af0c55f4f8badc205
parent6d308627cae4d34c058591de73ce14a52b79cf4e (diff)
downloadgit-080739ba1db7897dde53427937acc011ea98a006.tar.gz
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>
-rw-r--r--Documentation/git-worktree.txt5
-rw-r--r--worktree.c29
2 files changed, 34 insertions, 0 deletions
diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 27330c5a39..7850deedf7 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -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
-------
diff --git a/worktree.c b/worktree.c
index 2bcfff3850..2107c0625d 100644
--- a/worktree.c
+++ b/worktree.c
@@ -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++)