worktree: generalize delete_git_dir() to reduce code duplication

prune_worktrees() and delete_git_dir() both remove worktree administrative entries from .git/worktrees, and their implementations are nearly identical. The only difference is that prune_worktrees() is also capable of removing a bogus non-worktree-related file from .git/worktrees. Simplify by extending delete_git_dir() to handle the little bit of extra functionality needed by prune_worktrees(), and drop the effectively duplicate code from the latter. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Eric Sunshine committed Aug 28, 2018 at 17:20 UTC 602aaed03f7f82323d88703d6fa2263a13c37907
1 file changed +9 -16
builtin/worktree.c
+9 -16
@@ -47,16 +47,17 @@ static int git_worktree_config(const char *var, const char *value, void *cb)
47 return git_default_config(var, value, cb);
48 }
49
50 -static int delete_git_dir(struct worktree *wt)
50 +static int delete_git_dir(const char *id)
51 {
52 struct strbuf sb = STRBUF_INIT;
53 - int ret = 0;
53 + int ret;
54
55 - strbuf_addstr(&sb, git_common_path("worktrees/%s", wt->id));
56 - if (remove_dir_recursively(&sb, 0)) {
55 + strbuf_addstr(&sb, git_common_path("worktrees/%s", id));
56 + ret = remove_dir_recursively(&sb, 0);
57 + if (ret < 0 && errno == ENOTDIR)
58 + ret = unlink(sb.buf);
59 + if (ret)
60 error_errno(_("failed to delete '%s'"), sb.buf);
58 - ret = -1;
59 - }
61 strbuf_release(&sb);
62 return ret;
63 }
@@ -130,10 +131,8 @@ static int prune_worktree(const char *id, struct strbuf *reason)
131 static void prune_worktrees(void)
132 {
133 struct strbuf reason = STRBUF_INIT;
133 - struct strbuf path = STRBUF_INIT;
134 DIR *dir = opendir(git_path("worktrees"));
135 struct dirent *d;
136 - int ret;
136 if (!dir)
137 return;
138 while ((d = readdir(dir)) != NULL) {
@@ -146,18 +145,12 @@ static void prune_worktrees(void)
145 printf("%s\n", reason.buf);
146 if (show_only)
147 continue;
149 - git_path_buf(&path, "worktrees/%s", d->d_name);
150 - ret = remove_dir_recursively(&path, 0);
151 - if (ret < 0 && errno == ENOTDIR)
152 - ret = unlink(path.buf);
153 - if (ret)
154 - error_errno(_("failed to remove '%s'"), path.buf);
148 + delete_git_dir(d->d_name);
149 }
150 closedir(dir);
151 if (!show_only)
152 rmdir(git_path("worktrees"));
153 strbuf_release(&reason);
160 - strbuf_release(&path);
154 }
155
156 static int prune(int ac, const char **av, const char *prefix)
@@ -882,7 +875,7 @@ static int remove_worktree(int ac, const char **av, const char *prefix)
875 * continue on even if ret is non-zero, there's no going back
876 * from here.
877 */
885 - ret |= delete_git_dir(wt);
878 + ret |= delete_git_dir(wt->id);
879
880 free_worktrees(worktrees);
881 return ret;