]> git.ipfire.org Git - thirdparty/git.git/commitdiff
worktree: libify should_prune_worktree()
authorRafael Silva <rafaeloliveira.cs@gmail.com>
Tue, 19 Jan 2021 21:27:33 +0000 (22:27 +0100)
committerJunio C Hamano <gitster@pobox.com>
Sat, 30 Jan 2021 17:57:08 +0000 (09:57 -0800)
As part of teaching "git worktree list" to annotate worktree that is a
candidate for pruning, let's move should_prune_worktree() from
builtin/worktree.c to worktree.c in order to make part of the worktree
public API.

should_prune_worktree() knows how to select the given worktree for
pruning based on an expiration date, however the expiration value is
stored in a static file-scope variable and it is not local to the
function. In order to move the function, teach should_prune_worktree()
to take the expiration date as an argument and document the new
parameter that is not immediately obvious.

Also, change the function comment to clearly state that the worktree's
path is returned in `wtpath` argument.

Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Rafael Silva <rafaeloliveira.cs@gmail.com>
Reviewed-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/worktree.c
worktree.c
worktree.h

index 71287b2da6ccf54afe575b443592468121fa4e5a..dd886d5029843497397b336ba6bcfb454b34599e 100644 (file)
@@ -67,79 +67,6 @@ static void delete_worktrees_dir_if_empty(void)
        rmdir(git_path("worktrees")); /* ignore failed removal */
 }
 
-/*
- * Return true if worktree entry should be pruned, along with the reason for
- * pruning. Otherwise, return false and the worktree's path, or NULL if it
- * cannot be determined. Caller is responsible for freeing returned path.
- */
-static int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath)
-{
-       struct stat st;
-       char *path;
-       int fd;
-       size_t len;
-       ssize_t read_result;
-
-       *wtpath = NULL;
-       if (!is_directory(git_path("worktrees/%s", id))) {
-               strbuf_addstr(reason, _("not a valid directory"));
-               return 1;
-       }
-       if (file_exists(git_path("worktrees/%s/locked", id)))
-               return 0;
-       if (stat(git_path("worktrees/%s/gitdir", id), &st)) {
-               strbuf_addstr(reason, _("gitdir file does not exist"));
-               return 1;
-       }
-       fd = open(git_path("worktrees/%s/gitdir", id), O_RDONLY);
-       if (fd < 0) {
-               strbuf_addf(reason, _("unable to read gitdir file (%s)"),
-                           strerror(errno));
-               return 1;
-       }
-       len = xsize_t(st.st_size);
-       path = xmallocz(len);
-
-       read_result = read_in_full(fd, path, len);
-       if (read_result < 0) {
-               strbuf_addf(reason, _("unable to read gitdir file (%s)"),
-                           strerror(errno));
-               close(fd);
-               free(path);
-               return 1;
-       }
-       close(fd);
-
-       if (read_result != len) {
-               strbuf_addf(reason,
-                           _("short read (expected %"PRIuMAX" bytes, read %"PRIuMAX")"),
-                           (uintmax_t)len, (uintmax_t)read_result);
-               free(path);
-               return 1;
-       }
-       while (len && (path[len - 1] == '\n' || path[len - 1] == '\r'))
-               len--;
-       if (!len) {
-               strbuf_addstr(reason, _("invalid gitdir file"));
-               free(path);
-               return 1;
-       }
-       path[len] = '\0';
-       if (!file_exists(path)) {
-               if (stat(git_path("worktrees/%s/index", id), &st) ||
-                   st.st_mtime <= expire) {
-                       strbuf_addstr(reason, _("gitdir file points to non-existent location"));
-                       free(path);
-                       return 1;
-               } else {
-                       *wtpath = path;
-                       return 0;
-               }
-       }
-       *wtpath = path;
-       return 0;
-}
-
 static void prune_worktree(const char *id, const char *reason)
 {
        if (show_only || verbose)
@@ -195,7 +122,7 @@ static void prune_worktrees(void)
                if (is_dot_or_dotdot(d->d_name))
                        continue;
                strbuf_reset(&reason);
-               if (should_prune_worktree(d->d_name, &reason, &path))
+               if (should_prune_worktree(d->d_name, &reason, &path, expire))
                        prune_worktree(d->d_name, reason.buf);
                else if (path)
                        string_list_append(&kept, path)->util = xstrdup(d->d_name);
index 821b23347955a56ea3ee93fb3307afddf79c0279..8ae019af79bb5d17ce993745d996cbde42289f10 100644 (file)
@@ -741,3 +741,71 @@ done:
        strbuf_release(&realdotgit);
        strbuf_release(&dotgit);
 }
