Beispiel #1
0
void test_refs_rename__invalid_name(void)
{
	// can not rename a reference with an invalid name
	git_reference *looked_up_ref, *renamed_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. */
	cl_assert_equal_i(
		GIT_EINVALIDSPEC,
		git_reference_rename(&renamed_ref, looked_up_ref, "Hello! I'm a very invalid name.", 0, NULL));

	/* 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(&renamed_ref, looked_up_ref, "i-will-sudo-you", 0, NULL));

	/* 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));
	cl_assert_equal_s(looked_up_ref->name, packed_test_head_name);

	git_reference_free(looked_up_ref);
}
Beispiel #2
0
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, *renamed_ref;
	git_oid oid;

	/* An existing reference... */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, "refs/heads/br2"));
	git_oid_cpy(&oid, git_reference_target(looked_up_ref));

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

	/* Check we actually renamed it */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, "refs/heads/test"));
	cl_assert_equal_s(looked_up_ref->name,  "refs/heads/test");
	cl_assert_equal_oid(&oid, git_reference_target(looked_up_ref));
	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);
}
Beispiel #3
0
int git_branch_move(git_repository *repo, const char *old_branch_name, const char *new_branch_name, int force)
{
	git_reference *reference = NULL;
	git_buf old_reference_name = GIT_BUF_INIT, new_reference_name = GIT_BUF_INIT;
	int error = 0;

	if ((error = git_buf_joinpath(&old_reference_name, GIT_REFS_HEADS_DIR, old_branch_name)) < 0)
		goto cleanup;

	/* We need to be able to return GIT_ENOTFOUND */
	if ((error = git_reference_lookup(&reference, repo, git_buf_cstr(&old_reference_name))) < 0)
		goto cleanup;

	if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0)
		goto cleanup;

	error = git_reference_rename(reference, git_buf_cstr(&new_reference_name), force);

cleanup:
	git_reference_free(reference);
	git_buf_free(&old_reference_name);
	git_buf_free(&new_reference_name);

	return error;
}
Beispiel #4
0
/**
 * ggit_ref_rename:
 * @ref: a #GgitRef.
 * @new_name: the new name.
 * @force: %TRUE to force the renaming.
 * @log_message: The one line long message to be appended to the reflog.
 * @error: a #GError for error reporting, or %NULL.
 *
 * Rename an existing reference.
 *
 * This method works for both direct and symbolic references.
 *
 * The new name will be checked for validity.
 * See `ggit_ref_create_symbolic()` for rules about valid names.
 *
 * If not error, @ref will be deleted from disk and a
 * new #GgitRef will be returned.
 *
 * The reference will be immediately renamed in-memory and on disk.
 *
 * If the `force` flag is not enabled, and there's already
 * a reference with the given name, the renaming will fail.
 *
 * IMPORTANT:
 * The user needs to write a proper reflog entry if the
 * reflog is enabled for the repository. We only rename
 * the reflog if it exists.
 *
 * Returns: (transfer full): a newly created #GgitRef.
 */
