git-merge: make it usable as the first class UI
This teaches the oft-requested syntax git merge $commit to implement merging the named commit to the current branch. This hopefully would make "git merge" usable as the first class UI instead of being a mere backend for "git pull". Most notably, $commit above can be any committish, so you can say for example: git merge js/shortlog~2 to merge early part of a topic branch without merging the rest of it. A custom merge message can be given with the new --message=<msg> parameter. The message is prepended in front of the usual "Merge ..." message autogenerated with fmt-merge-message. Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
7cdbff14d4
commit
17bcdad3b7
@ -8,12 +8,14 @@ git-merge - Grand Unified Merge Driver
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-merge' [-n] [--no-commit] [-s <strategy>]... <msg> <head> <remote> <remote>...
|
||||
|
||||
[verse]
|
||||
'git-merge' [-n] [--no-commit] [--squash] [-s <strategy>]...
|
||||
[--reflog-action=<action>]
|
||||
-m=<msg> <remote> <remote>...
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
This is the top-level user interface to the merge machinery
|
||||
This is the top-level interface to the merge machinery
|
||||
which drives multiple merge strategy scripts.
|
||||
|
||||
|
||||
@ -27,13 +29,19 @@ include::merge-options.txt[]
|
||||
to give a good default for automated `git-merge` invocations.
|
||||
|
||||
<head>::
|
||||
our branch head commit.
|
||||
Our branch head commit. This has to be `HEAD`, so new
|
||||
syntax does not require it
|
||||
|
||||
<remote>::
|
||||
other branch head merged into our branch. You need at
|
||||
Other branch head merged into our branch. You need at
|
||||
least one <remote>. Specifying more than one <remote>
|
||||
obviously means you are trying an Octopus.
|
||||
|
||||
--reflog-action=<action>::
|
||||
This is used internally when `git-pull` calls this command
|
||||
to record that the merge was created by `pull` command
|
||||
in the `ref-log` entry that results from the merge.
|
||||
|
||||
include::merge-strategies.txt[]
|
||||
|
||||
|
||||
|
53
git-merge.sh
53
git-merge.sh
@ -3,7 +3,8 @@
|
||||
# Copyright (c) 2005 Junio C Hamano
|
||||
#
|
||||
|
||||
USAGE='[-n] [--no-commit] [--squash] [-s <strategy>]... <merge-message> <head> <remote>+'
|
||||
USAGE='[-n] [--no-commit] [--squash] [-s <strategy>] [--reflog-action=<action>] [-m=<merge-message>] <commit>+'
|
||||
|
||||
. git-sh-setup
|
||||
|
||||
LF='
|
||||
@ -92,7 +93,7 @@ finish () {
|
||||
|
||||
case "$#" in 0) usage ;; esac
|
||||
|
||||
rloga=
|
||||
rloga= have_message=
|
||||
while case "$#" in 0) break ;; esac
|
||||
do
|
||||
case "$1" in
|
||||
@ -125,17 +126,63 @@ do
|
||||
--reflog-action=*)
|
||||
rloga=`expr "z$1" : 'z-[^=]*=\(.*\)'`
|
||||
;;
|
||||
-m=*|--m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
|
||||
merge_msg=`expr "z$1" : 'z-[^=]*=\(.*\)'`
|
||||
have_message=t
|
||||
;;
|
||||
-m|--m|--me|--mes|--mess|--messa|--messag|--message)
|
||||
shift
|
||||
case "$#" in
|
||||
1) usage ;;
|
||||
esac
|
||||
merge_msg="$1"
|
||||
have_message=t
|
||||
;;
|
||||
-*) usage ;;
|
||||
*) break ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# This could be traditional "merge <msg> HEAD <commit>..." and the
|
||||
# way we can tell it is to see if the second token is HEAD, but some
|
||||
# people might have misused the interface and used a committish that
|
||||
# is the same as HEAD there instead. Traditional format never would
|
||||
# have "-m" so it is an additional safety measure to check for it.
|
||||
|
||||
if test -z "$have_message" &&
|
||||
second_token=$(git-rev-parse --verify "$2^0" 2>/dev/null) &&
|
||||
head_commit=$(git-rev-parse --verify "HEAD" 2>/dev/null) &&
|
||||
test "$second_token" = "$head_commit"
|
||||
then
|
||||
merge_msg="$1"
|
||||
shift
|
||||
head_arg="$1"
|
||||
head=$(git-rev-parse --verify "$1"^0) || usage
|
||||
shift
|
||||
else
|
||||
# We are invoked directly as the first-class UI.
|
||||
head_arg=HEAD
|
||||
|
||||
# All the rest are the commits being merged; prepare
|
||||
# the standard merge summary message to be appended to
|
||||
# the given message. If remote is invalid we will die
|
||||
# later in the common codepath so we discard the error
|
||||
# in this loop.
|
||||
merge_name=$(for remote
|
||||
do
|
||||
rh=$(git-rev-parse --verify "$remote"^0 2>/dev/null)
|
||||
if git show-ref -q --verify "refs/heads/$remote"
|
||||
then
|
||||
what=branch
|
||||
else
|
||||
what=commit
|
||||
fi
|
||||
echo "$rh $what '$remote'"
|
||||
done | git-fmt-merge-msg
|
||||
)
|
||||
merge_msg="${merge_msg:+$merge_msg$LF$LF}$merge_name"
|
||||
fi
|
||||
head=$(git-rev-parse --verify "$head_arg"^0) || usage
|
||||
|
||||
# All the rest are remote heads
|
||||
test "$#" = 0 && usage ;# we need at least one remote head.
|
||||
|
Loading…
Reference in New Issue
Block a user