+
+int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath, timestamp_t expire)
+{
+       struct stat st;
+       char *path;
+       int fd;
+       size_t len;
+       ssize_t read_result;
+
+       *wtpath = NULL;
+       if (!is_directory(git_path("worktrees/%s", id))) {
+               strbuf_addstr(reason, _("not a valid directory"));
+               return 1;
+       }
+       if (file_exists(git_path("worktrees/%s/locked", id)))
+               return 0;
+       if (stat(git_path("worktrees/%s/gitdir", id), &st)) {
+               strbuf_addstr(reason, _("gitdir file does not exist"));
+               return 1;
+       }
+       fd = open(git_path("worktrees/%s/gitdir", id), O_RDONLY);
+       if (fd < 0) {
+               strbuf_addf(reason, _("unable to read gitdir file (%s)"),
+                           strerror(errno));
+               return 1;
+       }
+       len = xsize_t(st.st_size);
+       path = xmallocz(len);
+
+       read_result = read_in_full(fd, path, len);
+       if (read_result < 0) {
+               strbuf_addf(reason, _("unable to read gitdir file (%s)"),
+                           strerror(errno));
+               close(fd);
+               free(path);
+               return 1;
+       }
+       close(fd);
+
+       if (read_result != len) {
+               strbuf_addf(reason,
+                           _("short read (expected %"PRIuMAX" bytes, read %"PRIuMAX")"),
+                           (uintmax_t)len, (uintmax_t)read_result);
+               free(path);
+               return 1;
+       }
+       while (len && (path[len - 1] == '\n' || path[len - 1] == '\r'))
+               len--;
+       if (!len) {
+               strbuf_addstr(reason, _("invalid gitdir file"));
+               free(path);
+               return 1;
+       }
+       path[len] = '\0';
+       if (!file_exists(path)) {
+               if (stat(git_path("worktrees/%s/index", id), &st) ||
+                   st.st_mtime <= expire) {
+                       strbuf_addstr(reason, _("gitdir file points to non-existent location"));
+                       free(path);
+                       return 1;
+               } else {
+                       *wtpath = path;
+                       return 0;
+               }
+       }
+       *wtpath = path;
+       return 0;
+}
index f38e6fd5a224fbe891f924df6b60a613b0b91638..818e1491c7ec331647cfa3886877c1fc3a33a123 100644 (file)
@@ -73,6 +73,20 @@ int is_main_worktree(const struct worktree *wt);
  */
 const char *worktree_lock_reason(struct worktree *wt);
 
+/*
+ * Return true if worktree entry should be pruned, along with the reason for
+ * pruning. Otherwise, return false and the worktree's path in `wtpath`, or
+ * NULL if it cannot be determined. Caller is responsible for freeing
+ * returned path.
+ *
+ * `expire` defines a grace period to prune the worktree when its path
+ * does not exist.
+ */
+int should_prune_worktree(const char *id,
+                         struct strbuf *reason,
+                         char **wtpath,
+                         timestamp_t expire);
+
 #define WT_VALIDATE_WORKTREE_MISSING_OK (1 << 0)
 
 /*