worktree prune: improve prune logic when worktree is moved
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Thu, 15 Mar 2018 16:44:12 +0000 (17:44 +0100)
committerJunio C Hamano <gitster@pobox.com>
Thu, 15 Mar 2018 19:37:48 +0000 (12:37 -0700)
Automatic detection of worktree relocation by a user (via 'mv', for
instance) was removed by 618244e160 (worktree: stop supporting moving
worktrees manually - 2016-01-22). Prior to that,
.git/worktrees/<tag>/gitdir was updated whenever the worktree was
accessed in order to let the pruning logic know that the worktree was
"active" even if it disappeared for a while (due to being located on
removable media, for instance).

"git worktree move" has come so we don't really need this, but since
it's easy to do, perhaps we could keep supporting manual worktree move
a bit longer. Notice that when a worktree is active, the "index" file
should be updated pretty often in common case. The logic is updated to
check for index mtime to see if the worktree is alive.

The old logic of checking gitdir's mtime is dropped because nobody
updates it anyway. The new corner case is, if the index file does not
exist, we immediately remove the stale worktree. But if the "index"
file does not exist, you may have a bigger problem.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/worktree.c
t/t2026-worktree-prune.sh
index 60440c41064624ba06220989eb9f6bc86ce5f6db..b1e8f0534c208e011ae915d58cbee6539956643a 100644 (file)
@@ -100,7 +100,8 @@ static int prune_worktree(const char *id, struct strbuf *reason)
        path[len] = '\0';
        if (!file_exists(path)) {
                free(path);
-               if (st.st_mtime <= expire) {
+               if (stat(git_path("worktrees/%s/index", id), &st) ||
+                   st.st_mtime <= expire) {
                        strbuf_addf(reason, _("Removing worktrees/%s: gitdir file points to non-existent location"), id);
                        return 1;
                } else {
index a0f1e3bb800ec6943648eeffb9e7ca84e328fa41..b7d6d5d45adf6067ab2f39801f658f778f9b2855 100755 (executable)
@@ -78,10 +78,9 @@ test_expect_success 'not prune locked checkout' '
 
 test_expect_success 'not prune recent checkouts' '
        test_when_finished rm -r .git/worktrees &&
-       mkdir zz &&
-       mkdir -p .git/worktrees/jlm &&
-       echo "$(pwd)"/zz >.git/worktrees/jlm/gitdir &&
-       rmdir zz &&
+       git worktree add jlm HEAD &&
+       test -d .git/worktrees/jlm &&
+       rm -rf jlm &&
        git worktree prune --verbose --expire=2.days.ago &&
        test -d .git/worktrees/jlm
 '