Commit 62d38a1d by Carlos Martín Nieto

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.
parent d675982a
......@@ -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
......
......@@ -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.
......
......@@ -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
......
......@@ -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;
......
......@@ -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;
......
......@@ -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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment