]> git.proxmox.com Git - libgit2.git/blame - tests/refs/rename.c
New upstream version 1.4.3+dfsg.1
[libgit2.git] / tests / refs / rename.c
CommitLineData
00a48934
BS
1#include "clar_libgit2.h"
2
22a2d3d5 3#include "futils.h"
00a48934
BS
4#include "git2/reflog.h"
5#include "reflog.h"
114f5a6c 6#include "refs.h"
d00d5464 7#include "ref_helpers.h"
00a48934
BS
8
9static const char *loose_tag_ref_name = "refs/tags/e90810b";
10static const char *packed_head_name = "refs/heads/packed";
11static const char *packed_test_head_name = "refs/heads/packed-test";
12static const char *ref_one_name = "refs/heads/one/branch";
13static const char *ref_one_name_new = "refs/heads/two/branch";
14static const char *ref_two_name = "refs/heads/two";
15static const char *ref_master_name = "refs/heads/master";
16static const char *ref_two_name_new = "refs/heads/two/two";
17
18static git_repository *g_repo;
19
20
21
22void test_refs_rename__initialize(void)
23{
6ce61a0b 24 g_repo = cl_git_sandbox_init("testrepo");
659cf202 25 cl_git_pass(git_repository_set_ident(g_repo, "me", "foo@example.com"));
00a48934
BS
26}
27
28void test_refs_rename__cleanup(void)
29{
6ce61a0b 30 cl_git_sandbox_cleanup();
00a48934
BS
31}
32
33
34
35void test_refs_rename__loose(void)
36{
ac3d33df 37 /* rename a loose reference */
d00d5464 38 git_reference *looked_up_ref, *new_ref, *another_looked_up_ref;
e579e0f7 39 git_str temp_path = GIT_STR_INIT;
00a48934
BS
40 const char *new_name = "refs/tags/Nemo/knows/refs.kung-fu";
41
42 /* Ensure the ref doesn't exist on the file system */
e579e0f7
MB
43 cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), new_name));
44 cl_assert(!git_fs_path_exists(temp_path.ptr));
00a48934
BS
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 */
d00d5464 50 cl_assert(reference_is_packed(looked_up_ref) == 0);
00a48934
BS
51
52 /* Now that the reference is renamed... */
659cf202 53 cl_git_pass(git_reference_rename(&new_ref, looked_up_ref, new_name, 0, NULL));
d00d5464
ET
54 cl_assert_equal_s(new_ref->name, new_name);
55 git_reference_free(looked_up_ref);
00a48934
BS
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));
d00d5464 62 cl_assert_equal_s(new_ref->name, new_name);
00a48934 63
d00d5464
ET
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);
00a48934
BS
67
68 /* ...and the ref can be found in the file system */
e579e0f7
MB
69 cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), new_name));
70 cl_assert(git_fs_path_exists(temp_path.ptr));
00a48934 71
d00d5464 72 git_reference_free(new_ref);
00a48934 73 git_reference_free(another_looked_up_ref);
e579e0f7 74 git_str_dispose(&temp_path);
00a48934
BS
75}
76
77void test_refs_rename__packed(void)
78{
ac3d33df 79 /* rename a packed reference (should make it loose) */
d00d5464 80 git_reference *looked_up_ref, *new_ref, *another_looked_up_ref;
e579e0f7 81 git_str temp_path = GIT_STR_INIT;
00a48934
BS
82 const char *brand_new_name = "refs/heads/brand_new_name";
83
84 /* Ensure the ref doesn't exist on the file system */
e579e0f7
MB
85 cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), packed_head_name));
86 cl_assert(!git_fs_path_exists(temp_path.ptr));
00a48934
BS
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 */
d00d5464 92 cl_assert(reference_is_packed(looked_up_ref) != 0);
00a48934
BS
93
94 /* Now that the reference is renamed... */
659cf202 95 cl_git_pass(git_reference_rename(&new_ref, looked_up_ref, brand_new_name, 0, NULL));
d00d5464
ET
96 cl_assert_equal_s(new_ref->name, brand_new_name);
97 git_reference_free(looked_up_ref);
00a48934
BS
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));
946a6dc4 104 cl_assert_equal_s(another_looked_up_ref->name, brand_new_name);
00a48934
BS
105
106 /* .. the ref is no longer packed... */
d00d5464
ET
107 cl_assert(reference_is_packed(another_looked_up_ref) == 0);
108 cl_assert(reference_is_packed(new_ref) == 0);
00a48934
BS
109
110 /* ...and the ref now happily lives in the file system */
e579e0f7
MB
111 cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), brand_new_name));
112 cl_assert(git_fs_path_exists(temp_path.ptr));
00a48934 113
d00d5464 114 git_reference_free(new_ref);
00a48934 115 git_reference_free(another_looked_up_ref);
e579e0f7 116 git_str_dispose(&temp_path);
00a48934
BS
117}
118
119void test_refs_rename__packed_doesnt_pack_others(void)
120{
ac3d33df 121 /* renaming a packed reference does not pack another reference which happens to be in both loose and pack state */
d00d5464 122 git_reference *looked_up_ref, *another_looked_up_ref, *renamed_ref;
e579e0f7 123 git_str temp_path = GIT_STR_INIT;
00a48934
BS
124 const char *brand_new_name = "refs/heads/brand_new_name";
125
126 /* Ensure the other reference exists on the file system */
e579e0f7
MB
127 cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), packed_test_head_name));
128 cl_assert(git_fs_path_exists(temp_path.ptr));
00a48934
BS
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 */
d00d5464 134 cl_assert(reference_is_packed(another_looked_up_ref) == 0);
00a48934
BS
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 */
d00d5464 141 cl_assert(reference_is_packed(looked_up_ref) != 0);
00a48934
BS
142
143 /* Now that the reference is renamed... */
659cf202 144 cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, brand_new_name, 0, NULL));
d00d5464 145 git_reference_free(looked_up_ref);
00a48934
BS
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 */
d00d5464 151 cl_assert(reference_is_packed(another_looked_up_ref) == 0);
00a48934
BS
152
153 /* Ensure the other ref still exists on the file system */
e579e0f7 154 cl_assert(git_fs_path_exists(temp_path.ptr));
00a48934 155
d00d5464 156 git_reference_free(renamed_ref);
00a48934 157 git_reference_free(another_looked_up_ref);
e579e0f7 158 git_str_dispose(&temp_path);
00a48934
BS
159}
160
161void test_refs_rename__name_collision(void)
162{
ac3d33df 163 /* can not rename a reference with the name of an existing reference */
d00d5464 164 git_reference *looked_up_ref, *renamed_ref;
00a48934
BS
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. */
659cf202 170 cl_git_fail(git_reference_rename(&renamed_ref, looked_up_ref, packed_test_head_name, 0, NULL));
00a48934
BS
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));
946a6dc4 175 cl_assert_equal_s(looked_up_ref->name, packed_head_name);
00a48934
BS
176
177 git_reference_free(looked_up_ref);
178}
179
180void test_refs_rename__invalid_name(void)
181{
ac3d33df 182 /* can not rename a reference with an invalid name */
d00d5464 183 git_reference *looked_up_ref, *renamed_ref;
00a48934
BS
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. */
80d9d1df 189 cl_assert_equal_i(
190 GIT_EINVALIDSPEC,
659cf202 191 git_reference_rename(&renamed_ref, looked_up_ref, "Hello! I'm a very invalid name.", 0, NULL));
80d9d1df 192
193 /* Can not be renamed outside of the refs hierarchy
194 * unless it's ALL_CAPS_AND_UNDERSCORES.
195 */
659cf202 196 cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_rename(&renamed_ref, looked_up_ref, "i-will-sudo-you", 0, NULL));
00a48934
BS
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));
946a6dc4 201 cl_assert_equal_s(looked_up_ref->name, packed_test_head_name);
00a48934
BS
202
203 git_reference_free(looked_up_ref);
204}
205
206void test_refs_rename__force_loose_packed(void)
207{
ac3d33df 208 /* can force-rename a packed reference with the name of an existing loose and packed reference */
d00d5464 209 git_reference *looked_up_ref, *renamed_ref;
00a48934
BS
210 git_oid oid;
211
212 /* An existing reference... */
213 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
2508cc66 214 git_oid_cpy(&oid, git_reference_target(looked_up_ref));
00a48934
BS
215
216 /* Can be force-renamed to the name of another existing reference. */
659cf202 217 cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, packed_test_head_name, 1, NULL));
00a48934 218 git_reference_free(looked_up_ref);
d00d5464 219 git_reference_free(renamed_ref);
00a48934
BS
220
221 /* Check we actually renamed it */
222 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_test_head_name));
946a6dc4 223 cl_assert_equal_s(looked_up_ref->name, packed_test_head_name);
0cee70eb 224 cl_assert_equal_oid(&oid, git_reference_target(looked_up_ref));
00a48934
BS
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
231void test_refs_rename__force_loose(void)
232{
ac3d33df 233 /* can force-rename a loose reference with the name of an existing loose reference */
d00d5464 234 git_reference *looked_up_ref, *renamed_ref;
00a48934
BS
235 git_oid oid;
236
237 /* An existing reference... */
238 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, "refs/heads/br2"));
2508cc66 239 git_oid_cpy(&oid, git_reference_target(looked_up_ref));
00a48934
BS
240
241 /* Can be force-renamed to the name of another existing reference. */
659cf202 242 cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, "refs/heads/test", 1, NULL));
00a48934 243 git_reference_free(looked_up_ref);
d00d5464 244 git_reference_free(renamed_ref);
00a48934
BS
245
246 /* Check we actually renamed it */
247 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, "refs/heads/test"));
946a6dc4 248 cl_assert_equal_s(looked_up_ref->name, "refs/heads/test");
0cee70eb 249 cl_assert_equal_oid(&oid, git_reference_target(looked_up_ref));
00a48934
BS
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
259void test_refs_rename__overwrite(void)
260{
ac3d33df 261 /* can not overwrite name of existing reference */
00a48934 262 git_reference *ref, *ref_one, *ref_one_new, *ref_two;
d00d5464 263 git_refdb *refdb;
00a48934
BS
264 git_oid id;
265
266 cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
ac3d33df 267 cl_assert(git_reference_type(ref) & GIT_REFERENCE_DIRECT);
00a48934 268
2508cc66 269 git_oid_cpy(&id, git_reference_target(ref));
00a48934
BS
270
271 /* Create loose references */
659cf202
CMN
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));
00a48934
BS
274
275 /* Pack everything */
d00d5464
ET
276 cl_git_pass(git_repository_refdb(&refdb, g_repo));
277 cl_git_pass(git_refdb_compress(refdb));
00a48934
BS
278
279 /* Attempt to create illegal reference */
659cf202 280 cl_git_fail(git_reference_create(&ref_one_new, g_repo, ref_one_name_new, &id, 0, NULL));
00a48934
BS
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);
4e4eab52 289 git_refdb_free(refdb);
00a48934
BS
290}
291
292
293void test_refs_rename__prefix(void)
294{
ac3d33df 295 /* can be renamed to a new name prefixed with the old name */
d00d5464 296 git_reference *ref, *ref_two, *looked_up_ref, *renamed_ref;
00a48934
BS
297 git_oid id;
298
299 cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
ac3d33df 300 cl_assert(git_reference_type(ref) & GIT_REFERENCE_DIRECT);
00a48934 301
2508cc66 302 git_oid_cpy(&id, git_reference_target(ref));
00a48934
BS
303
304 /* Create loose references */
659cf202 305 cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0, NULL));
00a48934
BS
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. */
659cf202 311 cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, ref_two_name_new, 0, NULL));
00a48934 312 git_reference_free(looked_up_ref);
d00d5464 313 git_reference_free(renamed_ref);
00a48934
BS
314
315 /* Check we actually renamed it */
316 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new));
946a6dc4 317 cl_assert_equal_s(looked_up_ref->name, ref_two_name_new);
00a48934
BS
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
326void test_refs_rename__move_up(void)
327{
ac3d33df 328 /* can move a reference to a upper reference hierarchy */
d00d5464 329 git_reference *ref, *ref_two, *looked_up_ref, *renamed_ref;
6ce61a0b 330 git_oid id;
00a48934 331
6ce61a0b 332 cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
ac3d33df 333 cl_assert(git_reference_type(ref) & GIT_REFERENCE_DIRECT);
00a48934 334
6ce61a0b 335 git_oid_cpy(&id, git_reference_target(ref));
00a48934 336
6ce61a0b 337 /* Create loose references */
659cf202 338 cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name_new, &id, 0, NULL));
6ce61a0b 339 git_reference_free(ref_two);
00a48934 340
6ce61a0b
SG
341 /* An existing reference... */
342 cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new));
00a48934 343
6ce61a0b 344 /* Can be renamed upward the reference tree. */
659cf202 345 cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, ref_two_name, 0, NULL));
6ce61a0b 346 git_reference_free(looked_up_ref);
d00d5464 347 git_reference_free(renamed_ref);
00a48934 348
6ce61a0b
SG
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);
d00d5464 353
6ce61a0b
SG
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);
00a48934 357}
3548fcf5 358
359void test_refs_rename__propagate_eexists(void)
360{
d00d5464 361 git_reference *ref, *new_ref;
3548fcf5 362
363 cl_git_pass(git_reference_lookup(&ref, g_repo, packed_head_name));
364
659cf202 365 cl_assert_equal_i(GIT_EEXISTS, git_reference_rename(&new_ref, ref, packed_test_head_name, 0, NULL));
3548fcf5 366
367 git_reference_free(ref);
368}