From 94f263f59be5be74945367b9793c57f297ed4a44 Mon Sep 17 00:00:00 2001 From: Ben Straub Date: Sat, 25 Jan 2014 08:04:49 -0800 Subject: [PATCH] Add reflog params to set-head calls --- include/git2/repository.h | 12 ++++++++++-- src/clone.c | 31 +++++++++++++++++++++---------- src/refs.c | 2 +- src/repository.c | 27 ++++++++++++++++++--------- tests/checkout/tree.c | 22 +++++++++++----------- tests/checkout/typechange.c | 4 ++-- tests/clone/nonetwork.c | 2 +- tests/repo/head.c | 16 ++++++++-------- tests/status/submodules.c | 2 +- 9 files changed, 73 insertions(+), 45 deletions(-) diff --git a/include/git2/repository.h b/include/git2/repository.h index a0453da5c..648667cd6 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -567,11 +567,15 @@ GIT_EXTERN(int) git_repository_hashfile( * * @param repo Repository pointer * @param refname Canonical name of the reference the HEAD should point at + * @param signature The identity that will used to populate the reflog entry + * @param log_message The one line long message to be appended to the reflog * @return 0 on success, or an error code */ GIT_EXTERN(int) git_repository_set_head( git_repository* repo, - const char* refname); + const char* refname, + const git_signature *signature, + const char *log_message); /** * Make the repository HEAD directly point to the Commit. @@ -587,11 +591,15 @@ GIT_EXTERN(int) git_repository_set_head( * * @param repo Repository pointer * @param commitish Object id of the Commit the HEAD should point to + * @param signature The identity that will used to populate the reflog entry + * @param log_message The one line long message to be appended to the reflog * @return 0 on success, or an error code */ GIT_EXTERN(int) git_repository_set_head_detached( git_repository* repo, - const git_oid* commitish); + const git_oid* commitish, + const git_signature *signature, + const char *log_message); /** * Detach the HEAD. diff --git a/src/clone.c b/src/clone.c index 2e9d72ab9..2bf2fc509 100644 --- a/src/clone.c +++ b/src/clone.c @@ -152,21 +152,26 @@ static int reference_matches_remote_head( static int update_head_to_new_branch( git_repository *repo, const git_oid *target, - const char *name) + const char *name, + const char *reflog_message) { git_reference *tracking_branch = NULL; int error = create_tracking_branch(&tracking_branch, repo, target, name); if (!error) error = git_repository_set_head( - repo, git_reference_name(tracking_branch)); + repo, git_reference_name(tracking_branch), + NULL, reflog_message); git_reference_free(tracking_branch); return error; } -static int update_head_to_remote(git_repository *repo, git_remote *remote) +static int update_head_to_remote( + git_repository *repo, + git_remote *remote, + const char *reflog_message) { int error = 0; size_t refs_len; @@ -215,7 +220,8 @@ static int update_head_to_remote(git_repository *repo, git_remote *remote) error = update_head_to_new_branch( repo, &head_info.remote_head_oid, - git_buf_cstr(&head_info.branchname)); + git_buf_cstr(&head_info.branchname), + reflog_message); goto cleanup; } @@ -229,10 +235,11 @@ static int update_head_to_remote(git_repository *repo, git_remote *remote) error = update_head_to_new_branch( repo, &head_info.remote_head_oid, - git_buf_cstr(&head_info.branchname)); + git_buf_cstr(&head_info.branchname), + reflog_message); } else { error = git_repository_set_head_detached( - repo, &head_info.remote_head_oid); + repo, &head_info.remote_head_oid, NULL, reflog_message); } cleanup: @@ -244,7 +251,8 @@ cleanup: static int update_head_to_branch( git_repository *repo, const char *remote_name, - const char *branch) + const char *branch, + const char *reflog_message) { int retcode; git_buf remote_branch_name = GIT_BUF_INIT; @@ -259,7 +267,7 @@ static int update_head_to_branch( if ((retcode = git_reference_lookup(&remote_ref, repo, git_buf_cstr(&remote_branch_name))) < 0) goto cleanup; - retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch); + retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch, reflog_message); cleanup: git_reference_free(remote_ref); @@ -323,6 +331,7 @@ int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_ { int error = 0, old_fetchhead; git_strarray refspecs; + git_buf reflog_message = GIT_BUF_INIT; assert(repo && remote); @@ -340,15 +349,16 @@ int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_ old_fetchhead = git_remote_update_fetchhead(remote); git_remote_set_update_fetchhead(remote, 0); + git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote)); if ((error = git_remote_fetch(remote)) != 0) goto cleanup; if (branch) - error = update_head_to_branch(repo, git_remote_name(remote), branch); + error = update_head_to_branch(repo, git_remote_name(remote), branch, git_buf_cstr(&reflog_message)); /* Point HEAD to the same ref as the remote's head */ else - error = update_head_to_remote(repo, remote); + error = update_head_to_remote(repo, remote, git_buf_cstr(&reflog_message)); if (!error && should_checkout(repo, git_repository_is_bare(repo), co_opts)) error = git_checkout_head(repo, co_opts); @@ -364,6 +374,7 @@ cleanup: } git_strarray_free(&refspecs); + git_buf_free(&reflog_message); return error; } diff --git a/src/refs.c b/src/refs.c index 0f0a380ea..65e7e6439 100644 --- a/src/refs.c +++ b/src/refs.c @@ -545,7 +545,7 @@ static int reference__rename(git_reference **out, git_reference *ref, const char /* Update HEAD it was pointing to the reference being renamed */ if (should_head_be_updated && - (error = git_repository_set_head(ref->db->repo, new_name)) < 0) { + (error = git_repository_set_head(ref->db->repo, new_name, signature, message)) < 0) { giterr_set(GITERR_REFERENCE, "Failed to update HEAD after renaming reference"); return error; } diff --git a/src/repository.c b/src/repository.c index 285d8897f..2c1b60266 100644 --- a/src/repository.c +++ b/src/repository.c @@ -1830,7 +1830,9 @@ static bool looks_like_a_branch(const char *refname) int git_repository_set_head( git_repository* repo, - const char* refname) + const char* refname, + const git_signature *signature, + const char *log_message) { git_reference *ref, *new_head = NULL; @@ -1843,12 +1845,17 @@ int git_repository_set_head( return error; if (!error) { - if (git_reference_is_branch(ref)) - error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, git_reference_name(ref), 1, NULL, NULL); - else - error = git_repository_set_head_detached(repo, git_reference_target(ref)); - } else if (looks_like_a_branch(refname)) - error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname, 1, NULL, NULL); + if (git_reference_is_branch(ref)) { + error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, + git_reference_name(ref), true, signature, log_message); + } else { + error = git_repository_set_head_detached(repo, git_reference_target(ref), + signature, log_message); + } + } else if (looks_like_a_branch(refname)) { + error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname, + true, signature, log_message); + } git_reference_free(ref); git_reference_free(new_head); @@ -1857,7 +1864,9 @@ int git_repository_set_head( int git_repository_set_head_detached( git_repository* repo, - const git_oid* commitish) + const git_oid* commitish, + const git_signature *signature, + const char *log_message) { int error; git_object *object, @@ -1872,7 +1881,7 @@ int git_repository_set_head_detached( if ((error = git_object_peel(&peeled, object, GIT_OBJ_COMMIT)) < 0) goto cleanup; - error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), 1, NULL, NULL); + error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, signature, log_message); cleanup: git_object_free(object); diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c index 3c731c5ae..4e915e824 100644 --- a/tests/checkout/tree.c +++ b/tests/checkout/tree.c @@ -63,7 +63,7 @@ void test_checkout_tree__can_checkout_and_remove_directory(void) cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees")); cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); + cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees", NULL, NULL)); cl_assert_equal_i(true, git_path_isdir("./testrepo/ab/")); cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt")); @@ -78,7 +78,7 @@ void test_checkout_tree__can_checkout_and_remove_directory(void) cl_git_pass(git_revparse_single(&g_object, g_repo, "master")); cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master")); + cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master", NULL, NULL)); /* This directory should no longer exist */ cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/")); @@ -163,7 +163,7 @@ void test_checkout_tree__can_switch_branches(void) cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY)); cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); - cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir")); + cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir", NULL, NULL)); cl_assert(git_path_isfile("testrepo/README")); cl_assert(git_path_isfile("testrepo/branch_file.txt")); @@ -183,7 +183,7 @@ void test_checkout_tree__can_switch_branches(void) cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY)); cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); - cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); + cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees", NULL, NULL)); cl_assert(git_path_isfile("testrepo/README")); cl_assert(git_path_isfile("testrepo/branch_file.txt")); @@ -253,7 +253,7 @@ static int checkout_tree_with_blob_ignored_in_workdir(int strategy, bool isdir) cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY)); cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); - cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir")); + cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir", NULL, NULL)); cl_assert(git_path_isfile("testrepo/README")); cl_assert(git_path_isfile("testrepo/branch_file.txt")); @@ -313,7 +313,7 @@ void test_checkout_tree__can_overwrite_ignored_by_default(void) { cl_git_pass(checkout_tree_with_blob_ignored_in_workdir(GIT_CHECKOUT_SAFE, false)); - cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); + cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees", NULL, NULL)); cl_assert(git_path_isfile("testrepo/ab/4.txt")); @@ -334,7 +334,7 @@ void test_checkout_tree__can_overwrite_ignored_folder_by_default(void) { cl_git_pass(checkout_tree_with_blob_ignored_in_workdir(GIT_CHECKOUT_SAFE, true)); - cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); + cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees", NULL, NULL)); cl_assert(git_path_isfile("testrepo/ab/4.txt")); @@ -367,7 +367,7 @@ void test_checkout_tree__can_update_only(void) cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY)); cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); - cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir")); + cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir", NULL, NULL)); assert_on_branch(g_repo, "dir"); @@ -396,7 +396,7 @@ void test_checkout_tree__can_checkout_with_pattern(void) cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); cl_git_pass( - git_repository_set_head_detached(g_repo, git_object_id(g_object))); + git_repository_set_head_detached(g_repo, git_object_id(g_object), NULL, NULL)); git_object_free(g_object); g_object = NULL; @@ -435,7 +435,7 @@ void test_checkout_tree__can_disable_pattern_match(void) cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); cl_git_pass( - git_repository_set_head_detached(g_repo, git_object_id(g_object))); + git_repository_set_head_detached(g_repo, git_object_id(g_object), NULL, NULL)); git_object_free(g_object); g_object = NULL; @@ -687,7 +687,7 @@ void test_checkout_tree__can_checkout_with_last_workdir_item_missing(void) cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id)); cl_git_pass(git_checkout_tree(g_repo, (git_object *)commit, &opts)); - cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master")); + cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master", NULL, NULL)); cl_git_pass(p_mkdir("./testrepo/this-is-dir", 0777)); cl_git_mkfile("./testrepo/this-is-dir/contained_file", "content\n"); diff --git a/tests/checkout/typechange.c b/tests/checkout/typechange.c index 6cf99ac15..d88864cf3 100644 --- a/tests/checkout/typechange.c +++ b/tests/checkout/typechange.c @@ -122,7 +122,7 @@ void test_checkout_typechange__checkout_typechanges_safe(void) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); cl_git_pass( - git_repository_set_head_detached(g_repo, git_object_id(obj))); + git_repository_set_head_detached(g_repo, git_object_id(obj), NULL, NULL)); assert_workdir_matches_tree(g_repo, git_object_id(obj), NULL, true); @@ -231,7 +231,7 @@ void test_checkout_typechange__checkout_with_conflicts(void) cl_assert(!git_path_exists("typechanges/untracked")); cl_git_pass( - git_repository_set_head_detached(g_repo, git_object_id(obj))); + git_repository_set_head_detached(g_repo, git_object_id(obj), NULL, NULL)); assert_workdir_matches_tree(g_repo, git_object_id(obj), NULL, true); diff --git a/tests/clone/nonetwork.c b/tests/clone/nonetwork.c index 3cd5fb7f6..863412cdb 100644 --- a/tests/clone/nonetwork.c +++ b/tests/clone/nonetwork.c @@ -217,7 +217,7 @@ void test_clone_nonetwork__can_detached_head(void) cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_revparse_single(&obj, g_repo, "master~1")); - cl_git_pass(git_repository_set_head_detached(g_repo, git_object_id(obj))); + cl_git_pass(git_repository_set_head_detached(g_repo, git_object_id(obj), NULL, NULL)); cl_git_pass(git_clone(&cloned, "./foo", "./foo1", &g_options)); diff --git a/tests/repo/head.c b/tests/repo/head.c index 101e30f10..06e837d70 100644 --- a/tests/repo/head.c +++ b/tests/repo/head.c @@ -54,7 +54,7 @@ void test_repo_head__set_head_Attaches_HEAD_to_un_unborn_branch_when_the_branch_ { git_reference *head; - cl_git_pass(git_repository_set_head(repo, "refs/heads/doesnt/exist/yet")); + cl_git_pass(git_repository_set_head(repo, "refs/heads/doesnt/exist/yet", NULL, NULL)); cl_assert_equal_i(false, git_repository_head_detached(repo)); @@ -63,19 +63,19 @@ void test_repo_head__set_head_Attaches_HEAD_to_un_unborn_branch_when_the_branch_ void test_repo_head__set_head_Returns_ENOTFOUND_when_the_reference_doesnt_exist(void) { - cl_assert_equal_i(GIT_ENOTFOUND, git_repository_set_head(repo, "refs/tags/doesnt/exist/yet")); + cl_assert_equal_i(GIT_ENOTFOUND, git_repository_set_head(repo, "refs/tags/doesnt/exist/yet", NULL, NULL)); } void test_repo_head__set_head_Fails_when_the_reference_points_to_a_non_commitish(void) { - cl_git_fail(git_repository_set_head(repo, "refs/tags/point_to_blob")); + cl_git_fail(git_repository_set_head(repo, "refs/tags/point_to_blob", NULL, NULL)); } void test_repo_head__set_head_Attaches_HEAD_when_the_reference_points_to_a_branch(void) { git_reference *head; - cl_git_pass(git_repository_set_head(repo, "refs/heads/br2")); + cl_git_pass(git_repository_set_head(repo, "refs/heads/br2", NULL, NULL)); cl_assert_equal_i(false, git_repository_head_detached(repo)); @@ -102,7 +102,7 @@ static void assert_head_is_correctly_detached(void) void test_repo_head__set_head_Detaches_HEAD_when_the_reference_doesnt_point_to_a_branch(void) { - cl_git_pass(git_repository_set_head(repo, "refs/tags/test")); + cl_git_pass(git_repository_set_head(repo, "refs/tags/test", NULL, NULL)); cl_assert_equal_i(true, git_repository_head_detached(repo)); @@ -115,7 +115,7 @@ void test_repo_head__set_head_detached_Return_ENOTFOUND_when_the_object_doesnt_e cl_git_pass(git_oid_fromstr(&oid, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); - cl_assert_equal_i(GIT_ENOTFOUND, git_repository_set_head_detached(repo, &oid)); + cl_assert_equal_i(GIT_ENOTFOUND, git_repository_set_head_detached(repo, &oid, NULL, NULL)); } void test_repo_head__set_head_detached_Fails_when_the_object_isnt_a_commitish(void) @@ -124,7 +124,7 @@ void test_repo_head__set_head_detached_Fails_when_the_object_isnt_a_commitish(vo cl_git_pass(git_revparse_single(&blob, repo, "point_to_blob")); - cl_git_fail(git_repository_set_head_detached(repo, git_object_id(blob))); + cl_git_fail(git_repository_set_head_detached(repo, git_object_id(blob), NULL, NULL)); git_object_free(blob); } @@ -136,7 +136,7 @@ void test_repo_head__set_head_detached_Detaches_HEAD_and_make_it_point_to_the_pe cl_git_pass(git_revparse_single(&tag, repo, "tags/test")); cl_assert_equal_i(GIT_OBJ_TAG, git_object_type(tag)); - cl_git_pass(git_repository_set_head_detached(repo, git_object_id(tag))); + cl_git_pass(git_repository_set_head_detached(repo, git_object_id(tag), NULL, NULL)); assert_head_is_correctly_detached(); diff --git a/tests/status/submodules.c b/tests/status/submodules.c index dc7990cf1..80ff162fd 100644 --- a/tests/status/submodules.c +++ b/tests/status/submodules.c @@ -140,7 +140,7 @@ void test_status_submodules__moved_head(void) /* move submodule HEAD to c47800c7266a2be04c571c04d5a6614691ea99bd */ cl_git_pass( git_oid_fromstr(&oid, "c47800c7266a2be04c571c04d5a6614691ea99bd")); - cl_git_pass(git_repository_set_head_detached(smrepo, &oid)); + cl_git_pass(git_repository_set_head_detached(smrepo, &oid, NULL, NULL)); /* first do a normal status, which should now include the submodule */