GgitRef *
ggit_ref_rename (GgitRef       *ref,
                 const gchar   *new_name,
                 gboolean       force,
                 const gchar   *log_message,
                 GError       **error)
{
	git_reference *out;
	gint ret;

	g_return_val_if_fail (ref != NULL, NULL);
	g_return_val_if_fail (new_name != NULL, NULL);
	g_return_val_if_fail (error == NULL || *error == NULL, NULL);

	force = (force != FALSE);

	ret = git_reference_rename (&out,
	                            _ggit_native_get (ref),
	                            new_name,
	                            force,
	                            log_message);

	if (ret != GIT_OK)
	{
		_ggit_error_set (error, ret);
		return NULL;
	}

	return _ggit_ref_wrap (out, FALSE);
}
Beispiel #5
0
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, *renamed_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);

	git_oid_cpy(&id, git_reference_target(ref));

	/* Create loose references */
	cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0, NULL));

	/* 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(&renamed_ref, looked_up_ref, ref_two_name_new, 0, NULL));
	git_reference_free(looked_up_ref);
	git_reference_free(renamed_ref);

	/* Check we actually renamed it */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new));
	cl_assert_equal_s(looked_up_ref->name, ref_two_name_new);
	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);
}
Beispiel #6
0
void test_refs_rename__move_up(void)
{
	// can move a reference to a upper reference hierarchy
	git_reference *ref, *ref_two, *looked_up_ref, *renamed_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);

	git_oid_cpy(&id, git_reference_target(ref));

	/* Create loose references */
	cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name_new, &id, 0, NULL));
	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(&renamed_ref, looked_up_ref, ref_two_name, 0, NULL));
	git_reference_free(looked_up_ref);
	git_reference_free(renamed_ref);

	/* Check we actually renamed it */
	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name));
	cl_assert_equal_s(looked_up_ref->name, ref_two_name);
	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);
}
Beispiel #7
0
void test_refs_rename__propagate_eexists(void)
{
	git_reference *ref, *new_ref;

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

	cl_assert_equal_i(GIT_EEXISTS, git_reference_rename(&new_ref, ref, packed_test_head_name, 0, NULL));

	git_reference_free(ref);
}
Beispiel #8
0
int git_branch_move(
	git_reference **out,
	git_reference *branch,
	const char *new_branch_name,
	int force)
{
	git_buf new_reference_name = GIT_BUF_INIT,
	        old_config_section = GIT_BUF_INIT,
	        new_config_section = GIT_BUF_INIT,
	        log_message = GIT_BUF_INIT;
	int error;

	assert(branch && new_branch_name);

	if (!git_reference_is_branch(branch))
		return not_a_local_branch(git_reference_name(branch));

	if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0)
		goto done;

	if ((error = git_buf_printf(&log_message, "branch: renamed %s to %s",
				    git_reference_name(branch), git_buf_cstr(&new_reference_name))) < 0)
			goto done;

	/* first update ref then config so failure won't trash config */

	error = git_reference_rename(
		out, branch, git_buf_cstr(&new_reference_name), force,
		git_buf_cstr(&log_message));
	if (error < 0)
		goto done;

	git_buf_join(&old_config_section, '.', "branch",
		git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR));
	git_buf_join(&new_config_section, '.', "branch", new_branch_name);

	error = git_config_rename_section(
		git_reference_owner(branch),
		git_buf_cstr(&old_config_section),
		git_buf_cstr(&new_config_section));

