rename.c 12.2 KB
Newer Older
Ben Straub committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
#include "clar_libgit2.h"

#include "repository.h"
#include "git2/reflog.h"
#include "reflog.h"

static const char *loose_tag_ref_name = "refs/tags/e90810b";
static const char *packed_head_name = "refs/heads/packed";
static const char *packed_test_head_name = "refs/heads/packed-test";
static const char *ref_one_name = "refs/heads/one/branch";
static const char *ref_one_name_new = "refs/heads/two/branch";
static const char *ref_two_name = "refs/heads/two";
static const char *ref_master_name = "refs/heads/master";
static const char *ref_two_name_new = "refs/heads/two/two";

static git_repository *g_repo;



void test_refs_rename__initialize(void)
{
   g_repo = cl_git_sandbox_init("testrepo");
}

void test_refs_rename__cleanup(void)
{
   cl_git_sandbox_cleanup();
}



void test_refs_rename__loose(void)
{
   // rename a loose reference
	git_reference *looked_up_ref, *another_looked_up_ref;
	git_buf temp_path = GIT_BUF_INIT;
	const char *new_name = "refs/tags/Nemo/knows/refs.kung-fu";

	/* Ensure the ref doesn't exist on the file system */
	cl_git_pass(git_buf_joinpath(&temp_path, g_repo->path_repository, new_name));
Vicent Martí committed
41
	cl_assert(!git_path_exists(temp_path.ptr));
Ben Straub committed
42 43 44 45 46 47 48 49 50

	/* Retrieval of the reference to rename */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, loose_tag_ref_name));

	/* ... which is indeed loose */
	cl_assert(git_reference_is_packed(looked_up_ref) == 0);

	/* Now that the reference is renamed... */
	cl_git_pass(git_reference_rename(looked_up_ref, new_name, 0));
Vicent Martí committed
51
	cl_assert_equal_s(looked_up_ref->name, new_name);
Ben Straub committed
52 53 54 55 56 57

	/* ...It can't be looked-up with the old name... */
	cl_git_fail(git_reference_lookup(&another_looked_up_ref, g_repo, loose_tag_ref_name));

	/* ...but the new name works ok... */
	cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, new_name));
Vicent Martí committed
58
	cl_assert_equal_s(another_looked_up_ref->name, new_name);
Ben Straub committed
59 60 61 62 63 64 65

	/* .. the ref is still loose... */
	cl_assert(git_reference_is_packed(another_looked_up_ref) == 0);
	cl_assert(git_reference_is_packed(looked_up_ref) == 0);

	/* ...and the ref can be found in the file system */
	cl_git_pass(git_buf_joinpath(&temp_path, g_repo->path_repository, new_name));
Vicent Martí committed
66
	cl_assert(git_path_exists(temp_path.ptr));
Ben Straub committed
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

	git_reference_free(looked_up_ref);
	git_reference_free(another_looked_up_ref);
	git_buf_free(&temp_path);
}

void test_refs_rename__packed(void)
{
   // rename a packed reference (should make it loose)
	git_reference *looked_up_ref, *another_looked_up_ref;
	git_buf temp_path = GIT_BUF_INIT;
	const char *brand_new_name = "refs/heads/brand_new_name";

	/* Ensure the ref doesn't exist on the file system */
	cl_git_pass(git_buf_joinpath(&temp_path, g_repo->path_repository, packed_head_name));
Vicent Martí committed
82
	cl_assert(!git_path_exists(temp_path.ptr));
Ben Straub committed
83 84 85 86 87 88 89 90 91

	/* The reference can however be looked-up... */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));

	/* .. and it's packed */
	cl_assert(git_reference_is_packed(looked_up_ref) != 0);

	/* Now that the reference is renamed... */
	cl_git_pass(git_reference_rename(looked_up_ref, brand_new_name, 0));
Vicent Martí committed
92
	cl_assert_equal_s(looked_up_ref->name, brand_new_name);
Ben Straub committed
93 94 95 96 97 98

	/* ...It can't be looked-up with the old name... */
	cl_git_fail(git_reference_lookup(&another_looked_up_ref, g_repo, packed_head_name));

	/* ...but the new name works ok... */
	cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, brand_new_name));
Vicent Martí committed
99
	cl_assert_equal_s(another_looked_up_ref->name, brand_new_name);
Ben Straub committed
100 101 102 103 104 105 106

	/* .. the ref is no longer packed... */
	cl_assert(git_reference_is_packed(another_looked_up_ref) == 0);
	cl_assert(git_reference_is_packed(looked_up_ref) == 0);

	/* ...and the ref now happily lives in the file system */
	cl_git_pass(git_buf_joinpath(&temp_path, g_repo->path_repository, brand_new_name));
