Merge https://github.com/j6t/git-gui
[git.git] / t / t1460-refs-migrate.sh
blobf7c0783d30ccd61b0fee67c115193b42bb0e2c77
1 #!/bin/sh
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
9 . ./test-lib.sh
11 test_migration () {
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 &&
20 echo "$2" >expect &&
21 test_cmp expect actual
24 test_expect_success 'setup' '
25 rm -rf .git &&
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" &&
32 git init repo &&
33 test_must_fail git -C repo refs migrate foo 2>err &&
34 cat >expect <<-EOF &&
35 usage: too many arguments
36 EOF
37 test_cmp expect err
40 test_expect_success "missing ref storage format" '
41 test_when_finished "rm -rf repo" &&
42 git init repo &&
43 test_must_fail git -C repo refs migrate 2>err &&
44 cat >expect <<-EOF &&
45 usage: missing --ref-format=<format>
46 EOF
47 test_cmp expect err
50 test_expect_success "unknown ref storage format" '
51 test_when_finished "rm -rf repo" &&
52 git init repo &&
53 test_must_fail git -C repo refs migrate \
54 --ref-format=unknown 2>err &&
55 cat >expect <<-EOF &&
56 error: unknown ref storage format ${SQ}unknown${SQ}
57 EOF
58 test_cmp expect err
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"
67 then
68 continue
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 &&
76 cat >expect <<-EOF &&
77 error: repository already uses ${SQ}$from_format${SQ} format
78 EOF
79 test_cmp expect err
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 &&
89 cat >expect <<-EOF &&
90 error: migrating reflogs is not supported yet
91 EOF
92 test_cmp expect err
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
104 test_cmp expect err
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 &&
174 cat >input <<-EOF &&
175 create FOO_HEAD HEAD
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
199 done
200 done
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
243 test_done