]> git.proxmox.com Git - libgit2.git/commitdiff
git_rebase_commit: write HEAD's reflog appropriately
authorEdward Thomson <ethomson@edwardthomson.com>
Fri, 18 Jul 2014 22:22:54 +0000 (18:22 -0400)
committerEdward Thomson <ethomson@microsoft.com>
Mon, 27 Oct 2014 02:59:27 +0000 (22:59 -0400)
src/commit.c
src/rebase.c
src/refs.c
src/refs.h
tests/rebase/merge.c

index 227d5c4a58feb75067623b42e458e1fd944af6bf..78c4b9de307fd997d2201438f89e630f573de777 100644 (file)
@@ -16,6 +16,7 @@
 #include "commit.h"
 #include "signature.h"
 #include "message.h"
+#include "refs.h"
 
 void git_commit__free(void *_commit)
 {
@@ -34,35 +35,6 @@ void git_commit__free(void *_commit)
        git__free(commit);
 }
 
-static int update_ref_for_commit(git_repository *repo, git_reference *ref, const char *update_ref, const git_oid *id, const git_signature *committer)
-{
-       git_reference *ref2 = NULL;
-       int error;
-       git_commit *c;
-       const char *shortmsg;
-       git_buf reflog_msg = GIT_BUF_INIT;
-
-       if ((error = git_commit_lookup(&c, repo, id)) < 0) {
-               return error;
-       }
-
-       shortmsg = git_commit_summary(c);
-       git_buf_printf(&reflog_msg, "commit%s: %s",
-                      git_commit_parentcount(c) == 0 ? " (initial)" : "",
-                      shortmsg);
-       git_commit_free(c);
-
-       if (ref) {
-               error = git_reference_set_target(&ref2, ref, id, committer, git_buf_cstr(&reflog_msg));
-               git_reference_free(ref2);
-       } else {
-               error = git_reference__update_terminal(repo, update_ref, id, committer, git_buf_cstr(&reflog_msg));
-       }
-
-       git_buf_free(&reflog_msg);
-       return error;
-}
-
 int git_commit_create_from_callback(
        git_oid *id,
        git_repository *repo,
@@ -131,7 +103,8 @@ int git_commit_create_from_callback(
        git_buf_free(&commit);
 
        if (update_ref != NULL) {
-               error = update_ref_for_commit(repo, ref, update_ref, id, committer);
+               error = git_reference__update_for_commit(
+                       repo, ref, update_ref, id, committer, "commit");
                git_reference_free(ref);
                return error;
        }
@@ -321,7 +294,8 @@ int git_commit_amend(
                &tree_id, commit_parent_for_amend, (void *)commit_to_amend);
 
        if (!error && update_ref) {
-               error = update_ref_for_commit(repo, ref, NULL, id, committer);
+               error = git_reference__update_for_commit(
+                       repo, ref, NULL, id, committer, "commit");
                git_reference_free(ref);
        }
 
index 101dfb107f943bfa68d1743427fa81537ef8ec3f..60c3dd02b05312456cd7512a5c127b18910fed19 100644 (file)
@@ -686,10 +686,11 @@ static int rebase_commit_merge(
 {
        git_index *index = NULL;
        git_reference *head = NULL;
-       git_commit *head_commit = NULL;
+       git_commit *head_commit = NULL, *commit = NULL;
        git_tree *head_tree = NULL, *tree = NULL;
        git_diff *diff = NULL;
        git_oid tree_id;
+       git_buf reflog_msg = GIT_BUF_INIT;
        char old_idstr[GIT_OID_HEXSZ], new_idstr[GIT_OID_HEXSZ];
        int error;
 
@@ -732,9 +733,12 @@ static int rebase_commit_merge(
                message = git_commit_message(state->merge.current);
        }
 
-       if ((error = git_commit_create(commit_id, repo, "HEAD", author,
+       if ((error = git_commit_create(commit_id, repo, NULL, author,
                        committer, message_encoding, message, tree, 1,
-                       (const git_commit **)&head_commit)) < 0)
+                       (const git_commit **)&head_commit)) < 0 ||
+               (error = git_commit_lookup(&commit, repo, commit_id)) < 0 ||
+               (error = git_reference__update_for_commit(
+                       repo, NULL, "HEAD", commit_id, committer, "rebase")) < 0)
                goto done;
 
        git_oid_fmt(old_idstr, git_commit_id(state->merge.current));
@@ -744,6 +748,8 @@ static int rebase_commit_merge(
                "%.*s %.*s\n", GIT_OID_HEXSZ, old_idstr, GIT_OID_HEXSZ, new_idstr);
 
 done:
+       git_buf_free(&reflog_msg);
+       git_commit_free(commit);
        git_diff_free(diff);
        git_tree_free(tree);
        git_tree_free(head_tree);
index 08e407e48bf0021845d024320d9937f3cd9f0f5c..43c7333f2b0fbe14ed77ef3ce1a896087b085a0f 100644 (file)
@@ -22,6 +22,7 @@
 #include <git2/refdb.h>
 #include <git2/sys/refs.h>
 #include <git2/signature.h>
+#include <git2/commit.h>
 
 GIT__USE_STRMAP;
 
@@ -1090,6 +1091,40 @@ int git_reference__update_terminal(
        return reference__update_terminal(repo, ref_name, oid, 0, signature, log_message);
 }
 
+int git_reference__update_for_commit(
+       git_repository *repo,
+       git_reference *ref,
+       const char *ref_name,
+       const git_oid *id,
+       const git_signature *committer,
+       const char *operation)
+{
+       git_reference *ref_new = NULL;
+       git_commit *commit = NULL;
+       git_buf reflog_msg = GIT_BUF_INIT;
+       int error;
+
+       if ((error = git_commit_lookup(&commit, repo, id)) < 0 ||
+               (error = git_buf_printf(&reflog_msg, "%s%s: %s",
+                       operation ? operation : "commit",
+                       git_commit_parentcount(commit) == 0 ? " (initial)" : "",
+                       git_commit_summary(commit))) < 0)
+               goto done;
+
+       if (ref)
+               error = git_reference_set_target(
+                       &ref_new, ref, id, committer, git_buf_cstr(&reflog_msg));
+       else
+               error = git_reference__update_terminal(
+                       repo, ref_name, id, committer, git_buf_cstr(&reflog_msg));
+
+done:
+       git_reference_free(ref_new);
+       git_buf_free(&reflog_msg);
+       git_commit_free(commit);
+       return error;
+}
+
 int git_reference_has_log(git_repository *repo, const char *refname)
 {
        int error;
index c6ec429a52c6f17b3b89e8b08d672dc7ba647c0a..5f48efc41aab4594b08764b7c0acc72d6e27f32a 100644 (file)
@@ -100,4 +100,13 @@ int git_reference_lookup_resolved(
 
 int git_reference__log_signature(git_signature **out, git_repository *repo);
 
+/** Update a reference after a commit. */
+int git_reference__update_for_commit(
+       git_repository *repo,
+       git_reference *ref,
+       const char *ref_name,
+       const git_oid *id,
+       const git_signature *committer,
+       const char *operation);
+
 #endif
index fa37e89e6a8d67fa665b864091df1a7d8e6fbbb4..0d4dca489432c3d96304fc6a11a089521c1cc46f 100644 (file)
@@ -178,6 +178,8 @@ void test_rebase_merge__commit(void)
        git_oid commit_id, tree_id, parent_id;
        git_signature *author;
        git_commit *commit;
+       git_reflog *reflog;
+       const git_reflog_entry *reflog_entry;
 
        checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
 
@@ -211,8 +213,14 @@ void test_rebase_merge__commit(void)
 
        cl_assert(git_signature__equal(signature, git_commit_committer(commit)));
 
-       cl_assert_equal_file("da9c51a23d02d931a486f45ad18cda05cf5d2b94 776e4c48922799f903f03f5f6e51da8b01e4cce0\n", 82, "rebase/.git/rebase-merge/rewritten");
+       /* Make sure the reflogs are updated appropriately */
+       cl_git_pass(git_reflog_read(&reflog, repo, "HEAD"));
+       cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0));
+       cl_assert_equal_oid(&parent_id, git_reflog_entry_id_old(reflog_entry));
+       cl_assert_equal_oid(&commit_id, git_reflog_entry_id_new(reflog_entry));
+       cl_assert_equal_s("rebase: Modification 1 to beef", git_reflog_entry_message(reflog_entry));
 
+       git_reflog_free(reflog);
        git_signature_free(author);
        git_commit_free(commit);
        git_merge_head_free(branch_head);