Vicent Martí committed
107
	cl_assert(git_path_exists(temp_path.ptr));
Ben Straub committed
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

	git_reference_free(looked_up_ref);
	git_reference_free(another_looked_up_ref);
	git_buf_free(&temp_path);
}

void test_refs_rename__packed_doesnt_pack_others(void)
{
   // renaming a packed reference does not pack another reference which happens to be in both loose and pack state
	git_reference *looked_up_ref, *another_looked_up_ref;
	git_buf temp_path = GIT_BUF_INIT;
	const char *brand_new_name = "refs/heads/brand_new_name";

	/* Ensure the other reference exists on the file system */
	cl_git_pass(git_buf_joinpath(&temp_path, g_repo->path_repository, packed_test_head_name));
Vicent Martí committed
123
	cl_assert(git_path_exists(temp_path.ptr));
Ben Straub committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147

	/* Lookup the other reference */
	cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, packed_test_head_name));

	/* Ensure it's loose */
	cl_assert(git_reference_is_packed(another_looked_up_ref) == 0);
	git_reference_free(another_looked_up_ref);

	/* Lookup the reference to rename */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));

	/* Ensure it's packed */
	cl_assert(git_reference_is_packed(looked_up_ref) != 0);

	/* Now that the reference is renamed... */
	cl_git_pass(git_reference_rename(looked_up_ref, brand_new_name, 0));

	/* Lookup the other reference */
	cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, packed_test_head_name));

	/* Ensure it's loose */
	cl_assert(git_reference_is_packed(another_looked_up_ref) == 0);

	/* Ensure the other ref still exists on the file system */
Vicent Martí committed
148
	cl_assert(git_path_exists(temp_path.ptr));
Ben Straub committed
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168

	git_reference_free(looked_up_ref);
	git_reference_free(another_looked_up_ref);
	git_buf_free(&temp_path);
}

void test_refs_rename__name_collision(void)
{
   // can not rename a reference with the name of an existing reference
	git_reference *looked_up_ref;

	/* An existing reference... */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));

	/* Can not be renamed to the name of another existing reference. */
	cl_git_fail(git_reference_rename(looked_up_ref, packed_test_head_name, 0));
	git_reference_free(looked_up_ref);

	/* Failure to rename it hasn't corrupted its state */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
Vicent Martí committed
169
	cl_assert_equal_s(looked_up_ref->name, packed_head_name);
Ben Straub committed
170 171 172 173 174 175 176 177 178 179 180 181 182

	git_reference_free(looked_up_ref);
}

void test_refs_rename__invalid_name(void)
{
   // can not rename a reference with an invalid name
	git_reference *looked_up_ref;

	/* An existing oid reference... */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_test_head_name));

	/* Can not be renamed with an invalid name. */
183 184 185 186 187 188 189 190
	cl_assert_equal_i(
		GIT_EINVALIDSPEC,
		git_reference_rename(looked_up_ref, "Hello! I'm a very invalid name.", 0));

	/* Can not be renamed outside of the refs hierarchy
	 * unless it's ALL_CAPS_AND_UNDERSCORES.
	 */
	cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_rename(looked_up_ref, "i-will-sudo-you", 0));
Ben Straub committed
191 192 193 194

	/* Failure to rename it hasn't corrupted its state */
	git_reference_free(looked_up_ref);
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_test_head_name));
Vicent Martí committed
195
	cl_assert_equal_s(looked_up_ref->name, packed_test_head_name);
Ben Straub committed
196 197 198 199 200 201 202 203 204 205 206 207

	git_reference_free(looked_up_ref);
}

void test_refs_rename__force_loose_packed(void)
{
   // can force-rename a packed reference with the name of an existing loose and packed reference
	git_reference *looked_up_ref;
	git_oid oid;

	/* An existing reference... */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
208
	git_oid_cpy(&oid, git_reference_target(looked_up_ref));
Ben Straub committed
209 210 211 212 213 214 215

	/* Can be force-renamed to the name of another existing reference. */
	cl_git_pass(git_reference_rename(looked_up_ref, packed_test_head_name, 1));
	git_reference_free(looked_up_ref);

	/* Check we actually renamed it */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_test_head_name));
Vicent Martí committed
216
	cl_assert_equal_s(looked_up_ref->name, packed_test_head_name);
217
	cl_assert(!git_oid_cmp(&oid, git_reference_target(looked_up_ref)));
Ben Straub committed
218 219 220 221 222 223 224 225 226 227 228 229 230 231
	git_reference_free(looked_up_ref);

	/* And that the previous one doesn't exist any longer */
	cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
}

