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