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) &&