done:
	git_buf_free(&new_reference_name);
	git_buf_free(&old_config_section);
	git_buf_free(&new_config_section);
	git_buf_free(&log_message);

	return error;
}
Beispiel #9
0
int luagi_reference_gen_rename( lua_State *L, const char *tablename )
{
   git_reference **ref = luaL_checkudata( L, 1, tablename );
   const char *name = luaL_checkstring( L, 2 );
   const char *log_message = luaL_checkstring( L, 4 );
   int force = lua_toboolean( L, 5 );

   git_reference **out = lua_newuserdata( L, sizeof( git_reference * ) );
   if( git_reference_rename( out, *ref, name, force, log_message ) )
   {
      return ltk_push_git_error( L );
   }
   ltk_setmetatable( L, LUAGI_REFERENCE_FUNCS );
   return 1;
}
Beispiel #10
0
void test_refs_reflog_messages__renaming_ref(void)
{
	git_reference *ref, *new_ref;

	cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/heads/master"));
	cl_git_pass(git_reference_rename(&new_ref, ref, "refs/heads/renamed", false,
									 "message"));

	cl_reflog_check_entry(g_repo, git_reference_name(new_ref), 0,
		"a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
		"a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
		"*****@*****.**", "message");

	git_reference_free(ref);
	git_reference_free(new_ref);
}
Beispiel #11
0
static void create_fake_stash_reference_and_reflog(git_repository *repo)
{
	git_reference *master;
	git_buf log_path = GIT_BUF_INIT;

	git_buf_joinpath(&log_path, git_repository_path(repo), "logs/refs/fakestash");

	cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&log_path)));

	cl_git_pass(git_reference_lookup(&master, repo, "refs/heads/master"));
	cl_git_pass(git_reference_rename(master, "refs/fakestash", 0));

	cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&log_path)));

	git_buf_free(&log_path);
	git_reference_free(master);
}
Beispiel #12
0
void test_refs_rename__name_collision(void)
{
	// can not rename a reference with the name of an existing reference
	git_reference *looked_up_ref, *renamed_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(&renamed_ref, looked_up_ref, packed_test_head_name, 0, NULL));
	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));
	cl_assert_equal_s(looked_up_ref->name, packed_head_name);

	git_reference_free(looked_up_ref);
}
Beispiel #13
0
void test_refs_rename__writes_to_reflog(void)
{
	git_reference *ref, *new_ref;
	git_reflog *log;
	const git_reflog_entry *entry;

	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
	cl_git_pass(git_reference_rename(&new_ref, ref, ref_one_name_new, false,
				"message"));
	cl_git_pass(git_reflog_read(&log, g_repo, git_reference_name(new_ref)));
	entry = git_reflog_entry_byindex(log, 0);
	cl_assert_equal_s("message", git_reflog_entry_message(entry));
	cl_assert_equal_s("*****@*****.**", git_reflog_entry_committer(entry)->email);

	git_reflog_free(log);
	git_reference_free(ref);
	git_reference_free(new_ref);
}
Beispiel #14
0
int git_branch_move(
	git_reference *branch,
	const char *new_branch_name,
	int force)
{
	git_buf new_reference_name = GIT_BUF_INIT,
		old_config_section = GIT_BUF_INIT,
		new_config_section = GIT_BUF_INIT;
	int error;

	assert(branch && new_branch_name);

	if (!git_reference_is_branch(branch))
		return not_a_local_branch(branch);

	if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0)
		goto cleanup;

	if (git_buf_printf(
		&old_config_section,
		"branch.%s",
		git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0)
			goto cleanup;

	if ((error = git_reference_rename(branch, git_buf_cstr(&new_reference_name), force)) < 0)
		goto cleanup;

	if (git_buf_printf(&new_config_section, "branch.%s", new_branch_name) < 0)
		goto cleanup;

	if ((error = git_config_rename_section(
		git_reference_owner(branch), 
		git_buf_cstr(&old_config_section),
		git_buf_cstr(&new_config_section))) < 0)
			goto cleanup;

cleanup:
	git_buf_free(&new_reference_name);
	git_buf_free(&old_config_section);
	git_buf_free(&new_config_section);

	return error;
}
Beispiel #15
0
void test_refs_rename__packed(void)
{
	// rename a packed reference (should make it loose)
	git_reference *looked_up_ref, *new_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, git_repository_path(g_repo), packed_head_name));
	cl_assert(!git_path_exists(temp_path.ptr));

	/* 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(reference_is_packed(looked_up_ref) != 0);

	/* Now that the reference is renamed... */
	cl_git_pass(git_reference_rename(&new_ref, looked_up_ref, brand_new_name, 0, NULL));
	cl_assert_equal_s(new_ref->name, brand_new_name);
	git_reference_free(looked_up_ref);

	/* ...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));
	cl_assert_equal_s(another_looked_up_ref->name, brand_new_name);

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

	/* ...and the ref now happily lives in the file system */
	cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), brand_new_name));
	cl_assert(git_path_exists(temp_path.ptr));

	git_reference_free(new_ref);
	git_reference_free(another_looked_up_ref);
	git_buf_free(&temp_path);
}
Beispiel #16
0
void test_refs_rename__loose(void)
{
	// rename a loose reference
	git_reference *looked_up_ref, *new_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, git_repository_path(g_repo), new_name));
	cl_assert(!git_path_exists(temp_path.ptr));

	/* 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(reference_is_packed(looked_up_ref) == 0);

	/* Now that the reference is renamed... */
	cl_git_pass(git_reference_rename(&new_ref, looked_up_ref, new_name, 0, NULL));
	cl_assert_equal_s(new_ref->name, new_name);
	git_reference_free(looked_up_ref);

	/* ...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));
	cl_assert_equal_s(new_ref->name, new_name);

	/* .. the new ref is loose... */
	cl_assert(reference_is_packed(another_looked_up_ref) == 0);
	cl_assert(reference_is_packed(new_ref) == 0);

	/* ...and the ref can be found in the file system */
	cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), new_name));
	cl_assert(git_path_exists(temp_path.ptr));

	git_reference_free(new_ref);
	git_reference_free(another_looked_up_ref);
	git_buf_free(&temp_path);
}
Beispiel #17
0
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, *renamed_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, git_repository_path(g_repo), packed_test_head_name));
	cl_assert(git_path_exists(temp_path.ptr));

	/* 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(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(reference_is_packed(looked_up_ref) != 0);

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

	/* 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(reference_is_packed(another_looked_up_ref) == 0);

	/* Ensure the other ref still exists on the file system */
	cl_assert(git_path_exists(temp_path.ptr));

	git_reference_free(renamed_ref);
	git_reference_free(another_looked_up_ref);
	git_buf_free(&temp_path);
}
Beispiel #18
0
void test_refs_reflog_reflog__cannot_write_a_moved_reflog(void)
{
	git_reference *master, *new_master;
	git_buf master_log_path = GIT_BUF_INIT, moved_log_path = GIT_BUF_INIT;
	git_reflog *reflog;

	cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master"));
	cl_git_pass(git_reflog_read(&reflog, g_repo, "refs/heads/master"));

	cl_git_pass(git_reflog_write(reflog));

	cl_git_pass(git_reference_rename(&new_master, master, "refs/moved", 0, NULL));
	git_reference_free(master);

	cl_git_fail(git_reflog_write(reflog));

	git_reflog_free(reflog);
	git_reference_free(new_master);
	git_buf_dispose(&moved_log_path);
	git_buf_dispose(&master_log_path);
}
Beispiel #19
0
PyObject *
Reference_rename(Reference *self, PyObject *py_name)
{
    char *c_name;
    int err;
    git_reference *new_reference;

    CHECK_REFERENCE(self);

    /* Get the C name */
    c_name = py_path_to_c_str(py_name);
    if (c_name == NULL)
        return NULL;

    /* Rename */
    err = git_reference_rename(&new_reference, self->reference, c_name, 0);
    git_reference_free(self->reference);
    free(c_name);
    if (err < 0)
        return Error_set(err);

    self->reference = new_reference;
    Py_RETURN_NONE;
}
Beispiel #20
0
void test_refs_reflog_reflog__renaming_the_reference_moves_the_reflog(void)
{
	git_reference *master, *new_master;
	git_buf master_log_path = GIT_BUF_INIT, moved_log_path = GIT_BUF_INIT;

	git_buf_joinpath(&master_log_path, git_repository_path(g_repo), GIT_REFLOG_DIR);
	git_buf_puts(&moved_log_path, git_buf_cstr(&master_log_path));
	git_buf_joinpath(&master_log_path, git_buf_cstr(&master_log_path), "refs/heads/master");
	git_buf_joinpath(&moved_log_path, git_buf_cstr(&moved_log_path), "refs/moved");

	cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&master_log_path)));
	cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&moved_log_path)));

	cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master"));
	cl_git_pass(git_reference_rename(&new_master, master, "refs/moved", 0, NULL));
	git_reference_free(master);

	cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&master_log_path)));
	cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&moved_log_path)));

	git_reference_free(new_master);
	git_buf_dispose(&moved_log_path);
	git_buf_dispose(&master_log_path);
}
Beispiel #21
0
	const char *new_name = "refs/tags/Nemo/knows/refs.kung-fu";

	must_pass(open_temp_repo(&repo, REPOSITORY_FOLDER));

	/* Ensure the ref doesn't exist on the file system */
	git_path_join(temp_path, repo->path_repository, new_name);
	must_pass(!git_futils_exists(temp_path));

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

	/* ... which is indeed loose */
	must_be_true((looked_up_ref->type & GIT_REF_PACKED) == 0);

	/* Now that the reference is renamed... */
	must_pass(git_reference_rename(looked_up_ref, new_name, 0));
	must_be_true(!strcmp(looked_up_ref->name, new_name));

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

	/* ...but the new name works ok... */
	must_pass(git_reference_lookup(&another_looked_up_ref, repo, new_name));
	must_be_true(!strcmp(another_looked_up_ref->name, new_name));

	/* .. the ref is still loose... */
	must_be_true((another_looked_up_ref->type & GIT_REF_PACKED) == 0);
	must_be_true((looked_up_ref->type & GIT_REF_PACKED) == 0);

	/* ...and the ref can be found in the file system */
	git_path_join(temp_path, repo->path_repository, new_name);