Skip to content

Commit

Permalink
git-merge: make it usable as the first class UI
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Junio C Hamano committed Nov 22, 2006
1 parent 7cdbff1 commit 17bcdad
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 12 deletions.
18 changes: 13 additions & 5 deletions Documentation/git-merge.txt
Expand Up @@ -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.


Expand All @@ -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[]


Expand Down
61 changes: 54 additions & 7 deletions git-merge.sh
Expand Up @@ -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='
Expand Down Expand Up @@ -92,7 +93,7 @@ finish () {

case "$#" in 0) usage ;; esac

rloga=
rloga= have_message=
while case "$#" in 0) break ;; esac
do
case "$1" in
Expand Down Expand Up @@ -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

merge_msg="$1"
shift
head_arg="$1"
head=$(git-rev-parse --verify "$1"^0) || usage
shift
# 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"
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.
Expand Down

0 comments on commit 17bcdad

Please sign in to comment.