summaryrefslogtreecommitdiff
path: root/t/t2406-worktree-repair.sh
blob: f73741886b6d60e9fb583ce9e1b2606dbb00b31a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#!/bin/sh

test_description='test git worktree repair'

. ./test-lib.sh

test_expect_success setup '
	test_commit init
'

test_expect_success 'skip missing worktree' '
	test_when_finished "git worktree prune" &&
	git worktree add --detach missing &&
	rm -rf missing &&
	git worktree repair >out 2>err &&
	test_must_be_empty out &&
	test_must_be_empty err
'

test_expect_success 'worktree path not directory' '
	test_when_finished "git worktree prune" &&
	git worktree add --detach notdir &&
	rm -rf notdir &&
	>notdir &&
	test_must_fail git worktree repair >out 2>err &&
	test_must_be_empty out &&
	test_i18ngrep "not a directory" err
'

test_expect_success "don't clobber .git repo" '
	test_when_finished "rm -rf repo && git worktree prune" &&
	git worktree add --detach repo &&
	rm -rf repo &&
	test_create_repo repo &&
	test_must_fail git worktree repair >out 2>err &&
	test_must_be_empty out &&
	test_i18ngrep ".git is not a file" err
'

test_corrupt_gitfile () {
	butcher=$1 &&
	problem=$2 &&
	repairdir=${3:-.} &&
	test_when_finished 'rm -rf corrupt && git worktree prune' &&
	git worktree add --detach corrupt &&
	git -C corrupt rev-parse --absolute-git-dir >expect &&
	eval "$butcher" &&
	git -C "$repairdir" worktree repair >out 2>err &&
	test_i18ngrep "$problem" out &&
	test_must_be_empty err &&
	git -C corrupt rev-parse --absolute-git-dir >actual &&
	test_cmp expect actual
}

test_expect_success 'repair missing .git file' '
	test_corrupt_gitfile "rm -f corrupt/.git" ".git file broken"
'

test_expect_success 'repair bogus .git file' '
	test_corrupt_gitfile "echo \"gitdir: /nowhere\" >corrupt/.git" \
		".git file broken"
'

test_expect_success 'repair incorrect .git file' '
	test_when_finished "rm -rf other && git worktree prune" &&
	test_create_repo other &&
	other=$(git -C other rev-parse --absolute-git-dir) &&
	test_corrupt_gitfile "echo \"gitdir: $other\" >corrupt/.git" \
		".git file incorrect"
'

test_expect_success 'repair .git file from main/.git' '
	test_corrupt_gitfile "rm -f corrupt/.git" ".git file broken" .git
'

test_expect_success 'repair .git file from linked worktree' '
	test_when_finished "rm -rf other && git worktree prune" &&
	git worktree add --detach other &&
	test_corrupt_gitfile "rm -f corrupt/.git" ".git file broken" other
'

test_expect_success 'repair .git file from bare.git' '
	test_when_finished "rm -rf bare.git corrupt && git worktree prune" &&
	git clone --bare . bare.git &&
	git -C bare.git worktree add --detach ../corrupt &&
	git -C corrupt rev-parse --absolute-git-dir >expect &&
	rm -f corrupt/.git &&
	git -C bare.git worktree repair &&
	git -C corrupt rev-parse --absolute-git-dir >actual &&
	test_cmp expect actual
'

test_expect_success 'invalid worktree path' '
	test_must_fail git worktree repair /notvalid >out 2>err &&
	test_must_be_empty out &&
	test_i18ngrep "not a valid path" err
'

test_expect_success 'repo not found; .git not file' '
	test_when_finished "rm -rf not-a-worktree" &&
	test_create_repo not-a-worktree &&
	test_must_fail git worktree repair not-a-worktree >out 2>err &&
	test_must_be_empty out &&
	test_i18ngrep ".git is not a file" err
'

test_expect_success 'repo not found; .git not referencing repo' '
	test_when_finished "rm -rf side not-a-repo && git worktree prune" &&
	git worktree add --detach side &&
	sed s,\.git/worktrees/side$,not-a-repo, side/.git >side/.newgit &&
	mv side/.newgit side/.git &&
	mkdir not-a-repo &&
	test_must_fail git worktree repair side 2>err &&
	test_i18ngrep ".git file does not reference a repository" err
