git-cherryon commit Teach format-patch, rebase and cherry a..b format (4282c4f)
   1#!/bin/sh
   2#
   3# Copyright (c) 2005 Junio C Hamano.
   4#
   5
   6. git-sh-setup-script || die "Not a git archive."
   7
   8usage="usage: $0 "'<upstream> [<head>]
   9
  10             __*__*__*__*__> <upstream>
  11            /
  12  fork-point
  13            \__+__+__+__+__+__+__+__> <head>
  14
  15Each commit between the fork-point and <head> is examined, and
  16compared against the change each commit between the fork-point and
  17<upstream> introduces.  If the change does not seem to be in the
  18upstream, it is shown on the standard output.
  19
  20The output is intended to be used as:
  21
  22    OLD_HEAD=$(git-rev-parse HEAD)
  23    git-rev-parse upstream >${GIT_DIR-.}/HEAD
  24    git-cherry upstream $OLD_HEAD |
  25    while read commit
  26    do
  27        GIT_EXTERNAL_DIFF=git-apply-patch-script git-diff-tree -p "$commit" &&
  28        git-commit-script -C "$commit"
  29    done
  30'
  31
  32case "$#,$1" in
  331,*..*)
  34    upstream=$(expr "$1" : '\(.*\)\.\.') ours=$(expr "$1" : '.*\.\.\(.*\)$')
  35    set x "$upstream" "$ours"
  36    shift ;;
  37esac
  38
  39case "$#" in
  401) upstream=`git-rev-parse --verify "$1"` &&
  41   ours=`git-rev-parse --verify HEAD` || exit
  42   ;;
  432) upstream=`git-rev-parse --verify "$1"` &&
  44   ours=`git-rev-parse --verify "$2"` || exit
  45   ;;
  46*) echo >&2 "$usage"; exit 1 ;;
  47esac
  48
  49# Note that these list commits in reverse order;
  50# not that the order in inup matters...
  51inup=`git-rev-list ^$ours $upstream` &&
  52ours=`git-rev-list $ours ^$upstream` || exit
  53
  54tmp=.cherry-tmp$$
  55patch=$tmp-patch
  56mkdir $patch
  57trap "rm -rf $tmp-*" 0 1 2 3 15
  58
  59_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
  60_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
  61
  62for c in $inup
  63do
  64        git-diff-tree -p $c
  65done | git-patch-id |
  66while read id name
  67do
  68        echo $name >>$patch/$id
  69done
  70
  71LF='
  72'
  73
  74O=
  75for c in $ours
  76do
  77        set x `git-diff-tree -p $c | git-patch-id`
  78        if test "$2" != ""
  79        then
  80                if test -f "$patch/$2"
  81                then
  82                        sign=-
  83                else
  84                        sign=+
  85                fi
  86                case "$O" in
  87                '')     O="$sign $c" ;;
  88                *)      O="$sign $c$LF$O" ;;
  89                esac
  90        fi
  91done
  92case "$O" in
  93'') ;;
  94*)  echo "$O" ;;
  95esac