Skip to content

Commit 35d2fff

Browse files
jherlandgitster
authored andcommitted
Provide 'git merge --abort' as a synonym to 'git reset --merge'
Teach 'git merge' the --abort option, which verifies the existence of MERGE_HEAD and then invokes 'git reset --merge' to abort the current in-progress merge and attempt to reconstruct the pre-merge state. The reason for adding this option is to provide a user interface for aborting an in-progress merge that is consistent with the interface for aborting a rebase ('git rebase --abort'), aborting the application of a patch series ('git am --abort'), and aborting an in-progress notes merge ('git notes merge --abort'). The patch includes documentation and testcases that explain and verify the various scenarios in which 'git merge --abort' can run. The testcases also document the cases in which 'git merge --abort' is unable to correctly restore the pre-merge state (look for the '###' comments towards the bottom of t/t7609-merge-abort.sh). This patch has been improved by the following contributions: - Jonathan Nieder: Move test documentation into test_description Thanks-to: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Johan Herland <johan@herland.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 2a22c1b commit 35d2fff

File tree

3 files changed

+351
-3
lines changed

3 files changed

+351
-3
lines changed

Documentation/git-merge.txt

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ SYNOPSIS
1313
[-s <strategy>] [-X <strategy-option>]
1414
[--[no-]rerere-autoupdate] [-m <msg>] <commit>...
1515
'git merge' <msg> HEAD <commit>...
16+
'git merge' --abort
1617

1718
DESCRIPTION
1819
-----------
@@ -47,6 +48,14 @@ The second syntax (<msg> `HEAD` <commit>...) is supported for
4748
historical reasons. Do not use it from the command line or in
4849
new scripts. It is the same as `git merge -m <msg> <commit>...`.
4950

51+
The third syntax ("`git merge --abort`") can only be run after the
52+
merge has resulted in conflicts. 'git merge --abort' will abort the
53+
merge process and try to reconstruct the pre-merge state. However,
54+
if there were uncommitted changes when the merge started (and
55+
especially if those changes were further modified after the merge
56+
was started), 'git merge --abort' will in some cases be unable to
57+
reconstruct the original (pre-merge) changes. Therefore:
58+
5059
*Warning*: Running 'git merge' with uncommitted changes is
5160
discouraged: while possible, it leaves you in a state that is hard to
5261
back out of in the case of a conflict.
@@ -72,6 +81,18 @@ include::merge-options.txt[]
7281
Allow the rerere mechanism to update the index with the
7382
result of auto-conflict resolution if possible.
7483

84+
--abort::
85+
Abort the current conflict resolution process, and
86+
try to reconstruct the pre-merge state.
87+
+
88+
If there were uncommitted worktree changes present when the merge
89+
started, 'git merge --abort' will in some cases be unable to
90+
reconstruct these changes. It is therefore recommended to always
91+
commit or stash your changes before running 'git merge'.
92+
+
93+
'git merge --abort' is equivalent to 'git reset --merge' when
94+
`MERGE_HEAD` is present.
95+
7596
<commit>...::
7697
Commits, usually other branch heads, to merge into our branch.
7798
You need at least one <commit>. Specifying more than one
@@ -142,7 +163,7 @@ happens:
142163
i.e. matching `HEAD`.
143164

144165
If you tried a merge which resulted in complex conflicts and
145-
want to start over, you can recover with `git reset --merge`.
166+
want to start over, you can recover with `git merge --abort`.
146167

147168
HOW CONFLICTS ARE PRESENTED
148169
---------------------------
@@ -213,8 +234,8 @@ After seeing a conflict, you can do two things:
213234

214235
* Decide not to merge. The only clean-ups you need are to reset
215236
the index file to the `HEAD` commit to reverse 2. and to clean
216-
up working tree changes made by 2. and 3.; `git-reset --hard` can
217-
be used for this.
237+
up working tree changes made by 2. and 3.; `git merge --abort`
238+
can be used for this.
218239

219240
* Resolve the conflicts. Git will mark the conflicts in
220241
the working tree. Edit the files into shape and

builtin/merge.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ static size_t xopts_nr, xopts_alloc;
5656
static const char *branch;
5757
static int verbosity;
5858
static int allow_rerere_auto;
59+
static int abort_current_merge;
5960

6061
static struct strategy all_strategy[] = {
6162
{ "recursive", DEFAULT_TWOHEAD | NO_TRIVIAL },
@@ -194,6 +195,8 @@ static struct option builtin_merge_options[] = {
194195
"message to be used for the merge commit (if any)",
195196
option_parse_message),
196197
OPT__VERBOSITY(&verbosity),
198+
OPT_BOOLEAN(0, "abort", &abort_current_merge,
199+
"abort the current in-progress merge"),
197200
OPT_END()
198201
};
199202

@@ -914,6 +917,17 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
914917
argc = parse_options(argc, argv, prefix, builtin_merge_options,
915918
builtin_merge_usage, 0);
916919

920+
if (abort_current_merge) {
921+
int nargc = 2;
922+
const char *nargv[] = {"reset", "--merge", NULL};
923+
924+
if (!file_exists(git_path("MERGE_HEAD")))
925+
die("There is no merge to abort (MERGE_HEAD missing).");
926+
927+
/* Invoke 'git reset --merge' */
928+
return cmd_reset(nargc, nargv, prefix);
929+
}
930+
917931
if (read_cache_unmerged())
918932
die_resolve_conflict("merge");
919933

0 commit comments

Comments
 (0)