-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #669 from nulltoken/topic/reset
Add git_reset()
- Loading branch information
Showing
11 changed files
with
380 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,5 +44,6 @@ | |
#include "git2/indexer.h" | ||
#include "git2/submodule.h" | ||
#include "git2/notes.h" | ||
#include "git2/reset.h" | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright (C) 2009-2012 the libgit2 contributors | ||
* | ||
* This file is part of libgit2, distributed under the GNU GPL v2 with | ||
* a Linking Exception. For full terms see the included COPYING file. | ||
*/ | ||
#ifndef INCLUDE_git_reset_h__ | ||
#define INCLUDE_git_reset_h__ | ||
|
||
/** | ||
* @file git2/reset.h | ||
* @brief Git reset management routines | ||
* @ingroup Git | ||
* @{ | ||
*/ | ||
GIT_BEGIN_DECL | ||
|
||
/** | ||
* Sets the current head to the specified commit oid and optionally | ||
* resets the index and working tree to match. | ||
* | ||
* When specifying a Soft kind of reset, the head will be moved to the commit. | ||
* | ||
* Specifying a Mixed kind of reset will trigger a Soft reset and the index will | ||
* be replaced with the content of the commit tree. | ||
* | ||
* TODO: Implement remaining kinds of resets. | ||
* | ||
* @param repo Repository where to perform the reset operation. | ||
* | ||
* @param target Object to which the Head should be moved to. This object | ||
* must belong to the given `repo` and can either be a git_commit or a | ||
* git_tag. When a git_tag is being passed, it should be dereferencable | ||
* to a git_commit which oid will be used as the target of the branch. | ||
* | ||
* @param reset_type Kind of reset operation to perform. | ||
* | ||
* @return GIT_SUCCESS or an error code | ||
*/ | ||
GIT_EXTERN(int) git_reset(git_repository *repo, const git_object *target, git_reset_type reset_type); | ||
|
||
/** @} */ | ||
GIT_END_DECL | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/* | ||
* Copyright (C) 2009-2012 the libgit2 contributors | ||
* | ||
* This file is part of libgit2, distributed under the GNU GPL v2 with | ||
* a Linking Exception. For full terms see the included COPYING file. | ||
*/ | ||
|
||
#include "common.h" | ||
#include "commit.h" | ||
#include "tag.h" | ||
#include "git2/reset.h" | ||
|
||
#define ERROR_MSG "Cannot perform reset" | ||
|
||
static int reset_error_invalid(const char *msg) | ||
{ | ||
giterr_set(GITERR_INVALID, "%s - %s", ERROR_MSG, msg); | ||
return -1; | ||
} | ||
|
||
int git_reset( | ||
git_repository *repo, | ||
const git_object *target, | ||
git_reset_type reset_type) | ||
{ | ||
git_otype target_type = GIT_OBJ_BAD; | ||
git_object *commit = NULL; | ||
git_index *index = NULL; | ||
git_tree *tree = NULL; | ||
int error = -1; | ||
|
||
assert(repo && target); | ||
assert(reset_type == GIT_RESET_SOFT || reset_type == GIT_RESET_MIXED); | ||
|
||
if (git_object_owner(target) != repo) | ||
return reset_error_invalid("The given target does not belong to this repository."); | ||
|
||
if (reset_type == GIT_RESET_MIXED && git_repository_is_bare(repo)) | ||
return reset_error_invalid("Mixed reset is not allowed in a bare repository."); | ||
|
||
target_type = git_object_type(target); | ||
|
||
switch (target_type) | ||
{ | ||
case GIT_OBJ_TAG: | ||
if (git_tag_peel(&commit, (git_tag *)target) < 0) | ||
goto cleanup; | ||
|
||
if (git_object_type(commit) != GIT_OBJ_COMMIT) { | ||
reset_error_invalid("The given target does not resolve to a commit."); | ||
goto cleanup; | ||
} | ||
break; | ||
|
||
case GIT_OBJ_COMMIT: | ||
commit = (git_object *)target; | ||
break; | ||
|
||
default: | ||
return reset_error_invalid("Only git_tag and git_commit objects are valid targets."); | ||
} | ||
|
||
//TODO: Check for unmerged entries | ||
|
||
if (git_reference__update(repo, git_object_id(commit), GIT_HEAD_FILE) < 0) | ||
goto cleanup; | ||
|
||
if (reset_type == GIT_RESET_SOFT) { | ||
error = 0; | ||
goto cleanup; | ||
} | ||
|
||
if (git_commit_tree(&tree, (git_commit *)commit) < 0) { | ||
giterr_set(GITERR_OBJECT, "%s - Failed to retrieve the commit tree.", ERROR_MSG); | ||
goto cleanup; | ||
} | ||
|
||
if (git_repository_index(&index, repo) < 0) { | ||
giterr_set(GITERR_OBJECT, "%s - Failed to retrieve the index.", ERROR_MSG); | ||
goto cleanup; | ||
} | ||
|
||
if (git_index_read_tree(index, tree) < 0) { | ||
giterr_set(GITERR_INDEX, "%s - Failed to update the index.", ERROR_MSG); | ||
goto cleanup; | ||
} | ||
|
||
if (git_index_write(index) < 0) { | ||
giterr_set(GITERR_INDEX, "%s - Failed to write the index.", ERROR_MSG); | ||
goto cleanup; | ||
} | ||
|
||
error = 0; | ||
|
||
cleanup: | ||
if (target_type == GIT_OBJ_TAG) | ||
git_object_free(commit); | ||
|
||
git_index_free(index); | ||
git_tree_free(tree); | ||
|
||
return error; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#include "clar_libgit2.h" | ||
#include "posix.h" | ||
#include "reset_helpers.h" | ||
#include "path.h" | ||
|
||
static git_repository *repo; | ||
static git_object *target; | ||
|
||
void test_reset_mixed__initialize(void) | ||
{ | ||
repo = cl_git_sandbox_init("attr"); | ||
target = NULL; | ||
} | ||
|
||
void test_reset_mixed__cleanup(void) | ||
{ | ||
git_object_free(target); | ||
cl_git_sandbox_cleanup(); | ||
} | ||
|
||
void test_reset_mixed__cannot_reset_in_a_bare_repository(void) | ||
{ | ||
git_repository *bare; | ||
|
||
cl_git_pass(git_repository_open(&bare, cl_fixture("testrepo.git"))); | ||
cl_assert(git_repository_is_bare(bare) == true); | ||
|
||
retrieve_target_from_oid(&target, bare, KNOWN_COMMIT_IN_BARE_REPO); | ||
|
||
cl_git_fail(git_reset(bare, target, GIT_RESET_MIXED)); | ||
|
||
git_repository_free(bare); | ||
} | ||
|
||
void test_reset_mixed__resetting_refreshes_the_index_to_the_commit_tree(void) | ||
{ | ||
unsigned int status; | ||
|
||
cl_git_pass(git_status_file(&status, repo, "macro_bad")); | ||
cl_assert(status == GIT_STATUS_CURRENT); | ||
retrieve_target_from_oid(&target, repo, "605812ab7fe421fdd325a935d35cb06a9234a7d7"); | ||
|
||
cl_git_pass(git_reset(repo, target, GIT_RESET_MIXED)); | ||
|
||
cl_git_pass(git_status_file(&status, repo, "macro_bad")); | ||
cl_assert(status == GIT_STATUS_WT_NEW); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#include "clar_libgit2.h" | ||
#include "reset_helpers.h" | ||
|
||
void retrieve_target_from_oid(git_object **object_out, git_repository *repo, const char *sha) | ||
{ | ||
git_oid oid; | ||
|
||
cl_git_pass(git_oid_fromstr(&oid, sha)); | ||
cl_git_pass(git_object_lookup(object_out, repo, &oid, GIT_OBJ_ANY)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#include "common.h" | ||
|
||
#define KNOWN_COMMIT_IN_BARE_REPO "e90810b8df3e80c413d903f631643c716887138d" | ||
#define KNOWN_COMMIT_IN_ATTR_REPO "217878ab49e1314388ea2e32dc6fdb58a1b969e0" | ||
|
||
extern void retrieve_target_from_oid(git_object **object_out, git_repository *repo, const char *sha); |
Oops, something went wrong.