git: a7677a680f21 - main - git-mfc: Add --abort and --continue flags
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 30 Jul 2026 17:16:24 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=a7677a680f21e15bd67b29b0948538879320c451
commit a7677a680f21e15bd67b29b0948538879320c451
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-07-30 17:09:51 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-07-30 17:09:51 +0000
git-mfc: Add --abort and --continue flags
Instead of making the user run the underlying git-cherry-pick command
after a conflict.
Requested by: des
Reviewed by: des
Differential Revision: https://reviews.freebsd.org/D58514
---
tools/tools/git/git-mfc | 66 +++++++++++++++++++++++++++++++++--------------
tools/tools/git/git-mfc.1 | 24 +++++++++++++----
2 files changed, 65 insertions(+), 25 deletions(-)
diff --git a/tools/tools/git/git-mfc b/tools/tools/git/git-mfc
index c6c4ea2b786a..4b1a9e15cc98 100755
--- a/tools/tools/git/git-mfc
+++ b/tools/tools/git/git-mfc
@@ -419,9 +419,8 @@ def cherry_pick(commits, edit=False):
result = subprocess.run(cmd, capture_output=False)
if result.returncode != 0:
print("\nCherry-pick failed.", file=sys.stderr)
- print("Resolve the conflict and run 'git cherry-pick --continue',",
- file=sys.stderr)
- print("or run 'git cherry-pick --abort' to give up.", file=sys.stderr)
+ print("Resolve the conflict and run 'git mfc --continue',", file=sys.stderr)
+ print("or run 'git mfc --abort' to give up.", file=sys.stderr)
sys.exit(1)
@@ -432,35 +431,38 @@ def main():
'automatically including fixup commits.',
)
parser.add_argument(
- '-e', '--edit', action='store_true',
- help='Edit the commit message before committing',
+ '--abort', action='store_true',
+ help='Abort a cherry-pick in progress',
)
parser.add_argument(
- '-n', action='store_true',
- help='List the commits that would be cherry-picked, but do not act',
+ '--all', action='store_true',
+ help='With --pending/--dangling, show commits from all authors',
)
parser.add_argument(
'-a', '--author', type=str, default=None,
help='Filter --pending/--dangling results by author (default: ignore author)',
)
- parser.add_argument(
- '--all', action='store_true',
- help='With --pending/--dangling, show commits from all authors',
- )
parser.add_argument(
'--baking', action='store_true',
- help='With --pending, also show commits whose MFC-after period '
- 'has not yet elapsed',
+ help='With --pending, also show commits whose MFC-after period has not yet elapsed',
)
parser.add_argument(
'-c', '--committer', type=str, default=None,
help='Filter --pending/--dangling results by committer (default: current user)',
)
+ parser.add_argument(
+ '--continue', action='store_true', dest='continue_',
+ help='Continue cherry-picking after resolving a conflict',
+ )
parser.add_argument(
'--dangling', action='store_true',
help='Find cherry-picked commits in the current branch that are '
'missing fixup commits from the origin branch',
)
+ parser.add_argument(
+ '-e', '--edit', action='store_true',
+ help='Edit the commit message before committing',
+ )
parser.add_argument(
'-f', '--force', action='store_true',
help='Cherry-pick commits even if they appear to be already present',
@@ -469,6 +471,10 @@ def main():
'--ignore-reverts', action='store_true',
help='Cherry-pick commits even if they were reverted upstream',
)
+ parser.add_argument(
+ '-n', action='store_true',
+ help='List the commits that would be cherry-picked, but do not act',
+ )
parser.add_argument(
'--pending', action='store_true',
help='Show upstream commits with MFC-after tags that are ready to '
@@ -488,11 +494,21 @@ def main():
)
args = parser.parse_args()
- if args.dangling and args.pending:
- err(1, 'usage error: --dangling and --pending are mutually exclusive')
- if (args.dangling or args.pending) and len(args.commits) > 0:
- err(1, 'usage error: revisions cannot be specified with --dangling or --pending')
- if not args.dangling and not args.pending and len(args.commits) == 0:
+ mode = []
+ if args.dangling:
+ mode.append('--dangling')
+ if args.pending:
+ mode.append('--pending')
+ if args.abort:
+ mode.append('--abort')
+ if args.continue_:
+ mode.append('--continue')
+ if len(mode) > 1:
+ err(1, 'usage error: only one of --dangling, --pending, --abort, '
+ 'or --continue may be specified')
+ if len(mode) == 1 and len(args.commits) > 0:
+ err(1, f'usage error: revisions cannot be specified with {mode[0]}')
+ if len(mode) == 0 and len(args.commits) == 0:
err(1, 'usage error: at least one revision is required')
origin = args.origin if args.origin else origin_branch()
@@ -509,13 +525,13 @@ def main():
upstream = remote + '/' + origin
- if not args.n:
+ if not args.n and not args.abort and not args.continue_:
repo.remotes[remote].fetch(origin)
# Do we want to filter commits by author or committer? By default, use
# the current git user's email to match the committer field.
author = committer = None
- if not getattr(args, 'all'):
+ if not args.all:
user_email = repo.config_reader().get_value('user', 'email', default=None)
if args.author:
author = args.author
@@ -547,6 +563,16 @@ def main():
else:
status = f"ready on {date_str}"
print(f'{commit_summary(commit)} ({status})')
+ elif args.abort:
+ result = subprocess.run(['git', 'cherry-pick', '--abort'],
+ capture_output=False)
+ if result.returncode != 0:
+ err(1, "failed to abort cherry-pick")
+ elif args.continue_:
+ result = subprocess.run(['git', 'cherry-pick', '--continue'],
+ capture_output=False)
+ if result.returncode != 0:
+ err(1, "failed to continue cherry-pick")
else:
tomfc, reverted = mfcclosure(repo, upstream, args.commits)
diff --git a/tools/tools/git/git-mfc.1 b/tools/tools/git/git-mfc.1
index 9121c253f3a9..a79bb131cd2e 100644
--- a/tools/tools/git/git-mfc.1
+++ b/tools/tools/git/git-mfc.1
@@ -3,7 +3,7 @@
.\"
.\" SPDX-License-Identifier: BSD-2-Clause
.\"
-.Dd June 26, 2026
+.Dd July 28, 2026
.Dt GIT-MFC 1
.Os
.Sh NAME
@@ -31,6 +31,10 @@
.Op Fl -all
.Op Fl -origin Ar branch
.Op Fl r Ar remote
+.Nm
+.Fl -continue
+.Nm
+.Fl -abort
.Sh DESCRIPTION
The
.Nm
@@ -76,8 +80,10 @@ All commits are cherry-picked using a single
.Xr git-cherry-pick 1
invocation.
If a conflict occurs, resolve it and run
-.Dq git cherry-pick --continue
-to proceed with the remaining commits.
+.Nm Fl -continue
+to proceed with the remaining commits, or
+.Nm Fl -abort
+to give up.
.It
In
.Fl -pending
@@ -108,6 +114,8 @@ are considered.
.Pp
The following options are available:
.Bl -tag -width "-a author"
+.It Fl -abort
+Abort a cherry-pick in progress.
.It Fl a Ar author , Fl -author Ar author
With
.Fl -pending
@@ -126,6 +134,8 @@ By default, the value of
from
.Xr git-config 1
is used.
+.It Fl -continue
+Continue cherry-picking after resolving a conflict.
.It Fl -all
With
.Fl -pending
@@ -136,7 +146,9 @@ show commits from all authors instead of only the current user.
Find cherry-picked commits in the current branch that are missing fixup
commits from the origin branch.
Cannot be combined with
-.Fl -pending
+.Fl -pending ,
+.Fl -abort ,
+.Fl -continue ,
or revision arguments.
.It Fl e , Fl -edit
Open the commit message in an editor before committing each cherry-pick.
@@ -178,7 +190,9 @@ Show upstream commits with
.Dq MFC after:
tags that are ready to be cherry-picked.
Cannot be combined with
-.Fl -dangling
+.Fl -dangling ,
+.Fl -abort ,
+.Fl -continue ,
or revision arguments.
.It Fl r Ar remote , Fl -remote Ar remote
Specify the git remote to fetch from.