mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-08 23:55:44 +00:00
reset changes for merge
This commit is contained in:
parent
6f6b0c013c
commit
632d8b230b
@ -569,6 +569,22 @@ GIT_EXTERN(int) git_repository_set_head_detached(
|
||||
GIT_EXTERN(int) git_repository_detach_head(
|
||||
git_repository* repo);
|
||||
|
||||
typedef enum {
|
||||
GIT_REPOSITORY_STATE_NONE,
|
||||
GIT_REPOSITORY_STATE_MERGE,
|
||||
GIT_REPOSITORY_STATE_REVERT,
|
||||
GIT_REPOSITORY_STATE_CHERRY_PICK,
|
||||
} git_repository_state_t;
|
||||
|
||||
/**
|
||||
* Determines the status of a git repository - ie, whether an operation
|
||||
* (merge, cherry-pick, etc) is in progress.
|
||||
*
|
||||
* @param repo Repository pointer
|
||||
* @return The state of the repository
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_state(git_repository *repo);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
48
src/merge.c
Normal file
48
src/merge.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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 "repository.h"
|
||||
#include "buffer.h"
|
||||
#include "merge.h"
|
||||
#include "refs.h"
|
||||
#include "git2/repository.h"
|
||||
#include "git2/merge.h"
|
||||
#include "git2/reset.h"
|
||||
|
||||
int git_merge__cleanup(git_repository *repo)
|
||||
{
|
||||
int error = 0;
|
||||
git_buf merge_head_path = GIT_BUF_INIT,
|
||||
merge_mode_path = GIT_BUF_INIT,
|
||||
merge_msg_path = GIT_BUF_INIT;
|
||||
|
||||
assert(repo);
|
||||
|
||||
if (git_buf_joinpath(&merge_head_path, repo->path_repository, GIT_MERGE_HEAD_FILE) < 0 ||
|
||||
git_buf_joinpath(&merge_mode_path, repo->path_repository, GIT_MERGE_MODE_FILE) < 0 ||
|
||||
git_buf_joinpath(&merge_mode_path, repo->path_repository, GIT_MERGE_MODE_FILE) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_path_isfile(merge_head_path.ptr)) {
|
||||
if ((error = p_unlink(merge_head_path.ptr)) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (git_path_isfile(merge_mode_path.ptr))
|
||||
(void)p_unlink(merge_mode_path.ptr);
|
||||
|
||||
if (git_path_isfile(merge_msg_path.ptr))
|
||||
(void)p_unlink(merge_msg_path.ptr);
|
||||
|
||||
cleanup:
|
||||
git_buf_free(&merge_msg_path);
|
||||
git_buf_free(&merge_mode_path);
|
||||
git_buf_free(&merge_head_path);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
19
src/merge.h
Normal file
19
src/merge.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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_merge_h__
|
||||
#define INCLUDE_merge_h__
|
||||
|
||||
#include "git2/types.h"
|
||||
|
||||
#define GIT_MERGE_MSG_FILE "MERGE_MSG"
|
||||
#define GIT_MERGE_MODE_FILE "MERGE_MODE"
|
||||
|
||||
#define MERGE_CONFIG_FILE_MODE 0666
|
||||
|
||||
int git_merge__cleanup(git_repository *repo);
|
||||
|
||||
#endif
|
@ -28,8 +28,11 @@
|
||||
#define GIT_PACKEDREFS_FILE_MODE 0666
|
||||
|
||||
#define GIT_HEAD_FILE "HEAD"
|
||||
#define GIT_ORIG_HEAD_FILE "ORIG_HEAD"
|
||||
#define GIT_FETCH_HEAD_FILE "FETCH_HEAD"
|
||||
#define GIT_MERGE_HEAD_FILE "MERGE_HEAD"
|
||||
#define GIT_REVERT_HEAD_FILE "REVERT_HEAD"
|
||||
#define GIT_CHERRY_PICK_HEAD_FILE "CHERRY_PICK_HEAD"
|
||||
#define GIT_REFS_HEADS_MASTER_FILE GIT_REFS_HEADS_DIR "master"
|
||||
|
||||
#define GIT_REFNAME_MAX 1024
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "filter.h"
|
||||
#include "odb.h"
|
||||
#include "remote.h"
|
||||
#include "merge.h"
|
||||
|
||||
#define GIT_FILE_CONTENT_PREFIX "gitdir:"
|
||||
|
||||
@ -1348,15 +1349,13 @@ int git_repository_head_tree(git_tree **tree, git_repository *repo)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MERGE_MSG_FILE "MERGE_MSG"
|
||||
|
||||
int git_repository_message(char *buffer, size_t len, git_repository *repo)
|
||||
{
|
||||
git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT;
|
||||
struct stat st;
|
||||
int error;
|
||||
|
||||
if (git_buf_joinpath(&path, repo->path_repository, MERGE_MSG_FILE) < 0)
|
||||
if (git_buf_joinpath(&path, repo->path_repository, GIT_MERGE_MSG_FILE) < 0)
|
||||
return -1;
|
||||
|
||||
if ((error = p_stat(git_buf_cstr(&path), &st)) < 0) {
|
||||
@ -1382,7 +1381,7 @@ int git_repository_message_remove(git_repository *repo)
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
int error;
|
||||
|
||||
if (git_buf_joinpath(&path, repo->path_repository, MERGE_MSG_FILE) < 0)
|
||||
if (git_buf_joinpath(&path, repo->path_repository, GIT_MERGE_MSG_FILE) < 0)
|
||||
return -1;
|
||||
|
||||
error = p_unlink(git_buf_cstr(&path));
|
||||
@ -1541,3 +1540,24 @@ cleanup:
|
||||
git_reference_free(new_head);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_repository_state(git_repository *repo)
|
||||
{
|
||||
git_buf repo_path = GIT_BUF_INIT;
|
||||
int state = GIT_REPOSITORY_STATE_NONE;
|
||||
|
||||
assert(repo);
|
||||
|
||||
if (git_buf_puts(&repo_path, repo->path_repository) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_path_contains_file(&repo_path, GIT_MERGE_HEAD_FILE))
|
||||
state = GIT_REPOSITORY_STATE_MERGE;
|
||||
else if(git_path_contains_file(&repo_path, GIT_REVERT_HEAD_FILE))
|
||||
state = GIT_REPOSITORY_STATE_REVERT;
|
||||
else if(git_path_contains_file(&repo_path, GIT_CHERRY_PICK_HEAD_FILE))
|
||||
state = GIT_REPOSITORY_STATE_CHERRY_PICK;
|
||||
|
||||
git_buf_free(&repo_path);
|
||||
return state;
|
||||
}
|
||||
|
12
src/reset.c
12
src/reset.c
@ -8,8 +8,10 @@
|
||||
#include "common.h"
|
||||
#include "commit.h"
|
||||
#include "tag.h"
|
||||
#include "merge.h"
|
||||
#include "git2/reset.h"
|
||||
#include "git2/checkout.h"
|
||||
#include "git2/merge.h"
|
||||
|
||||
#define ERROR_MSG "Cannot perform reset"
|
||||
|
||||
@ -88,6 +90,11 @@ int git_reset(
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (reset_type == GIT_RESET_SOFT && (git_repository_state(repo) == GIT_REPOSITORY_STATE_MERGE)) {
|
||||
giterr_set(GITERR_OBJECT, "%s (soft) while in the middle of a merge.", ERROR_MSG);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
//TODO: Check for unmerged entries
|
||||
|
||||
if (update_head(repo, commit) < 0)
|
||||
@ -118,6 +125,11 @@ int git_reset(
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((error = git_merge__cleanup(repo)) < 0) {
|
||||
giterr_set(GITERR_INDEX, "%s - Failed to clean up merge data.", ERROR_MSG);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (reset_type == GIT_RESET_MIXED) {
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
|
47
tests-clar/repo/state.c
Normal file
47
tests-clar/repo/state.c
Normal file
@ -0,0 +1,47 @@
|
||||
#include "clar_libgit2.h"
|
||||
#include "buffer.h"
|
||||
#include "refs.h"
|
||||
#include "posix.h"
|
||||
|
||||
static git_repository *_repo;
|
||||
static git_buf _path;
|
||||
|
||||
void test_repo_state__initialize(void)
|
||||
{
|
||||
_repo = cl_git_sandbox_init("testrepo.git");
|
||||
}
|
||||
|
||||
void test_repo_state__cleanup(void)
|
||||
{
|
||||
cl_git_sandbox_cleanup();
|
||||
git_buf_free(&_path);
|
||||
}
|
||||
|
||||
void test_repo_state__none(void)
|
||||
{
|
||||
/* The repo should be at its default state */
|
||||
cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(_repo));
|
||||
}
|
||||
|
||||
void test_repo_state__merge(void)
|
||||
{
|
||||
|
||||
/* Then it should recognise that .git/MERGE_HEAD and friends mean their respective states */
|
||||
cl_git_pass(git_buf_joinpath(&_path, git_repository_path(_repo), GIT_MERGE_HEAD_FILE));
|
||||
cl_git_mkfile(git_buf_cstr(&_path), "dummy");
|
||||
cl_assert_equal_i(GIT_REPOSITORY_STATE_MERGE, git_repository_state(_repo));
|
||||
}
|
||||
|
||||
void test_repo_state__revert(void)
|
||||
{
|
||||
cl_git_pass(git_buf_joinpath(&_path, git_repository_path(_repo), GIT_REVERT_HEAD_FILE));
|
||||
cl_git_mkfile(git_buf_cstr(&_path), "dummy");
|
||||
cl_assert_equal_i(GIT_REPOSITORY_STATE_REVERT, git_repository_state(_repo));
|
||||
}
|
||||
|
||||
void test_repo_state__cherry_pick(void)
|
||||
{
|
||||
cl_git_pass(git_buf_joinpath(&_path, git_repository_path(_repo), GIT_CHERRY_PICK_HEAD_FILE));
|
||||
cl_git_mkfile(git_buf_cstr(&_path), "dummy");
|
||||
cl_assert_equal_i(GIT_REPOSITORY_STATE_CHERRY_PICK, git_repository_state(_repo));
|
||||
}
|
@ -58,3 +58,38 @@ void test_reset_hard__cannot_reset_in_a_bare_repository(void)
|
||||
|
||||
git_repository_free(bare);
|
||||
}
|
||||
|
||||
void test_reset_hard__cleans_up_merge(void)
|
||||
{
|
||||
git_buf merge_head_path = GIT_BUF_INIT,
|
||||
merge_msg_path = GIT_BUF_INIT,
|
||||
merge_mode_path = GIT_BUF_INIT,
|
||||
orig_head_path = GIT_BUF_INIT;
|
||||
|
||||
cl_git_pass(git_buf_joinpath(&merge_head_path, git_repository_path(repo), "MERGE_HEAD"));
|
||||
cl_git_mkfile(git_buf_cstr(&merge_head_path), "beefbeefbeefbeefbeefbeefbeefbeefbeefbeef\n");
|
||||
|
||||
cl_git_pass(git_buf_joinpath(&merge_msg_path, git_repository_path(repo), "MERGE_MSG"));
|
||||
cl_git_mkfile(git_buf_cstr(&merge_head_path), "Merge commit 0017bd4ab1ec30440b17bae1680cff124ab5f1f6\n");
|
||||
|
||||
cl_git_pass(git_buf_joinpath(&merge_msg_path, git_repository_path(repo), "MERGE_MODE"));
|
||||
cl_git_mkfile(git_buf_cstr(&merge_head_path), "");
|
||||
|
||||
cl_git_pass(git_buf_joinpath(&orig_head_path, git_repository_path(repo), "ORIG_HEAD"));
|
||||
cl_git_mkfile(git_buf_cstr(&orig_head_path), "0017bd4ab1ec30440b17bae1680cff124ab5f1f6");
|
||||
|
||||
retrieve_target_from_oid(&target, repo, "0017bd4ab1ec30440b17bae1680cff124ab5f1f6");
|
||||
cl_git_pass(git_reset(repo, target, GIT_RESET_HARD));
|
||||
|
||||
cl_assert(!git_path_exists(git_buf_cstr(&merge_head_path)));
|
||||
cl_assert(!git_path_exists(git_buf_cstr(&merge_msg_path)));
|
||||
cl_assert(!git_path_exists(git_buf_cstr(&merge_mode_path)));
|
||||
|
||||
cl_assert(git_path_exists(git_buf_cstr(&orig_head_path)));
|
||||
cl_git_pass(p_unlink(git_buf_cstr(&orig_head_path)));
|
||||
|
||||
git_buf_free(&merge_head_path);
|
||||
git_buf_free(&merge_msg_path);
|
||||
git_buf_free(&merge_mode_path);
|
||||
git_buf_free(&orig_head_path);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "clar_libgit2.h"
|
||||
#include "posix.h"
|
||||
#include "reset_helpers.h"
|
||||
#include "path.h"
|
||||
#include "repo/repo_helpers.h"
|
||||
|
||||
static git_repository *repo;
|
||||
@ -110,3 +112,14 @@ void test_reset_soft__resetting_against_an_orphaned_head_repo_makes_the_head_no_
|
||||
|
||||
git_reference_free(head);
|
||||
}
|
||||
|
||||
void test_reset_soft__fails_when_merging(void)
|
||||
{
|
||||
git_buf merge_head_path = GIT_BUF_INIT;
|
||||
|
||||
cl_git_pass(git_buf_joinpath(&merge_head_path, git_repository_path(repo), "MERGE_HEAD"));
|
||||
cl_git_mkfile(git_buf_cstr(&merge_head_path), "beefbeefbeefbeefbeefbeefbeefbeefbeefbeef\n");
|
||||
|
||||
cl_git_fail(git_reset(repo, target, GIT_RESET_SOFT));
|
||||
cl_git_pass(p_unlink(git_buf_cstr(&merge_head_path)));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user