]>
git.proxmox.com Git - libgit2.git/blob - tests/refs/rename.c
1 #include "clar_libgit2.h"
4 #include "git2/reflog.h"
7 #include "ref_helpers.h"
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";
18 static git_repository
*g_repo
;
22 void test_refs_rename__initialize(void)
24 g_repo
= cl_git_sandbox_init("testrepo");
25 cl_git_pass(git_repository_set_ident(g_repo
, "me", "foo@example.com"));
28 void test_refs_rename__cleanup(void)
30 cl_git_sandbox_cleanup();
35 void test_refs_rename__loose(void)
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";
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
));
46 /* Retrieval of the reference to rename */
47 cl_git_pass(git_reference_lookup(&looked_up_ref
, g_repo
, loose_tag_ref_name
));
49 /* ... which is indeed loose */
50 cl_assert(reference_is_packed(looked_up_ref
) == 0);
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
);
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
));
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
);
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);
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
));
72 git_reference_free(new_ref
);
73 git_reference_free(another_looked_up_ref
);
74 git_buf_dispose(&temp_path
);
77 void test_refs_rename__packed(void)
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";
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
));
88 /* The reference can however be looked-up... */
89 cl_git_pass(git_reference_lookup(&looked_up_ref
, g_repo
, packed_head_name
));
91 /* .. and it's packed */
92 cl_assert(reference_is_packed(looked_up_ref
) != 0);
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
);
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
));
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
);
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);
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
));
114 git_reference_free(new_ref
);
115 git_reference_free(another_looked_up_ref
);
116 git_buf_dispose(&temp_path
);
119 void test_refs_rename__packed_doesnt_pack_others(void)
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";
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
));
130 /* Lookup the other reference */
131 cl_git_pass(git_reference_lookup(&another_looked_up_ref
, g_repo
, packed_test_head_name
));
133 /* Ensure it's loose */
134 cl_assert(reference_is_packed(another_looked_up_ref
) == 0);
135 git_reference_free(another_looked_up_ref
);
137 /* Lookup the reference to rename */
138 cl_git_pass(git_reference_lookup(&looked_up_ref
, g_repo
, packed_head_name
));
140 /* Ensure it's packed */
141 cl_assert(reference_is_packed(looked_up_ref
) != 0);
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
);
147 /* Lookup the other reference */
148 cl_git_pass(git_reference_lookup(&another_looked_up_ref
, g_repo
, packed_test_head_name
));
150 /* Ensure it's loose */
151 cl_assert(reference_is_packed(another_looked_up_ref
) == 0);
153 /* Ensure the other ref still exists on the file system */
154 cl_assert(git_path_exists(temp_path
.ptr
));
156 git_reference_free(renamed_ref
);
157 git_reference_free(another_looked_up_ref
);
158 git_buf_dispose(&temp_path
);
161 void test_refs_rename__name_collision(void)
163 /* can not rename a reference with the name of an existing reference */
164 git_reference
*looked_up_ref
, *renamed_ref
;
166 /* An existing reference... */
167 cl_git_pass(git_reference_lookup(&looked_up_ref
, g_repo
, packed_head_name
));
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
);
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
);
177 git_reference_free(looked_up_ref
);
180 void test_refs_rename__invalid_name(void)
182 /* can not rename a reference with an invalid name */
183 git_reference
*looked_up_ref
, *renamed_ref
;
185 /* An existing oid reference... */
186 cl_git_pass(git_reference_lookup(&looked_up_ref
, g_repo
, packed_test_head_name
));
188 /* Can not be renamed with an invalid name. */
191 git_reference_rename(&renamed_ref
, looked_up_ref
, "Hello! I'm a very invalid name.", 0, NULL
));
193 /* Can not be renamed outside of the refs hierarchy
194 * unless it's ALL_CAPS_AND_UNDERSCORES.
196 cl_assert_equal_i(GIT_EINVALIDSPEC
, git_reference_rename(&renamed_ref
, looked_up_ref
, "i-will-sudo-you", 0, NULL
));
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
);
203 git_reference_free(looked_up_ref
);
206 void test_refs_rename__force_loose_packed(void)
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
;
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
));
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
);
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
);
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
));
231 void test_refs_rename__force_loose(void)
233 /* can force-rename a loose reference with the name of an existing loose reference */
234 git_reference
*looked_up_ref
, *renamed_ref
;
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
));
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
);
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
);
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"));
255 git_reference_free(looked_up_ref
);
259 void test_refs_rename__overwrite(void)
261 /* can not overwrite name of existing reference */
262 git_reference
*ref
, *ref_one
, *ref_one_new
, *ref_two
;
266 cl_git_pass(git_reference_lookup(&ref
, g_repo
, ref_master_name
));
267 cl_assert(git_reference_type(ref
) & GIT_REFERENCE_DIRECT
);
269 git_oid_cpy(&id
, git_reference_target(ref
));
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
));
275 /* Pack everything */
276 cl_git_pass(git_repository_refdb(&refdb
, g_repo
));
277 cl_git_pass(git_refdb_compress(refdb
));
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
));
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
));
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
);
293 void test_refs_rename__prefix(void)
295 /* can be renamed to a new name prefixed with the old name */
296 git_reference
*ref
, *ref_two
, *looked_up_ref
, *renamed_ref
;
299 cl_git_pass(git_reference_lookup(&ref
, g_repo
, ref_master_name
));
300 cl_assert(git_reference_type(ref
) & GIT_REFERENCE_DIRECT
);
302 git_oid_cpy(&id
, git_reference_target(ref
));
304 /* Create loose references */
305 cl_git_pass(git_reference_create(&ref_two
, g_repo
, ref_two_name
, &id
, 0, NULL
));
307 /* An existing reference... */
308 cl_git_pass(git_reference_lookup(&looked_up_ref
, g_repo
, ref_two_name
));
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
);
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
));
321 git_reference_free(ref
);
322 git_reference_free(ref_two
);
323 git_reference_free(looked_up_ref
);
326 void test_refs_rename__move_up(void)
328 /* can move a reference to a upper reference hierarchy */
329 git_reference
*ref
, *ref_two
, *looked_up_ref
, *renamed_ref
;
332 cl_git_pass(git_reference_lookup(&ref
, g_repo
, ref_master_name
));
333 cl_assert(git_reference_type(ref
) & GIT_REFERENCE_DIRECT
);
335 git_oid_cpy(&id
, git_reference_target(ref
));
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
);
341 /* An existing reference... */
342 cl_git_pass(git_reference_lookup(&looked_up_ref
, g_repo
, ref_two_name_new
));
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
);
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
);
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
);
359 void test_refs_rename__propagate_eexists(void)
361 git_reference
*ref
, *new_ref
;
363 cl_git_pass(git_reference_lookup(&ref
, g_repo
, packed_head_name
));
365 cl_assert_equal_i(GIT_EEXISTS
, git_reference_rename(&new_ref
, ref
, packed_test_head_name
, 0, NULL
));
367 git_reference_free(ref
);