@matheusbsbs / matheus-bagliano / commits / d179af679b
Fork 0

worktree: generalize candidate worktree path validation

"git worktree add" checks that the specified path is a valid location for a new worktree by ensuring that the path does not already exist and is not already registered to another worktree (a path can be registered but missing, for instance, if it resides on removable media). Since "git worktree add" is not the only command which should perform such validation ("git worktree move" ought to also), generalize the the validation function for use by other callers, as well. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Eric Sunshine committed Jun 10, 2020 at 02:30 UTC d179af679bd5f70506732e1c9242d367efc7ea42
1 file changed +16 -13
builtin/worktree.c
+16 -13
@@ -280,34 +280,33 @@ static const char *worktree_basename(const char *path, int *olen)
280 return name;
281 }
282
283 -static void validate_worktree_add(const char *path, const struct add_opts *opts)
283 +/* check that path is viable location for worktree */
284 +static void check_candidate_path(const char *path,
285 + int force,
286 + struct worktree **worktrees,
287 + const char *cmd)
288 {
285 - struct worktree **worktrees;
289 struct worktree *wt;
290 int locked;
291
292 if (file_exists(path) && !is_empty_dir(path))
293 die(_("'%s' already exists"), path);
294
292 - worktrees = get_worktrees(0);
295 wt = find_worktree_by_path(worktrees, path);
296 if (!wt)
295 - goto done;
297 + return;
298
299 locked = !!worktree_lock_reason(wt);
298 - if ((!locked && opts->force) || (locked && opts->force > 1)) {
300 + if ((!locked && force) || (locked && force > 1)) {
301 if (delete_git_dir(wt->id))
300 - die(_("unable to re-add worktree '%s'"), path);
301 - goto done;
302 + die(_("unusable worktree destination '%s'"), path);
303 + return;
304 }
305
306 if (locked)
305 - die(_("'%s' is a missing but locked worktree;\nuse 'add -f -f' to override, or 'unlock' and 'prune' or 'remove' to clear"), path);
307 + die(_("'%s' is a missing but locked worktree;\nuse '%s -f -f' to override, or 'unlock' and 'prune' or 'remove' to clear"), cmd, path);
308 else
307 - die(_("'%s' is a missing but already registered worktree;\nuse 'add -f' to override, or 'prune' or 'remove' to clear"), path);
308 -
309 -done:
310 - free_worktrees(worktrees);
309 + die(_("'%s' is a missing but already registered worktree;\nuse '%s -f' to override, or 'prune' or 'remove' to clear"), cmd, path);
310 }
311
312 static int add_worktree(const char *path, const char *refname,
@@ -324,8 +323,12 @@ static int add_worktree(const char *path, const char *refname,
323 struct commit *commit = NULL;
324 int is_branch = 0;
325 struct strbuf sb_name = STRBUF_INIT;
326 + struct worktree **worktrees;
327
328 - validate_worktree_add(path, opts);
328 + worktrees = get_worktrees(0);
329 + check_candidate_path(path, opts->force, worktrees, "add");
330 + free_worktrees(worktrees);
331 + worktrees = NULL;
332
333 /* is 'refname' a branch or commit? */
334 if (!opts->detach && !strbuf_check_branch_ref(&symref, refname) &&