Post 1.0.0 development track.
[git] / git-cherry.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Junio C Hamano.
4 #
5
6 USAGE='[-v] <upstream> [<head>]'
7 LONG_USAGE='             __*__*__*__*__> <upstream>
8             /
9   fork-point
10             \__+__+__+__+__+__+__+__> <head>
11
12 Each commit between the fork-point and <head> is examined, and
13 compared against the change each commit between the fork-point and
14 <upstream> introduces.  If the change seems to be in the upstream,
15 it is shown on the standard output with prefix "+".  Otherwise
16 it is shown with prefix "-".'
17 . git-sh-setup
18
19 case "$1" in -v) verbose=t; shift ;; esac 
20
21 case "$#,$1" in
22 1,*..*)
23     upstream=$(expr "$1" : '\(.*\)\.\.') ours=$(expr "$1" : '.*\.\.\(.*\)$')
24     set x "$upstream" "$ours"
25     shift ;;
26 esac
27
28 case "$#" in
29 1) upstream=`git-rev-parse --verify "$1"` &&
30    ours=`git-rev-parse --verify HEAD` || exit
31    ;;
32 2) upstream=`git-rev-parse --verify "$1"` &&
33    ours=`git-rev-parse --verify "$2"` || exit
34    ;;
35 *) usage ;;
36 esac
37
38 # Note that these list commits in reverse order;
39 # not that the order in inup matters...
40 inup=`git-rev-list ^$ours $upstream` &&
41 ours=`git-rev-list $ours ^$upstream` || exit
42
43 tmp=.cherry-tmp$$
44 patch=$tmp-patch
45 mkdir $patch
46 trap "rm -rf $tmp-*" 0 1 2 3 15
47
48 _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
49 _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
50
51 for c in $inup
52 do
53         git-diff-tree -p $c
54 done | git-patch-id |
55 while read id name
56 do
57         echo $name >>$patch/$id
58 done
59
60 LF='
61 '
62
63 O=
64 for c in $ours
65 do
66         set x `git-diff-tree -p $c | git-patch-id`
67         if test "$2" != ""
68         then
69                 if test -f "$patch/$2"
70                 then
71                         sign=-
72                 else
73                         sign=+
74                 fi
75                 case "$verbose" in
76                 t)
77                         c=$(git-rev-list --pretty=oneline --max-count=1 $c)
78                 esac
79                 case "$O" in
80                 '')     O="$sign $c" ;;
81                 *)      O="$sign $c$LF$O" ;;
82                 esac
83         fi
84 done
85 case "$O" in
86 '') ;;
87 *)  echo "$O" ;;
88 esac