X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=git-apply-patch-script;h=0849a3e68b3a219aa41e3357fd71fb39b285e059;hb=f1a7eb36b017c62d9a007b6b8660bdeec3f94f97;hp=c28015aad3bbe9ec18c031c1ef8f1f3c3c388378;hpb=285bf834bea11981ae7c2242e9f087d3effe7de8;p=git.git diff --git a/git-apply-patch-script b/git-apply-patch-script index c28015aa..0849a3e6 100755 --- a/git-apply-patch-script +++ b/git-apply-patch-script @@ -8,51 +8,134 @@ # case "$#" in -2) exit 1 ;; # do not feed unmerged diff to me! +1) + echo >&2 "cannot handle unmerged diff on path $1." + exit 1 ;; esac name="$1" tmp1="$2" hex1="$3" mode1="$4" tmp2="$5" hex2="$6" mode2="$7" -case "$mode1" in *7??) mode1=+x ;; *6??) mode1=-x ;; esac -case "$mode2" in *7??) mode2=+x ;; *6??) mode2=-x ;; esac - -if test -f "$name.orig" || test -f "$name.rej" -then - echo >&2 "Unresolved patch conflicts in the previous run found." - exit 1 -fi -# This will say "patching ..." so we do not say anything outselves. - -diff -u -L "a/$name" -L "b/$name" "$tmp1" "$tmp2" | patch -p1 -test -f "$name.rej" || { - case "$mode1,$mode2" in - .,?x) - # newly created + +type1=f +case "$mode1" in +*120???) type1=l ;; +*1007??) mode1=+x ;; +*1006??) mode1=-x ;; +.) type1=- ;; +esac + +type2=f +case "$mode2" in +*120???) type2=l ;; +*1007??) mode2=+x ;; +*1006??) mode2=-x ;; +.) type2=- ;; +esac + +case "$type1,$type2" in + +-,?) + dir=$(dirname "$name") + case "$dir" in '' | .) ;; *) mkdir -p "$dir" ;; esac || { + echo >&2 "cannot create leading path for $name." + exit 1 + } + if test -e "$name" + then + echo >&2 "path $name to be created already exists." + exit 1 + fi + case "$type2" in + f) + # creating a regular file + cat "$tmp2" >"$name" || { + echo >&2 "cannot create a regular file $name." + exit 1 + } case "$mode2" in +x) - echo >&2 "created $name with mode +x." + echo >&2 "created a regular file $name with mode +x." chmod "$mode2" "$name" ;; -x) - echo >&2 "created $name." - ;; - esac - git-update-cache --add -- "$name" - ;; - ?x,.) - # deleted - echo >&2 "deleted $name." - rm -f "$name" - git-update-cache --remove -- "$name" + echo >&2 "created a regular file $name." + ;; + esac ;; + l) + # creating a symlink + ln -s "$(cat "$tmp2")" "$name" || { + echo >&2 "cannot create a symbolic link $name." + exit 1 + } + echo >&2 "created a symbolic link $name." + ;; *) - # changed - case "$mode1,$mode2" in - "$mode2,$mode1") ;; - *) - echo >&2 "changing mode from $mode1 to $mode2." - chmod "$mode2" "$name" - ;; - esac - git-update-cache -- "$name" + echo >&2 "do not know how to create $name of type $type2." + exit 1 esac -} -exit 0 + git-update-cache --add -- "$name" ;; + +?,-) + rm -f "$name" || { + echo >&2 "cannot remove $name" + exit 1 + } + echo >&2 "deleted $name." + git-update-cache --remove -- "$name" ;; + +l,f|f,l) + echo >&2 "cannot change a regular file $name and a symbolic link $name." + exit 1 ;; + +l,l) + # symlink to symlink + current=$(readlink "$name") || { + echo >&2 "cannot read the target of the symbolic link $name." + exit 1 + } + original=$(cat "$tmp1") + next=$(cat "$tmp2") + test "$original" != "$current" || { + echo >&2 "cannot apply symbolic link target change ($original->$next) to $name which points to $current." + exit 1 + } + if test "$next" != "$current" + then + rm -f "$name" && ln -s "$next" "$name" || { + echo >&2 "cannot create symbolic link $name." + exit 1 + } + echo >&2 "changed symbolic target of $name." + git-update-cache -- "$name" + fi ;; + +f,f) + # changed + test -e "$name" || { + echo >&2 "regular file $name to be patched does not exist." + exit 1 + } + dir=$(dirname "$name") + case "$dir" in '' | .) ;; *) mkdir -p "$dir";; esac || { + echo >&2 "cannot create leading path for $name." + exit 1 + } + tmp=.git-apply-patch-$$ + trap "rm -f $tmp-*" 0 1 2 3 15 + + # Be careful, in case "$tmp2" is borrowed path from the work tree + # we are looking at... + diff -u -L "a/$name" -L "b/$name" "$tmp1" "$tmp2" >$tmp-patch + + # This will say "patching ..." so we do not say anything outselves. + patch -p1 <$tmp-patch || exit + rm -f $tmp-patch + case "$mode1,$mode2" in + "$mode2,$mode1") ;; + *) + chmod "$mode2" "$name" + echo >&2 "changed mode from $mode1 to $mode2." + ;; + esac + git-update-cache -- "$name" + +esac