sequencer: lib'ify save_todo()
[gitweb.git] / worktree.c
index 2bcfff3850203dbb283ff40455f0c97694fff7e5..5acfe4cd64967d86462f3958433f3d2f844ead51 100644 (file)
@@ -21,7 +21,7 @@ void free_worktrees(struct worktree **worktrees)
 
 /*
  * read 'path_to_ref' into 'ref'.  Also if is_detached is not NULL,
- * set is_detached to 1 (0) if the ref is detatched (is not detached).
+ * set is_detached to 1 (0) if the ref is detached (is not detached).
  *
  * $GIT_COMMON_DIR/$symref (e.g. HEAD) is practically outside $GIT_DIR so
  * for linked worktrees, `resolve_ref_unsafe()` won't work (it uses
@@ -81,7 +81,7 @@ static struct worktree *get_main_worktree(void)
        int is_bare = 0;
        int is_detached = 0;
 
-       strbuf_addstr(&worktree_path, absolute_path(get_git_common_dir()));
+       strbuf_add_absolute_path(&worktree_path, get_git_common_dir());
        is_bare = !strbuf_strip_suffix(&worktree_path, "/.git");
        if (is_bare)
                strbuf_strip_suffix(&worktree_path, "/.");
@@ -128,7 +128,7 @@ static struct worktree *get_linked_worktree(const char *id)
        strbuf_rtrim(&worktree_path);
        if (!strbuf_strip_suffix(&worktree_path, "/.git")) {
                strbuf_reset(&worktree_path);
-               strbuf_addstr(&worktree_path, absolute_path("."));
+               strbuf_add_absolute_path(&worktree_path, ".");
                strbuf_strip_suffix(&worktree_path, "/.");
        }
 
@@ -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++)