worktree: teach `add` to accept --reason <string> with --lock

The default reason stored in the lock file, "added with --lock", is unlikely to be what the user would have given in a separate `git worktree lock` command. Allowing `--reason` to be specified along with `--lock` when adding a working tree gives the user control over the reason for locking without needing a second command. Signed-off-by: Stephen Manz <smanz@alum.mit.edu> Reviewed-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Stephen Manz committed Jul 15, 2021 at 02:32 UTC 0db4961c49bb70cef89ed3d7c90f8f5d9dfc822d
3 files changed +32 -7
Documentation/git-worktree.txt
+2 -2
@@ -9,7 +9,7 @@ git-worktree - Manage multiple working trees
9 SYNOPSIS
10 --------
11 [verse]
12 -'git worktree add' [-f] [--detach] [--checkout] [--lock] [-b <new-branch>] <path> [<commit-ish>]
12 +'git worktree add' [-f] [--detach] [--checkout] [--lock [--reason <string>]] [-b <new-branch>] <path> [<commit-ish>]
13 'git worktree list' [--porcelain]
14 'git worktree lock' [--reason <string>] <worktree>
15 'git worktree move' <worktree> <new-path>
@@ -242,7 +242,7 @@ With `list`, annotate missing working trees as prunable if they are
242 older than `<time>`.
243
244 --reason <string>::
245 - With `lock`, an explanation why the working tree is locked.
245 + With `lock` or with `add --lock`, an explanation why the working tree is locked.
246
247 <worktree>::
248 Working trees can be identified by path, either relative or
builtin/worktree.c
+16 -5
@@ -30,7 +30,7 @@ struct add_opts {
30 int detach;
31 int quiet;
32 int checkout;
33 - int keep_locked;
33 + const char *keep_locked;
34 };
35
36 static int show_only;
@@ -302,10 +302,10 @@ static int add_worktree(const char *path, const char *refname,
302 * after the preparation is over.
303 */
304 strbuf_addf(&sb, "%s/locked", sb_repo.buf);
305 - if (!opts->keep_locked)
306 - write_file(sb.buf, _("initializing"));
305 + if (opts->keep_locked)
306 + write_file(sb.buf, "%s", opts->keep_locked);
307 else
308 - write_file(sb.buf, _("added with --lock"));
308 + write_file(sb.buf, _("initializing"));
309
310 strbuf_addf(&sb_git, "%s/.git", path);
311 if (safe_create_leading_directories_const(sb_git.buf))
@@ -475,6 +475,8 @@ static int add(int ac, const char **av, const char *prefix)
475 const char *branch;
476 const char *new_branch = NULL;
477 const char *opt_track = NULL;
478 + const char *lock_reason = NULL;
479 + int keep_locked = 0;
480 struct option options[] = {
481 OPT__FORCE(&opts.force,
482 N_("checkout <branch> even if already checked out in other worktree"),
@@ -485,7 +487,9 @@ static int add(int ac, const char **av, const char *prefix)
487 N_("create or reset a branch")),
488 OPT_BOOL('d', "detach", &opts.detach, N_("detach HEAD at named commit")),
489 OPT_BOOL(0, "checkout", &opts.checkout, N_("populate the new working tree")),
488 - OPT_BOOL(0, "lock", &opts.keep_locked, N_("keep the new working tree locked")),
490 + OPT_BOOL(0, "lock", &keep_locked, N_("keep the new working tree locked")),
491 + OPT_STRING(0, "reason", &lock_reason, N_("string"),
492 + N_("reason for locking")),
493 OPT__QUIET(&opts.quiet, N_("suppress progress reporting")),
494 OPT_PASSTHRU(0, "track", &opt_track, NULL,
495 N_("set up tracking mode (see git-branch(1))"),
@@ -500,6 +504,13 @@ static int add(int ac, const char **av, const char *prefix)
504 ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
505 if (!!opts.detach + !!new_branch + !!new_branch_force > 1)
506 die(_("-b, -B, and --detach are mutually exclusive"));
507 + if (lock_reason && !keep_locked)
508 + die(_("--reason requires --lock"));
509 + if (lock_reason)
510 + opts.keep_locked = lock_reason;
511 + else if (keep_locked)
512 + opts.keep_locked = _("added with --lock");
513 +
514 if (ac < 1 || ac > 2)
515 usage_with_options(worktree_usage, options);
516
t/t2400-worktree-add.sh
+14
@@ -72,6 +72,20 @@ test_expect_success '"add" worktree with lock' '
72 test -f .git/worktrees/here-with-lock/locked
73 '
74
75 +test_expect_success '"add" worktree with lock and reason' '
76 + lock_reason="why not" &&
77 + git worktree add --detach --lock --reason "$lock_reason" here-with-lock-reason main &&
78 + test_when_finished "git worktree unlock here-with-lock-reason || :" &&
79 + test -f .git/worktrees/here-with-lock-reason/locked &&
80 + echo "$lock_reason" >expect &&
81 + test_cmp expect .git/worktrees/here-with-lock-reason/locked
82 +'
83 +
84 +test_expect_success '"add" worktree with reason but no lock' '
85 + test_must_fail git worktree add --detach --reason "why not" here-with-reason-only main &&
86 + test_path_is_missing .git/worktrees/here-with-reason-only/locked
87 +'
88 +
89 test_expect_success '"add" worktree from a subdir' '
90 (
91 mkdir sub &&