3 test_description
='migration of ref storage backends'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
8 TEST_PASSES_SANITIZE_LEAK
=true
12 git
-C "$1" for-each-ref
--include-root-refs \
13 --format='%(refname) %(objectname) %(symref)' >expect
&&
14 git
-C "$1" refs migrate
--ref-format="$2" &&
15 git
-C "$1" for-each-ref
--include-root-refs \
16 --format='%(refname) %(objectname) %(symref)' >actual
&&
17 test_cmp expect actual
&&
19 git
-C "$1" rev-parse
--show-ref-format >actual
&&
21 test_cmp expect actual
24 test_expect_success
'setup' '
26 # The migration does not yet support reflogs.
27 git config --global core.logAllRefUpdates false
30 test_expect_success
"superfluous arguments" '
31 test_when_finished "rm -rf repo" &&
33 test_must_fail git -C repo refs migrate foo 2>err &&
35 usage: too many arguments
40 test_expect_success
"missing ref storage format" '
41 test_when_finished "rm -rf repo" &&
43 test_must_fail git -C repo refs migrate 2>err &&
45 usage: missing --ref-format=<format>
50 test_expect_success
"unknown ref storage format" '
51 test_when_finished "rm -rf repo" &&
53 test_must_fail git -C repo refs migrate \
54 --ref-format=unknown 2>err &&
56 error: unknown ref storage format ${SQ}unknown${SQ}
61 ref_formats
="files reftable"
62 for from_format
in $ref_formats
64 for to_format
in $ref_formats
66 if test "$from_format" = "$to_format"
71 test_expect_success
"$from_format: migration to same format fails" '
72 test_when_finished "rm -rf repo" &&
73 git init --ref-format=$from_format repo &&
74 test_must_fail git -C repo refs migrate \
75 --ref-format=$from_format 2>err &&
77 error: repository already uses ${SQ}$from_format${SQ} format
82 test_expect_success
"$from_format -> $to_format: migration with reflog fails" '
83 test_when_finished "rm -rf repo" &&
84 git init --ref-format=$from_format repo &&
85 test_config -C repo core.logAllRefUpdates true &&
86 test_commit -C repo logged &&
87 test_must_fail git -C repo refs migrate \
88 --ref-format=$to_format 2>err &&
90 error: migrating reflogs is not supported yet
95 test_expect_success
"$from_format -> $to_format: migration with worktree fails" '
96 test_when_finished "rm -rf repo" &&
97 git init --ref-format=$from_format repo &&
98 git -C repo worktree add wt &&
99 test_must_fail git -C repo refs migrate \
100 --ref-format=$to_format 2>err &&
101 cat >expect <<-EOF &&
102 error: migrating repositories with worktrees is not supported yet
107 test_expect_success
"$from_format -> $to_format: unborn HEAD" '
108 test_when_finished "rm -rf repo" &&
109 git init --ref-format=$from_format repo &&
110 test_migration repo "$to_format"
113 test_expect_success
"$from_format -> $to_format: single ref" '
114 test_when_finished "rm -rf repo" &&
115 git init --ref-format=$from_format repo &&
116 test_commit -C repo initial &&
117 test_migration repo "$to_format"
120 test_expect_success
"$from_format -> $to_format: bare repository" '
121 test_when_finished "rm -rf repo repo.git" &&
122 git init --ref-format=$from_format repo &&
123 test_commit -C repo initial &&
124 git clone --ref-format=$from_format --mirror repo repo.git &&
125 test_migration repo.git "$to_format"
128 test_expect_success
"$from_format -> $to_format: dangling symref" '
129 test_when_finished "rm -rf repo" &&
130 git init --ref-format=$from_format repo &&
131 test_commit -C repo initial &&
132 git -C repo symbolic-ref BROKEN_HEAD refs/heads/nonexistent &&
133 test_migration repo "$to_format" &&
134 echo refs/heads/nonexistent >expect &&
135 git -C repo symbolic-ref BROKEN_HEAD >actual &&
136 test_cmp expect actual
139 test_expect_success
"$from_format -> $to_format: broken ref" '
140 test_when_finished "rm -rf repo" &&
141 git init --ref-format=$from_format repo &&
142 test_commit -C repo initial &&
143 test-tool -C repo ref-store main update-ref "" refs/heads/broken \
144 "$(test_oid 001)" "$ZERO_OID" REF_SKIP_CREATE_REFLOG,REF_SKIP_OID_VERIFICATION &&
145 test_migration repo "$to_format" &&
146 test_oid 001 >expect &&
147 git -C repo rev-parse refs/heads/broken >actual &&
148 test_cmp expect actual
151 test_expect_success
"$from_format -> $to_format: pseudo-refs" '
152 test_when_finished "rm -rf repo" &&
153 git init --ref-format=$from_format repo &&
154 test_commit -C repo initial &&
155 git -C repo update-ref FOO_HEAD HEAD &&
156 test_migration repo "$to_format"
159 test_expect_success
"$from_format -> $to_format: special refs are left alone" '
160 test_when_finished "rm -rf repo" &&
161 git init --ref-format=$from_format repo &&
162 test_commit -C repo initial &&
163 git -C repo rev-parse HEAD >repo/.git/MERGE_HEAD &&
164 git -C repo rev-parse MERGE_HEAD &&
165 test_migration repo "$to_format" &&
166 test_path_is_file repo/.git/MERGE_HEAD
169 test_expect_success
"$from_format -> $to_format: a bunch of refs" '
170 test_when_finished "rm -rf repo" &&
171 git init --ref-format=$from_format repo &&
173 test_commit -C repo initial &&
176 create refs/heads/branch-1 HEAD
177 create refs/heads/branch-2 HEAD
178 create refs/heads/branch-3 HEAD
179 create refs/heads/branch-4 HEAD
180 create refs/tags/tag-1 HEAD
181 create refs/tags/tag-2 HEAD
183 git -C repo update-ref --stdin <input &&
184 test_migration repo "$to_format"
187 test_expect_success
"$from_format -> $to_format: dry-run migration does not modify repository" '
188 test_when_finished "rm -rf repo" &&
189 git init --ref-format=$from_format repo &&
190 test_commit -C repo initial &&
191 git -C repo refs migrate --dry-run \
192 --ref-format=$to_format >output &&
193 grep "Finished dry-run migration of refs" output &&
194 test_path_is_dir repo/.git/ref_migration.* &&
195 echo $from_format >expect &&
196 git -C repo rev-parse --show-ref-format >actual &&
197 test_cmp expect actual
202 test_expect_success
'migrating from files format deletes backend files' '
203 test_when_finished "rm -rf repo" &&
204 git init --ref-format=files repo &&
205 test_commit -C repo first &&
206 git -C repo pack-refs --all &&
207 test_commit -C repo second &&
208 git -C repo update-ref ORIG_HEAD HEAD &&
209 git -C repo rev-parse HEAD >repo/.git/FETCH_HEAD &&
211 test_path_is_file repo/.git/HEAD &&
212 test_path_is_file repo/.git/ORIG_HEAD &&
213 test_path_is_file repo/.git/refs/heads/main &&
214 test_path_is_file repo/.git/packed-refs &&
216 test_migration repo reftable &&
218 echo "ref: refs/heads/.invalid" >expect &&
219 test_cmp expect repo/.git/HEAD &&
220 echo "this repository uses the reftable format" >expect &&
221 test_cmp expect repo/.git/refs/heads &&
222 test_path_is_file repo/.git/FETCH_HEAD &&
223 test_path_is_missing repo/.git/ORIG_HEAD &&
224 test_path_is_missing repo/.git/refs/heads/main &&
225 test_path_is_missing repo/.git/logs &&
226 test_path_is_missing repo/.git/packed-refs
229 test_expect_success
'migrating from reftable format deletes backend files' '
230 test_when_finished "rm -rf repo" &&
231 git init --ref-format=reftable repo &&
232 test_commit -C repo first &&
234 test_path_is_dir repo/.git/reftable &&
235 test_migration repo files &&
237 test_path_is_missing repo/.git/reftable &&
238 echo "ref: refs/heads/main" >expect &&
239 test_cmp expect repo/.git/HEAD &&
240 test_path_is_file repo/.git/refs/heads/main