void test_refs_rename__force_loose(void)
{
   // can force-rename a loose reference with the name of an existing loose reference
	git_reference *looked_up_ref;
	git_oid oid;

	/* An existing reference... */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, "refs/heads/br2"));
232
	git_oid_cpy(&oid, git_reference_target(looked_up_ref));
Ben Straub committed
233 234 235 236 237 238 239

	/* Can be force-renamed to the name of another existing reference. */
   cl_git_pass(git_reference_rename(looked_up_ref, "refs/heads/test", 1));
	git_reference_free(looked_up_ref);

	/* Check we actually renamed it */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, "refs/heads/test"));
Vicent Martí committed
240
	cl_assert_equal_s(looked_up_ref->name,  "refs/heads/test");
241
	cl_assert(!git_oid_cmp(&oid, git_reference_target(looked_up_ref)));
Ben Straub committed
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
	git_reference_free(looked_up_ref);

	/* And that the previous one doesn't exist any longer */
	cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, "refs/heads/br2"));

	git_reference_free(looked_up_ref);
}


void test_refs_rename__overwrite(void)
{
   // can not overwrite name of existing reference
	git_reference *ref, *ref_one, *ref_one_new, *ref_two;
	git_oid id;

	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
	cl_assert(git_reference_type(ref) & GIT_REF_OID);

260
	git_oid_cpy(&id, git_reference_target(ref));
Ben Straub committed
261 262

	/* Create loose references */
263 264
	cl_git_pass(git_reference_create(&ref_one, g_repo, ref_one_name, &id, 0));
	cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0));
Ben Straub committed
265 266 267 268 269

	/* Pack everything */
	cl_git_pass(git_reference_packall(g_repo));

	/* Attempt to create illegal reference */
270
	cl_git_fail(git_reference_create(&ref_one_new, g_repo, ref_one_name_new, &id, 0));
Ben Straub committed
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290

	/* Illegal reference couldn't be created so this is supposed to fail */
	cl_git_fail(git_reference_lookup(&ref_one_new, g_repo, ref_one_name_new));

	git_reference_free(ref);
	git_reference_free(ref_one);
	git_reference_free(ref_one_new);
	git_reference_free(ref_two);
}


void test_refs_rename__prefix(void)
{
   // can be renamed to a new name prefixed with the old name
	git_reference *ref, *ref_two, *looked_up_ref;
	git_oid id;

	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
	cl_assert(git_reference_type(ref) & GIT_REF_OID);

291
	git_oid_cpy(&id, git_reference_target(ref));
Ben Straub committed
292 293

	/* Create loose references */
294
	cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0));
Ben Straub committed
295 296 297 298 299 300 301 302 303 304

	/* An existing reference... */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name));

	/* Can be rename to a new name starting with the old name. */
	cl_git_pass(git_reference_rename(looked_up_ref, ref_two_name_new, 0));
	git_reference_free(looked_up_ref);

	/* Check we actually renamed it */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new));
Vicent Martí committed
305
	cl_assert_equal_s(looked_up_ref->name, ref_two_name_new);
Ben Straub committed
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
	git_reference_free(looked_up_ref);
	cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name));

	git_reference_free(ref);
	git_reference_free(ref_two);
	git_reference_free(looked_up_ref);
}

void test_refs_rename__move_up(void)
{
   // can move a reference to a upper reference hierarchy
    git_reference *ref, *ref_two, *looked_up_ref;
    git_oid id;

    cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
    cl_assert(git_reference_type(ref) & GIT_REF_OID);

323
    git_oid_cpy(&id, git_reference_target(ref));
Ben Straub committed
324 325

    /* Create loose references */
326
    cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name_new, &id, 0));
Ben Straub committed
327 328 329 330 331 332 333 334 335 336 337
    git_reference_free(ref_two);

    /* An existing reference... */
    cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new));

    /* Can be renamed upward the reference tree. */
    cl_git_pass(git_reference_rename(looked_up_ref, ref_two_name, 0));
    git_reference_free(looked_up_ref);

    /* Check we actually renamed it */
    cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name));
Vicent Martí committed
338
    cl_assert_equal_s(looked_up_ref->name, ref_two_name);
Ben Straub committed
339 340 341 342 343
    git_reference_free(looked_up_ref);
    cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new));
    git_reference_free(ref);
    git_reference_free(looked_up_ref);
}
344 345 346 347 348 349 350 351 352 353 354

void test_refs_rename__propagate_eexists(void)
{
	git_reference *ref;

	cl_git_pass(git_reference_lookup(&ref, g_repo, packed_head_name));

	cl_assert_equal_i(GIT_EEXISTS, git_reference_rename(ref, packed_test_head_name, 0));

	git_reference_free(ref);
}