Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nguyễn Thái Ngọc Duy 2016-06-13 19:18:24 +07:00 коммит произвёл Junio C Hamano
Родитель 346ef53058
Коммит 58142c09a4
4 изменённых файлов: 110 добавлений и 7 удалений

Просмотреть файл

@ -11,6 +11,7 @@ SYNOPSIS
[verse]
'git worktree add' [-f] [--detach] [--checkout] [-b <new-branch>] <path> [<branch>]
'git worktree list' [--porcelain]
'git worktree lock' [--reason <string>] <worktree>
'git worktree prune' [-n] [-v] [--expire <expire>]
DESCRIPTION
@ -38,9 +39,8 @@ section "DETAILS" for more information.
If a linked working tree is stored on a portable device or network share
which is not always mounted, you can prevent its administrative files from
being pruned by creating a file named 'locked' alongside the other
administrative files, optionally containing a plain text reason that
pruning should be suppressed. See section "DETAILS" for more information.
being pruned by issuing the `git worktree lock` command, optionally
specifying `--reason` to explain why the working tree is locked.
COMMANDS
--------
@ -61,6 +61,14 @@ each of the linked worktrees. The output details include if the worktree is
bare, the revision currently checked out, and the branch currently checked out
(or 'detached HEAD' if none).
lock::
If a working tree is on a portable device or network share which
is not always mounted, lock it to prevent its administrative
files from being pruned automatically. This also prevents it from
being moved or deleted. Optionally, specify a reason for the lock
with `--reason`.
prune::
Prune working tree information in $GIT_DIR/worktrees.
@ -110,6 +118,13 @@ OPTIONS
--expire <time>::
With `prune`, only expire unused working trees older than <time>.
--reason <string>::
With `lock`, an explanation why the working tree is locked.
<worktree>::
Working trees can be identified by path, either relative or
absolute.
DETAILS
-------
Each linked working tree has a private sub-directory in the repository's
@ -150,7 +165,8 @@ instead.
To prevent a $GIT_DIR/worktrees entry from being pruned (which
can be useful in some situations, such as when the
entry's working tree is stored on a portable device), add a file named
entry's working tree is stored on a portable device), use the
`git worktree lock` command, which adds a file named
'locked' to the entry's directory. The file contains the reason in
plain text. For example, if a linked working tree's `.git` file points
to `/path/main/.git/worktrees/test-next` then a file named
@ -226,8 +242,6 @@ performed manually, such as:
- `remove` to remove a linked working tree and its administrative files (and
warn if the working tree is dirty)
- `mv` to move or rename a working tree and update its administrative files
- `lock` to prevent automatic pruning of administrative files (for instance,
for a working tree on a portable device)
GIT
---

Просмотреть файл

@ -14,6 +14,7 @@
static const char * const worktree_usage[] = {
N_("git worktree add [<options>] <path> [<branch>]"),
N_("git worktree list [<options>]"),
N_("git worktree lock [<options>] <path>"),
N_("git worktree prune [<options>]"),
NULL
};
@ -459,6 +460,41 @@ static int list(int ac, const char **av, const char *prefix)
return 0;
}
static int lock_worktree(int ac, const char **av, const char *prefix)
{
const char *reason = "", *old_reason;
struct option options[] = {
OPT_STRING(0, "reason", &reason, N_("string"),
N_("reason for locking")),
OPT_END()
};
struct worktree **worktrees, *wt;
ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
if (ac != 1)
usage_with_options(worktree_usage, options);
worktrees = get_worktrees();
wt = find_worktree(worktrees, prefix, av[0]);
if (!wt)
die(_("'%s' is not a working tree"), av[0]);
if (is_main_worktree(wt))
die(_("The main working tree cannot be locked or unlocked"));
old_reason = is_worktree_locked(wt);
if (old_reason) {
if (*old_reason)
die(_("'%s' is already locked, reason: %s"),
av[0], old_reason);
die(_("'%s' is already locked"), av[0]);
}
write_file(git_common_path("worktrees/%s/locked", wt->id),
"%s", reason);
free_worktrees(worktrees);
return 0;
}
int cmd_worktree(int ac, const char **av, const char *prefix)
{
struct option options[] = {
@ -475,5 +511,7 @@ int cmd_worktree(int ac, const char **av, const char *prefix)
return prune(ac - 1, av + 1, prefix);
if (!strcmp(av[1], "list"))
return list(ac - 1, av + 1, prefix);
if (!strcmp(av[1], "lock"))
return lock_worktree(ac - 1, av + 1, prefix);
usage_with_options(worktree_usage, options);
}

Просмотреть файл

@ -2597,7 +2597,7 @@ _git_whatchanged ()
_git_worktree ()
{
local subcommands="add list prune"
local subcommands="add list lock prune"
local subcommand="$(__git_find_on_cmdline "$subcommands")"
if [ -z "$subcommand" ]; then
__gitcomp "$subcommands"
@ -2609,6 +2609,9 @@ _git_worktree ()
list,--*)
__gitcomp "--porcelain"
;;
lock,--*)
__gitcomp "--reason"
;;
prune,--*)
__gitcomp "--dry-run --expire --verbose"
;;

48
t/t2028-worktree-move.sh Executable file
Просмотреть файл

@ -0,0 +1,48 @@
#!/bin/sh
test_description='test git worktree move, remove, lock and unlock'
. ./test-lib.sh
test_expect_success 'setup' '
test_commit init &&
git worktree add source &&
git worktree list --porcelain | grep "^worktree" >actual &&
cat <<-EOF >expected &&
worktree $(pwd)
worktree $(pwd)/source
EOF
test_cmp expected actual
'
test_expect_success 'lock main worktree' '
test_must_fail git worktree lock .
'
test_expect_success 'lock linked worktree' '
git worktree lock --reason hahaha source &&
echo hahaha >expected &&
test_cmp expected .git/worktrees/source/locked
'
test_expect_success 'lock linked worktree from another worktree' '
rm .git/worktrees/source/locked &&
git worktree add elsewhere &&
git -C elsewhere worktree lock --reason hahaha ../source &&
echo hahaha >expected &&
test_cmp expected .git/worktrees/source/locked
'
test_expect_success 'lock worktree twice' '
test_must_fail git worktree lock source &&
echo hahaha >expected &&
test_cmp expected .git/worktrees/source/locked
'
test_expect_success 'lock worktree twice (from the locked worktree)' '
test_must_fail git -C source worktree lock . &&
echo hahaha >expected &&
test_cmp expected .git/worktrees/source/locked
'
test_done