From fc54a9c30ccad3fde5890d2c0ca2e2acc0848fbc Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 5 May 2005 16:14:01 -0700 Subject: [PATCH] Update git-apply-patch-script for symbolic links. This patch updates the git-apply-patch-script for the symbolic links in the cache, recently added by Kay Sievers. It currently is very anal about symbolic link changes. It refuses to change between a regular file and a symbolic link, and only allows symbolic link changes if the patch is based on the same original. Signed-off-by: Junio C Hamano --- git-apply-patch-script | 139 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 101 insertions(+), 38 deletions(-) diff --git a/git-apply-patch-script b/git-apply-patch-script index dccad270..13ec1c44 100755 --- a/git-apply-patch-script +++ b/git-apply-patch-script @@ -8,71 +8,134 @@ # case "$#" in -2) exit 1 ;; # do not feed unmerged diff to me! +2) + 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 +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 -case "$mode1,$mode2" in -.,?x) - # newly created +-,?) dir=$(dirname "$name") - case "$dir" in '' | .) ;; *) mkdir -p "$dir" esac || { + case "$dir" in '' | .) ;; *) mkdir -p "$dir" ;; esac || { echo >&2 "cannot create leading path for $name." exit 1 } - if test -f "$name" + if test -e "$name" then - echo >&2 "file $name to be created already exists." + echo >&2 "path $name to be created already exists." exit 1 fi - cat "$tmp2" >"$name" || { - echo >&2 "cannot create $name." - exit 1 - } - case "$mode2" in - +x) - echo >&2 "created $name with mode +x." - chmod "$mode2" "$name" - ;; - -x) - echo >&2 "created $name." + 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 a regular file $name with mode +x." + chmod "$mode2" "$name" + ;; + -x) + 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." + ;; + *) + echo >&2 "do not know how to create $name of type $type2." + exit 1 esac - git-update-cache --add -- "$name" - ;; -?x,.) - # deleted - echo >&2 "deleted $name." + git-update-cache --add -- "$name" ;; + +?,-) rm -f "$name" || { - echo >&2 "cannot remove $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 } - git-update-cache --remove -- "$name" - ;; -*) + 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 || { + case "$dir" in '' | .) ;; *) mkdir -p "$dir";; esac || { echo >&2 "cannot create leading path for $name." exit 1 } - # This will say "patching ..." so we do not say anything outselves. - diff -u -L "a/$name" -L "b/$name" "$tmp1" "$tmp2" | patch -p1 || exit + 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") ;; *) - echo >&2 "changing mode from $mode1 to $mode2." chmod "$mode2" "$name" + echo >&2 "changed mode from $mode1 to $mode2." ;; esac git-update-cache -- "$name" + esac -- 2.11.0