]> git.proxmox.com Git - libgit2.git/blob - tests/refs/rename.c
New upstream version 1.3.0+dfsg.1
[libgit2.git] / tests / refs / rename.c
1 #include "clar_libgit2.h"
2
3 #include "futils.h"
4 #include "git2/reflog.h"
5 #include "reflog.h"
6 #include "refs.h"
7 #include "ref_helpers.h"
8
9 static const char *loose_tag_ref_name = "refs/tags/e90810b";
10 static const char *packed_head_name = "refs/heads/packed";
11 static const char *packed_test_head_name = "refs/heads/packed-test";
12 static const char *ref_one_name = "refs/heads/one/branch";
13 static const char *ref_one_name_new = "refs/heads/two/branch";
14 static const char *ref_two_name = "refs/heads/two";
15 static const char *ref_master_name = "refs/heads/master";
16 static const char *ref_two_name_new = "refs/heads/two/two";
17
18 static git_repository *g_repo;
19
20
21
22 void test_refs_rename__initialize(void)
23 {
24 g_repo = cl_git_sandbox_init("testrepo");
25 cl_git_pass(git_repository_set_ident(g_repo, "me", "foo@example.com"));
26 }
27
28 void test_refs_rename__cleanup(void)
29 {
30 cl_git_sandbox_cleanup();
31 }
32
33
34
35 void test_refs_rename__loose(void)
36 {
37 /* rename a loose reference */
38 git_reference *looked_up_ref, *new_ref, *another_looked_up_ref;
39 git_buf temp_path = GIT_BUF_INIT;
40 const char *new_name = "refs/tags/Nemo/knows/refs.kung-fu";
41
42 /* Ensure the ref doesn't exist on the file system */
43 cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), new_name));
44 cl_assert(!git_path_exists(temp_path.ptr));
45
46 /* Retrieval of the reference to rename */
47 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, loose_tag_ref_name));
48
49 /* ... which is indeed loose */
50 cl_assert(reference_is_packed(looked_up_ref) == 0);
51
52 /* Now that the reference is renamed... */
53 cl_git_pass(git_reference_rename(&new_ref, looked_up_ref, new_name, 0, NULL));
54 cl_assert_equal_s(new_ref->name, new_name);
55 git_reference_free(looked_up_ref);
56
57 /* ...It can't be looked-up with the old name... */
58 cl_git_fail(git_reference_lookup(&another_looked_up_ref, g_repo, loose_tag_ref_name));
59
60 /* ...but the new name works ok... */
61 cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, new_name));
62 cl_assert_equal_s(new_ref->name, new_name);
63
64 /* .. the new ref is loose... */
65 cl_assert(reference_is_packed(another_looked_up_ref) == 0);
66 cl_assert(reference_is_packed(new_ref) == 0);
67
68 /* ...and the ref can be found in the file system */
69 cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), new_name));
70 cl_assert(git_path_exists(temp_path.ptr));
71
72 git_reference_free(new_ref);
73 git_reference_free(another_looked_up_ref);
74 git_buf_dispose(&temp_path);
75 }
76
77 void test_refs_rename__packed(void)
78 {
79 /* rename a packed reference (should make it loose) */
80 git_reference *looked_up_ref, *new_ref, *another_looked_up_ref;
81 git_buf temp_path = GIT_BUF_INIT;
82 const char *brand_new_name = "refs/heads/brand_new_name";
83
84 /* Ensure the ref doesn't exist on the file system */
85 cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), packed_head_name));
86 cl_assert(!git_path_exists(temp_path.ptr));
87
88 /* The reference can however be looked-up... */
89 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
90
91 /* .. and it's packed */
92 cl_assert(reference_is_packed(looked_up_ref) != 0);
93
94 /* Now that the reference is renamed... */
95 cl_git_pass(git_reference_rename(&new_ref, looked_up_ref, brand_new_name, 0, NULL));
96 cl_assert_equal_s(new_ref->name, brand_new_name);
97 git_reference_free(looked_up_ref);
98
99 /* ...It can't be looked-up with the old name... */
100 cl_git_fail(git_reference_lookup(&another_looked_up_ref, g_repo, packed_head_name));
101
102 /* ...but the new name works ok... */
103 cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, brand_new_name));
104 cl_assert_equal_s(another_looked_up_ref->name, brand_new_name);
105
106 /* .. the ref is no longer packed... */
107 cl_assert(reference_is_packed(another_looked_up_ref) == 0);
108 cl_assert(reference_is_packed(new_ref) == 0);
109
110 /* ...and the ref now happily lives in the file system */
111 cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), brand_new_name));
112 cl_assert(git_path_exists(temp_path.ptr));
113
114 git_reference_free(new_ref);
115 git_reference_free(another_looked_up_ref);
116 git_buf_dispose(&temp_path);
117 }
118
119 void test_refs_rename__packed_doesnt_pack_others(void)
120 {
121 /* renaming a packed reference does not pack another reference which happens to be in both loose and pack state */
122 git_reference *looked_up_ref, *another_looked_up_ref, *renamed_ref;
123 git_buf temp_path = GIT_BUF_INIT;
124 const char *brand_new_name = "refs/heads/brand_new_name";
125
126 /* Ensure the other reference exists on the file system */
127 cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), packed_test_head_name));
128 cl_assert(git_path_exists(temp_path.ptr));
129
130 /* Lookup the other reference */
131 cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, packed_test_head_name));
132
133 /* Ensure it's loose */
134 cl_assert(reference_is_packed(another_looked_up_ref) == 0);
135 git_reference_free(another_looked_up_ref);
136
137 /* Lookup the reference to rename */
138 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
139
140 /* Ensure it's packed */
141 cl_assert(reference_is_packed(looked_up_ref) != 0);
142
143 /* Now that the reference is renamed... */
144 cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, brand_new_name, 0, NULL));
145 git_reference_free(looked_up_ref);
146
147 /* Lookup the other reference */
148 cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, packed_test_head_name));
149
150 /* Ensure it's loose */
151 cl_assert(reference_is_packed(another_looked_up_ref) == 0);
152
153 /* Ensure the other ref still exists on the file system */
154 cl_assert(git_path_exists(temp_path.ptr));
155
156 git_reference_free(renamed_ref);
157 git_reference_free(another_looked_up_ref);
158 git_buf_dispose(&temp_path);
159 }
160
161 void test_refs_rename__name_collision(void)
162 {
163 /* can not rename a reference with the name of an existing reference */
164 git_reference *looked_up_ref, *renamed_ref;
165
166 /* An existing reference... */
167 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
168
169 /* Can not be renamed to the name of another existing reference. */
170 cl_git_fail(git_reference_rename(&renamed_ref, looked_up_ref, packed_test_head_name, 0, NULL));
171 git_reference_free(looked_up_ref);
172
173 /* Failure to rename it hasn't corrupted its state */
174 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
175 cl_assert_equal_s(looked_up_ref->name, packed_head_name);
176
177 git_reference_free(looked_up_ref);
178 }
179
180 void test_refs_rename__invalid_name(void)
181 {
182 /* can not rename a reference with an invalid name */
183 git_reference *looked_up_ref, *renamed_ref;
184
185 /* An existing oid reference... */
186 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_test_head_name));
187
188 /* Can not be renamed with an invalid name. */
189 cl_assert_equal_i(
190 GIT_EINVALIDSPEC,
191 git_reference_rename(&renamed_ref, looked_up_ref, "Hello! I'm a very invalid name.", 0, NULL));
192
193 /* Can not be renamed outside of the refs hierarchy
194 * unless it's ALL_CAPS_AND_UNDERSCORES.
195 */
196 cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_rename(&renamed_ref, looked_up_ref, "i-will-sudo-you", 0, NULL));
197
198 /* Failure to rename it hasn't corrupted its state */
199 git_reference_free(looked_up_ref);
200 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_test_head_name));
201 cl_assert_equal_s(looked_up_ref->name, packed_test_head_name);
202
203 git_reference_free(looked_up_ref);
204 }
205
206 void test_refs_rename__force_loose_packed(void)
207 {
208 /* can force-rename a packed reference with the name of an existing loose and packed reference */
209 git_reference *looked_up_ref, *renamed_ref;
210 git_oid oid;
211
212 /* An existing reference... */
213 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
214 git_oid_cpy(&oid, git_reference_target(looked_up_ref));
215
216 /* Can be force-renamed to the name of another existing reference. */
217 cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, packed_test_head_name, 1, NULL));
218 git_reference_free(looked_up_ref);
219 git_reference_free(renamed_ref);
220
221 /* Check we actually renamed it */
222 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_test_head_name));
223 cl_assert_equal_s(looked_up_ref->name, packed_test_head_name);
224 cl_assert_equal_oid(&oid, git_reference_target(looked_up_ref));
225 git_reference_free(looked_up_ref);
226
227 /* And that the previous one doesn't exist any longer */
228 cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
229 }
230
231 void test_refs_rename__force_loose(void)
232 {
233 /* can force-rename a loose reference with the name of an existing loose reference */
234 git_reference *looked_up_ref, *renamed_ref;
235 git_oid oid;
236
237 /* An existing reference... */
238 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, "refs/heads/br2"));
239 git_oid_cpy(&oid, git_reference_target(looked_up_ref));
240
241 /* Can be force-renamed to the name of another existing reference. */
242 cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, "refs/heads/test", 1, NULL));
243 git_reference_free(looked_up_ref);
244 git_reference_free(renamed_ref);
245
246 /* Check we actually renamed it */
247 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, "refs/heads/test"));
248 cl_assert_equal_s(looked_up_ref->name, "refs/heads/test");
249 cl_assert_equal_oid(&oid, git_reference_target(looked_up_ref));
250 git_reference_free(looked_up_ref);
251
252 /* And that the previous one doesn't exist any longer */
253 cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, "refs/heads/br2"));
254
255 git_reference_free(looked_up_ref);
256 }
257
258
259 void test_refs_rename__overwrite(void)
260 {
261 /* can not overwrite name of existing reference */
262 git_reference *ref, *ref_one, *ref_one_new, *ref_two;
263 git_refdb *refdb;
264 git_oid id;
265
266 cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
267 cl_assert(git_reference_type(ref) & GIT_REFERENCE_DIRECT);
268
269 git_oid_cpy(&id, git_reference_target(ref));
270
271 /* Create loose references */
272 cl_git_pass(git_reference_create(&ref_one, g_repo, ref_one_name, &id, 0, NULL));
273 cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0, NULL));
274
275 /* Pack everything */
276 cl_git_pass(git_repository_refdb(&refdb, g_repo));
277 cl_git_pass(git_refdb_compress(refdb));
278
279 /* Attempt to create illegal reference */
280 cl_git_fail(git_reference_create(&ref_one_new, g_repo, ref_one_name_new, &id, 0, NULL));
281
282 /* Illegal reference couldn't be created so this is supposed to fail */
283 cl_git_fail(git_reference_lookup(&ref_one_new, g_repo, ref_one_name_new));
284
285 git_reference_free(ref);
286 git_reference_free(ref_one);
287 git_reference_free(ref_one_new);
288 git_reference_free(ref_two);
289 git_refdb_free(refdb);
290 }
291
292
293 void test_refs_rename__prefix(void)
294 {
295 /* can be renamed to a new name prefixed with the old name */
296 git_reference *ref, *ref_two, *looked_up_ref, *renamed_ref;
297 git_oid id;
298
299 cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
300 cl_assert(git_reference_type(ref) & GIT_REFERENCE_DIRECT);
301
302 git_oid_cpy(&id, git_reference_target(ref));
303
304 /* Create loose references */
305 cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0, NULL));
306
307 /* An existing reference... */
308 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name));
309
310 /* Can be rename to a new name starting with the old name. */
311 cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, ref_two_name_new, 0, NULL));
312 git_reference_free(looked_up_ref);
313 git_reference_free(renamed_ref);
314
315 /* Check we actually renamed it */
316 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new));
317 cl_assert_equal_s(looked_up_ref->name, ref_two_name_new);
318 git_reference_free(looked_up_ref);
319 cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name));
320
321 git_reference_free(ref);
322 git_reference_free(ref_two);
323 git_reference_free(looked_up_ref);
324 }
325
326 void test_refs_rename__move_up(void)
327 {
328 /* can move a reference to a upper reference hierarchy */
329 git_reference *ref, *ref_two, *looked_up_ref, *renamed_ref;
330 git_oid id;
331
332 cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
333 cl_assert(git_reference_type(ref) & GIT_REFERENCE_DIRECT);
334
335 git_oid_cpy(&id, git_reference_target(ref));
336
337 /* Create loose references */
338 cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name_new, &id, 0, NULL));
339 git_reference_free(ref_two);
340
341 /* An existing reference... */
342 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new));
343
344 /* Can be renamed upward the reference tree. */
345 cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, ref_two_name, 0, NULL));
346 git_reference_free(looked_up_ref);
347 git_reference_free(renamed_ref);
348
349 /* Check we actually renamed it */
350 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name));
351 cl_assert_equal_s(looked_up_ref->name, ref_two_name);
352 git_reference_free(looked_up_ref);
353
354 cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new));
355 git_reference_free(ref);
356 git_reference_free(looked_up_ref);
357 }
358
359 void test_refs_rename__propagate_eexists(void)
360 {
361 git_reference *ref, *new_ref;
362
363 cl_git_pass(git_reference_lookup(&ref, g_repo, packed_head_name));
364
365 cl_assert_equal_i(GIT_EEXISTS, git_reference_rename(&new_ref, ref, packed_test_head_name, 0, NULL));
366
367 git_reference_free(ref);
368 }