Revert a git merge using libgit2sharp
In libgit2sharp, I am doing a fetch and merge for an upstream branch, and I want to be able to abort the merge, similar to:
git merge --abort
when MergeStatus:
LibGit2Sharp.MergeStatus.Conflicts
Is this possible (using v.0.20.1)? If not, does anyone know what it would take to implement something like this?
source to share
The command git-merge --abort
is a shortcut for git reset --merge
, and both git-reset --merge
and git-reset --hard
interrupt the merger and clean repository, characterized as they are updated changed files.
LibGit2Sharp does not currently offer reset, parallel merge options. However, if you use a method Repository.Reset
with a parameter ResetMode.Hard
, your merge will be aborted (albeit with semantics git-reset --hard
).
source to share
I tried to emulate reset --merge by pre-filtering the paths passed to reset --hard. I think it has the same basic semantics as reset --merge. I am doing something like this pseudocode:
// Gather list of files modified in the index.
git_diff *index_diff;
git_diff_tree_to_index(&index_diff, repo, current_head_tree, ...);
// Iterate over index_diff to produce list of changed files.
// Gather list of files modified between index and workdir.
git_diff *workdir_diff;
git_diff_index_to_workdir(&workdir_diff, ...);
// Iterate over workdir_diff looking for files in the index list.
// Any non-conflicted files that are already in the index list
// cause the whole process to be aborted with an error. Can't reset
// merged files that have unstaged changes.
// The files in the index list are the ones that need to be reset.
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy |= GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH;
opts.paths = index_list;
git_reset(repo, current_head_commit, GIT_RESET_HARD, opts);
Of course, perhaps this is not how it should be implemented in the library. There should probably be a checkout strategy that skips files that have been modified in workdir but not indexed. This can then be combined with GIT_CHECKOUT_USE_OURS
to throw out conflicting files.
source to share