Commit 62d38a1ddb8081f8b46e7ff6e21ebeb0014162d6

Carlos Martín Nieto 2015-03-06T23:51:40

Add annotated commit versions of reflog-modifying functions We do not always want to put the id directly into the reflog, but we want to speicfy what a user typed. For this use-case we provide annotated version of a few functions which let the caller specify what user-friendly name was used when asking for the operation.

diff --git a/include/git2/branch.h b/include/git2/branch.h
index 06f4d2c..34354f4 100644
--- a/include/git2/branch.h
+++ b/include/git2/branch.h
@@ -55,6 +55,24 @@ GIT_EXTERN(int) git_branch_create(
 	int force);
 
 /**
+ * Create a new branch pointing at a target commit
+ *
+ * This behaves like `git_branch_create()` but takes an annotated
+ * commit, which lets you specify which extended sha syntax string was
+ * specified by a user, allowing for more exact reflog messages.
+ *
+ * See the documentation for `git_branch_create()`.
+ *
+ * @see git_branch_create
+ */
+GIT_EXTERN(int) git_branch_create_from_annotated(
+	git_reference **ref_out,
+	git_repository *repository,
+	const char *branch_name,
+	const git_annotated_commit *commit,
+	int force);
+
+/**
  * Delete an existing branch reference.
  *
  * If the branch is successfully deleted, the passed reference
diff --git a/include/git2/repository.h b/include/git2/repository.h
index e3ff3b3..ce56fef 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -630,6 +630,22 @@ GIT_EXTERN(int) git_repository_set_head_detached(
 	const git_oid* commitish);
 
 /**
+ * Make the repository HEAD directly point to the Commit.
+ *
+ * This behaves like `git_repository_set_head_detached()` but takes an
+ * annotated commit, which lets you specify which extended sha syntax
+ * string was specified by a user, allowing for more exact reflog
+ * messages.
+ *
+ * See the documentation for `git_repository_set_head_detached()`.
+ *
+ * @see git_repository_set_head_detached
+ */
+GIT_EXTERN(int) git_repository_set_head_detached_from_annotated(
+	git_repository *repo,
+	const git_annotated_commit *commitish);
+
+/**
  * Detach the HEAD.
  *
  * If the HEAD is already detached and points to a Commit, 0 is returned.
diff --git a/include/git2/reset.h b/include/git2/reset.h
index 93ac0b2..c03dbed 100644
--- a/include/git2/reset.h
+++ b/include/git2/reset.h
@@ -65,6 +65,24 @@ GIT_EXTERN(int) git_reset(
 	git_checkout_options *checkout_opts);
 
 /**
+ * Sets the current head to the specified commit oid and optionally
+ * resets the index and working tree to match.
+ *
+ * This behaves like `git_reset()` but takes an annotated commit,
+ * which lets you specify which extended sha syntax string was
+ * specified by a user, allowing for more exact reflog messages.
+ *
+ * See the documentation for `git_reset()`.
+ *
+ * @see git_reset
+ */
+GIT_EXTERN(int) git_reset_from_annotated(
+	git_repository *repo,
+	git_annotated_commit *commit,
+	git_reset_t reset_type,
+	git_checkout_options *checkout_opts);
+
+/**
  * Updates some entries in the index from the target commit tree.
  *
  * The scope of the updated entries is determined by the paths
diff --git a/src/branch.c b/src/branch.c
index a16d3a3..10be6f7 100644
--- a/src/branch.c
+++ b/src/branch.c
@@ -12,6 +12,7 @@
 #include "refspec.h"
 #include "refs.h"
 #include "remote.h"
+#include "annotated_commit.h"
 
 #include "git2/branch.h"
 
@@ -49,11 +50,12 @@ static int not_a_local_branch(const char *reference_name)
 	return -1;
 }
 
-int git_branch_create(
+static int create_branch(
 	git_reference **ref_out,
 	git_repository *repository,
 	const char *branch_name,
 	const git_commit *commit,
+	const char *from,
 	int force)
 {
 	int is_head = 0;
@@ -86,7 +88,7 @@ int git_branch_create(
 	if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0)
 		goto cleanup;
 
-	if (git_buf_printf(&log_message, "branch: Created from %s", git_oid_tostr_s(git_commit_id(commit))) < 0)
+	if (git_buf_printf(&log_message, "branch: Created from %s", from) < 0)
 		goto cleanup;
 
 	error = git_reference_create(&branch, repository,
@@ -102,6 +104,26 @@ cleanup:
 	return error;
 }
 
+int git_branch_create(
+	git_reference **ref_out,
+	git_repository *repository,
+	const char *branch_name,
+	const git_commit *commit,
+	int force)
+{
+	return create_branch(ref_out, repository, branch_name, commit, git_oid_tostr_s(git_commit_id(commit)), force);
+}
+
+int git_branch_create_from_annotated(
+	git_reference **ref_out,
+	git_repository *repository,
+	const char *branch_name,
+	const git_annotated_commit *commit,
+	int force)
+{
+	return create_branch(ref_out, repository, branch_name, commit->commit, commit->ref_name, force);
+}
+
 int git_branch_delete(git_reference *branch)
 {
 	int is_head;
diff --git a/src/repository.c b/src/repository.c
index 0cbdf08..b1f94f0 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -26,6 +26,7 @@
 #include "remote.h"
 #include "merge.h"
 #include "diff_driver.h"
+#include "annotated_commit.h"
 
 #ifdef GIT_WIN32
 # include "win32/w32_util.h"
@@ -1961,27 +1962,28 @@ cleanup:
 	return error;
 }
 
-int git_repository_set_head_detached(
-	git_repository* repo,
-	const git_oid* commitish)
+static int detach(git_repository *repo, const git_oid *id, const char *from)
 {
 	int error;
 	git_buf log_message = GIT_BUF_INIT;
 	git_object *object = NULL, *peeled = NULL;
 	git_reference *new_head = NULL, *current = NULL;
 
-	assert(repo && commitish);
+	assert(repo && id);
 
 	if ((error = git_reference_lookup(&current, repo, GIT_HEAD_FILE)) < 0)
 		return error;
 
-	if ((error = git_object_lookup(&object, repo, commitish, GIT_OBJ_ANY)) < 0)
+	if ((error = git_object_lookup(&object, repo, id, GIT_OBJ_ANY)) < 0)
 		goto cleanup;
 
 	if ((error = git_object_peel(&peeled, object, GIT_OBJ_COMMIT)) < 0)
 		goto cleanup;
 
-	if ((error = checkout_message(&log_message, current, git_oid_tostr_s(git_object_id(peeled)))) < 0)
+	if (from == NULL)
+		from = git_oid_tostr_s(git_object_id(peeled));
+
+	if ((error = checkout_message(&log_message, current, from)) < 0)
 		goto cleanup;
 
 	error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, git_buf_cstr(&log_message));
@@ -1995,6 +1997,22 @@ cleanup:
 	return error;
 }
 
+int git_repository_set_head_detached(
+	git_repository* repo,
+	const git_oid* commitish)
+{
+	return detach(repo, commitish, NULL);
+}
+
+int git_repository_set_head_detached_from_annotated(
+	git_repository *repo,
+	const git_annotated_commit *commitish)
+{
+	assert(repo && commitish);
+
+	return detach(repo, git_annotated_commit_id(commitish), commitish->ref_name);
+}
+
 int git_repository_detach_head(git_repository* repo)
 {
 	git_reference *old_head = NULL,	*new_head = NULL, *current = NULL;
diff --git a/src/reset.c b/src/reset.c
index 351ecaa..aaebf41 100644
--- a/src/reset.c
+++ b/src/reset.c
@@ -10,6 +10,7 @@
 #include "tag.h"
 #include "merge.h"
 #include "diff.h"
+#include "annotated_commit.h"
 #include "git2/reset.h"
 #include "git2/checkout.h"
 #include "git2/merge.h"
@@ -96,9 +97,10 @@ cleanup:
 	return error;
 }
 
-int git_reset(
+static int reset(
 	git_repository *repo,
 	git_object *target,
+	const char *to,
 	git_reset_t reset_type,
 	git_checkout_options *checkout_opts)
 {
@@ -139,7 +141,7 @@ int git_reset(
 		goto cleanup;
 	}
 
-	if ((error = git_buf_printf(&log_message, "reset: moving to %s", git_oid_tostr_s(git_object_id(commit)))) < 0)
+	if ((error = git_buf_printf(&log_message, "reset: moving to %s", to)) < 0)
 		return error;
 
 	/* move HEAD to the new target */
@@ -176,3 +178,21 @@ cleanup:
 
 	return error;
 }
+
+int git_reset(
+	git_repository *repo,
+	git_object *target,
+	git_reset_t reset_type,
+	git_checkout_options *checkout_opts)
+{
+	return reset(repo, target, git_oid_tostr_s(git_object_id(target)), reset_type, checkout_opts);
+}
+
+int git_reset_from_annotated(
+	git_repository *repo,
+	git_annotated_commit *commit,
+	git_reset_t reset_type,
+	git_checkout_options *checkout_opts)
+{
+	return reset(repo, (git_object *) commit->commit, commit->ref_name, reset_type, checkout_opts);
+}