'

test_expect_success 'repo not found; .git file broken' '
	test_when_finished "rm -rf orig moved && git worktree prune" &&
	git worktree add --detach orig &&
	echo /invalid >orig/.git &&
	mv orig moved &&
	test_must_fail git worktree repair moved >out 2>err &&
	test_must_be_empty out &&
	test_i18ngrep ".git file broken" err
'

test_expect_success 'repair broken gitdir' '
	test_when_finished "rm -rf orig moved && git worktree prune" &&
	git worktree add --detach orig &&
	sed s,orig/\.git$,moved/.git, .git/worktrees/orig/gitdir >expect &&
	rm .git/worktrees/orig/gitdir &&
	mv orig moved &&
	git worktree repair moved >out 2>err &&
	test_cmp expect .git/worktrees/orig/gitdir &&
	test_i18ngrep "gitdir unreadable" out &&
	test_must_be_empty err
'

test_expect_success 'repair incorrect gitdir' '
	test_when_finished "rm -rf orig moved && git worktree prune" &&
	git worktree add --detach orig &&
	sed s,orig/\.git$,moved/.git, .git/worktrees/orig/gitdir >expect &&
	mv orig moved &&
	git worktree repair moved >out 2>err &&
	test_cmp expect .git/worktrees/orig/gitdir &&
	test_i18ngrep "gitdir incorrect" out &&
	test_must_be_empty err
'

test_expect_success 'repair gitdir (implicit) from linked worktree' '
	test_when_finished "rm -rf orig moved && git worktree prune" &&
	git worktree add --detach orig &&
	sed s,orig/\.git$,moved/.git, .git/worktrees/orig/gitdir >expect &&
	mv orig moved &&
	git -C moved worktree repair >out 2>err &&
	test_cmp expect .git/worktrees/orig/gitdir &&
	test_i18ngrep "gitdir incorrect" out &&
	test_must_be_empty err
'

test_expect_success 'unable to repair gitdir (implicit) from main worktree' '
	test_when_finished "rm -rf orig moved && git worktree prune" &&
	git worktree add --detach orig &&
	cat .git/worktrees/orig/gitdir >expect &&
	mv orig moved &&
	git worktree repair >out 2>err &&
	test_cmp expect .git/worktrees/orig/gitdir &&
	test_must_be_empty out &&
	test_must_be_empty err
'

test_expect_success 'repair multiple gitdir files' '
	test_when_finished "rm -rf orig1 orig2 moved1 moved2 &&
		git worktree prune" &&
	git worktree add --detach orig1 &&
	git worktree add --detach orig2 &&
	sed s,orig1/\.git$,moved1/.git, .git/worktrees/orig1/gitdir >expect1 &&
	sed s,orig2/\.git$,moved2/.git, .git/worktrees/orig2/gitdir >expect2 &&
	mv orig1 moved1 &&
	mv orig2 moved2 &&
	git worktree repair moved1 moved2 >out 2>err &&
	test_cmp expect1 .git/worktrees/orig1/gitdir &&
	test_cmp expect2 .git/worktrees/orig2/gitdir &&
	test_i18ngrep "gitdir incorrect:.*orig1/gitdir$" out &&
	test_i18ngrep "gitdir incorrect:.*orig2/gitdir$" out &&
	test_must_be_empty err
'

test_expect_success 'repair moved main and linked worktrees' '
	test_when_finished "rm -rf main side mainmoved sidemoved" &&
	test_create_repo main &&
	test_commit -C main init &&
	git -C main worktree add --detach ../side &&
	sed "s,side/\.git$,sidemoved/.git," \
		main/.git/worktrees/side/gitdir >expect-gitdir &&
	sed "s,main/.git/worktrees/side$,mainmoved/.git/worktrees/side," \
		side/.git >expect-gitfile &&
	mv main mainmoved &&
	mv side sidemoved &&
	git -C mainmoved worktree repair ../sidemoved &&
	test_cmp expect-gitdir mainmoved/.git/worktrees/side/gitdir &&
	test_cmp expect-gitfile sidemoved/.git
'

test_done