git-apply-patch-scripton commit Merge of http://members.cox.net/junkio/git-jc.git (74c7cfa)
   1#!/bin/sh
   2# Copyright (C) 2005 Junio C Hamano
   3#
   4# Applying diff between two trees to the work tree can be
   5# done with the following single command:
   6#
   7# GIT_EXTERNAL_DIFF=git-apply-patch-script git-diff-tree -p $tree1 $tree2
   8#
   9
  10case "$#" in
  112)
  12    echo >&2 "cannot handle unmerged diff on path $1."
  13    exit 1 ;;
  14esac
  15name="$1" tmp1="$2" hex1="$3" mode1="$4" tmp2="$5" hex2="$6" mode2="$7"
  16
  17type1=f
  18case "$mode1" in
  19*120???) type1=l  ;;
  20*1007??) mode1=+x ;;
  21*1006??) mode1=-x ;;
  22.)       type1=-  ;; 
  23esac
  24
  25type2=f
  26case "$mode2" in
  27*120???) type2=l  ;;
  28*1007??) mode2=+x ;;
  29*1006??) mode2=-x ;;
  30.)       type2=-  ;; 
  31esac
  32
  33case "$type1,$type2" in
  34
  35-,?)
  36    dir=$(dirname "$name")
  37    case "$dir" in '' | .) ;; *) mkdir -p "$dir" ;; esac || {
  38        echo >&2 "cannot create leading path for $name."
  39        exit 1
  40    }
  41    if test -e "$name"
  42    then
  43        echo >&2 "path $name to be created already exists."
  44        exit 1
  45    fi
  46    case "$type2" in
  47    f)
  48        # creating a regular file
  49        cat "$tmp2" >"$name" || {
  50            echo >&2 "cannot create a regular file $name."
  51            exit 1
  52        } 
  53        case "$mode2" in
  54        +x)
  55            echo >&2 "created a regular file $name with mode +x."
  56            chmod "$mode2" "$name"
  57            ;;
  58        -x)
  59            echo >&2 "created a regular file $name."
  60            ;;
  61        esac
  62        ;;
  63    l)
  64        # creating a symlink
  65        ln -s "$(cat "$tmp2")" "$name" || {
  66            echo >&2 "cannot create a symbolic link $name."
  67            exit 1
  68        }
  69        echo >&2 "created a symbolic link $name."
  70        ;;
  71    *)
  72        echo >&2 "do not know how to create $name of type $type2."
  73        exit 1
  74    esac
  75    git-update-cache --add -- "$name" ;;
  76
  77?,-)
  78    rm -f "$name" || {
  79        echo >&2 "cannot remove $name"
  80        exit 1
  81    }
  82    echo >&2 "deleted $name."
  83    git-update-cache --remove -- "$name" ;;
  84
  85l,f|f,l)
  86    echo >&2 "cannot change a regular file $name and a symbolic link $name."
  87    exit 1 ;;
  88
  89l,l)
  90    # symlink to symlink
  91    current=$(readlink "$name") || {
  92        echo >&2 "cannot read the target of the symbolic link $name."
  93        exit 1
  94    }
  95    original=$(cat "$tmp1")
  96    next=$(cat "$tmp2")
  97    test "$original" != "$current" || {
  98        echo >&2 "cannot apply symbolic link target change ($original->$next) to $name which points to $current."
  99        exit 1
 100    }
 101    if test "$next" != "$current"
 102    then
 103        rm -f "$name" && ln -s "$next" "$name" || {
 104            echo >&2 "cannot create symbolic link $name."
 105            exit 1
 106        }
 107        echo >&2 "changed symbolic target of $name."
 108        git-update-cache -- "$name"
 109    fi ;;
 110
 111f,f)
 112    # changed
 113    test -e "$name" || {
 114        echo >&2 "regular file $name to be patched does not exist."
 115        exit 1
 116    }
 117    dir=$(dirname "$name")
 118    case "$dir" in '' | .) ;; *) mkdir -p "$dir";; esac || {
 119        echo >&2 "cannot create leading path for $name."
 120        exit 1
 121    }
 122    tmp=.git-apply-patch-$$
 123    trap "rm -f $tmp-*" 0 1 2 3 15
 124
 125    # Be careful, in case "$tmp2" is borrowed path from the work tree
 126    # we are looking at...
 127    diff -u -L "a/$name" -L "b/$name" "$tmp1" "$tmp2" >$tmp-patch
 128
 129    # This will say "patching ..." so we do not say anything outselves.
 130    patch -p1 <$tmp-patch || exit
 131    rm -f $tmp-patch
 132    case "$mode1,$mode2" in
 133    "$mode2,$mode1") ;;
 134    *)
 135        chmod "$mode2" "$name"
 136        echo >&2 "changed mode from $mode1 to $mode2."
 137        ;;
 138    esac
 139    git-update-cache -- "$name"
 140
 141esac