Skip to content
/ git Public
forked from git/git

Commit

Permalink
format-patch: take sequence of ranges.
Browse files Browse the repository at this point in the history
This enhances set of revs you can give format-patch.

Originally, format-patch took either one rev, or two revs:

    format-patch rev1
    format-patch rev1 rev2

The first format was a short-hand for "format-patch rev1 HEAD"
(i.e. rev2==HEAD).  What this meant was to find commits that are
in branch rev2 that has not been merged to branch rev1.

The above notation is still supported, but now it takes sequence
of "from1..to1 from2..to2 ...".  In short, the second format has
become a short-hand for "format-patch rev1..rev2".  Commits in
to1 but not in from1, to2 but not in from2, ... are formatted as
emailable patches.

With this, cherry-picking from other branch can be written as:

    git-format-patch -k --stdout master..branch1 master..branch2 |
    git-am -k -3

which is generally faster than traditional cherry-pick (which
always did 3-way merge) if patches apply cleanly, and still
falls back on 3-way merge if some of them do not.

Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
Junio C Hamano committed Oct 14, 2005
1 parent f7aac2e commit 603d874
Showing 1 changed file with 63 additions and 36 deletions.
99 changes: 63 additions & 36 deletions git-format-patch.sh
Expand Up @@ -6,7 +6,9 @@
. git-sh-setup || die "Not a git archive."

usage () {
echo >&2 "usage: $0"' [-n] [-o dir | --stdout] [--keep-subject] [--mbox] [--check] [--signoff] [-<diff options>...] upstream [ our-head ]
echo >&2 "usage: $0"' [-n] [-o dir | --stdout] [--keep-subject] [--mbox]
[--check] [--signoff] [-<diff options>...]
( from..to ... | upstream [ our-head ] )
Prepare each commit with its patch since our-head forked from upstream,
one file per patch, for e-mail submission. Each output file is
Expand Down Expand Up @@ -75,25 +77,70 @@ tt)
die '--keep-subject and --numbered are incompatible.' ;;
esac

rev1= rev2=
case "$#" in
2)
rev1="$1" rev2="$2" ;;
1)
case "$1" in
*..*)
rev1=`expr "$1" : '\(.*\)\.\.'`
rev2=`expr "$1" : '.*\.\.\(.*\)'`
tmp=.tmp-series$$
trap 'rm -f $tmp-*' 0 1 2 3 15

series=$tmp-series
commsg=$tmp-commsg
filelist=$tmp-files

# Backward compatible argument parsing hack.
#
# Historically, we supported:
# 1. "rev1" is equivalent to "rev1..HEAD"
# 2. "rev1..rev2"
# 3. "rev1" "rev2 is equivalent to "rev1..rev2"
#
# We want to take a sequence of "rev1..rev2" in general.

case "$#,$1" in
1,?*..?*)
# single "rev1..rev2"
;;
*)
rev1="$1"
rev2="HEAD"
1,*)
# single rev1
set x "$1..HEAD"
shift
;;
2,?*..?*)
# not traditional "rev1" "rev2"
;;
2,*)
set x "$1..$2"
shift
;;
esac ;;
*)
usage ;;
esac

# Now we have what we want in $@
for revpair
do
case "$revpair" in
?*..?*)
rev1=`expr "$revpair" : '\(.*\)\.\.'`
rev2=`expr "$revpair" : '.*\.\.\(.*\)'`
;;
*)
usage
;;
esac
git-rev-parse --verify "$rev1^0" >/dev/null 2>&1 ||
die "Not a valid rev $rev1 ($revpair)"
git-rev-parse --verify "$rev2^0" >/dev/null 2>&1 ||
die "Not a valid rev $rev2 ($revpair)"
git-cherry -v "$rev1" "$rev2" |
while read sign rev comment
do
case "$sign" in
'-')
echo >&2 "Merged already: $comment"
;;
*)
echo $rev
;;
esac
done
done >$series

me=`git-var GIT_AUTHOR_IDENT | sed -e 's/>.*/>/'`

case "$outdir" in
Expand All @@ -102,13 +149,6 @@ case "$outdir" in
esac
test -d "$outdir" || mkdir -p "$outdir" || exit

tmp=.tmp-series$$
trap 'rm -f $tmp-*' 0 1 2 3 15

series=$tmp-series
commsg=$tmp-commsg
filelist=$tmp-files

titleScript='
/./d
/^$/n
Expand All @@ -130,19 +170,6 @@ whosepatchScript='
q
}'

git-cherry -v "$rev1" "$rev2" |
while read sign rev comment
do
case "$sign" in
'-')
echo >&2 "Merged already: $comment"
;;
*)
echo $rev
;;
esac
done >$series

process_one () {
mailScript='
/./d
Expand Down

0 comments on commit 603d874

Please sign in to comment.