prune --worktrees: fix expire vs worktree existence condition

`git prune --worktrees` was pruning worktrees which were non-existent OR expired, while it rather should prune those which are orphaned AND expired, as git-checkout documentation describes. Fix it. Add test 'not prune proper checkouts', which uses valid but expired worktree. Modify test 'not prune recent checkouts' to remove the worktree before pruning - link in worktrees still must survive. In older form it is useless because would pass always when the other test passes. Signed-off-by: Max Kirillov <max@max630.net> Acked-by: Duy Nguyen <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Max Kirillov committed Mar 30, 2015 at 23:47 UTC 562bc080934b1bd16099723e80cc82a0dc6356b7
2 files changed +19 -3
builtin/prune.c
+7 -3
@@ -120,11 +120,15 @@ static int prune_worktree(const char *id, struct strbuf *reason)
120 if (!stat(git_path("worktrees/%s/link", id), &st_link) &&
121 st_link.st_nlink > 1)
122 return 0;
123 - strbuf_addf(reason, _("Removing worktrees/%s: gitdir file points to non-existent location"), id);
124 - return 1;
123 + if (st.st_mtime <= expire) {
124 + strbuf_addf(reason, _("Removing worktrees/%s: gitdir file points to non-existent location"), id);
125 + return 1;
126 + } else {
127 + return 0;
128 + }
129 }
130 free(path);
127 - return st.st_mtime <= expire;
131 + return 0;
132 }
133
134 static void prune_worktrees(void)
t/t2026-prune-linked-checkouts.sh
+12
@@ -4,6 +4,10 @@ test_description='prune $GIT_DIR/worktrees'
4
5 . ./test-lib.sh
6
7 +test_expect_success initialize '
8 + git commit --allow-empty -m init
9 +'
10 +
11 test_expect_success 'prune --worktrees on normal repo' '
12 git prune --worktrees &&
13 test_must_fail git prune --worktrees abc
@@ -77,8 +81,16 @@ test_expect_success 'not prune recent checkouts' '
81 mkdir zz &&
82 mkdir -p .git/worktrees/jlm &&
83 echo "$(pwd)"/zz >.git/worktrees/jlm/gitdir &&
84 + rmdir zz &&
85 git prune --worktrees --verbose --expire=2.days.ago &&
86 test -d .git/worktrees/jlm
87 '
88
89 +test_expect_success 'not prune proper checkouts' '
90 + test_when_finished rm -r .git/worktrees &&
91 + git checkout "--to=$PWD/nop" --detach master &&
92 + git prune --worktrees &&
93 + test -d .git/worktrees/nop
94 +'
95 +
96 test_done