From: Junio C Hamano Date: Sun, 1 May 2005 16:33:12 +0000 (-0700) Subject: [PATCH] Really fix git-merge-one-file-script this time. X-Git-Tag: v0.99~675 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=21a08dcbe70a79206b76c89fb95e26d3a7fdf1f4;p=git.git [PATCH] Really fix git-merge-one-file-script this time. The merge-cache program was updated to pass executable bits when calling git-merge-one-file-script, but the called script supplied as an example were not using them carefully. This patch fixes the following problems in the script: * When a new file is created in a directory, which is a file in the work tree, it tried to create leading directory but did not check for failure from the "mkdir -p" command. * The script did not check the exit status from the git-update-cache command at all. * The parameter "$4" to the script is a file name that can contain almost any characters, so it must be quoted with double quotes and also needs to be preceded with -- to mark it as a non-option when passed to certain commands. * The chmod command was used with parameter "$6" or "$7" to set the mode bits. This contradicts with the strategy taken by checkout-cache, where we honor user's umask and force only the executable bits. With this patch, it creates a new file by redirecting into it (thus honoring user's default umask), and then uses "chmod +x" if we want the resulting file executable. Without this fix, the merge result becomes 0644 or 0755 for users whose umask is 002 for whom it should become 0664 or 0775. * When "$1 -> $2 -> $3" case was not handled, the script did not say which path it was working on, which was not so useful when used with the -a option of git-merge-cache. Signed-off-by: Junio C Hamano Signed-off-by: Linus Torvalds --- diff --git a/git-merge-one-file-script b/git-merge-one-file-script index b521d05f..cefbe634 100755 --- a/git-merge-one-file-script +++ b/git-merge-one-file-script @@ -16,7 +16,7 @@ # if the directory is newly added in a branch, it might not exist # in the current tree dir=$(dirname "$4") -mkdir -p "$dir" +mkdir -p "$dir" || exit case "${1:-.}${2:-.}${3:-.}" in # @@ -30,22 +30,18 @@ case "${1:-.}${2:-.}${3:-.}" in # deleted in one and unchanged in the other # "$1.." | "$1.$1" | "$1$1.") - rm -f -- "$4" echo "Removing $4" - git-update-cache --remove -- "$4" - exit 0 - ;; - + rm -f -- "$4" && exec git-update-cache --remove -- "$4" ;; # # added in one # ".$2." | "..$3" ) - echo "Adding $4 with perm $6$7" - mv $(git-unpack-file "$2$3") $4 - chmod "$6$7" $4 - git-update-cache --add -- $4 - exit 0 - ;; + case "$6$7" in *7??) mode=+x;; *) mode=-x;; esac + echo "Adding $4 with perm $mode" + rm -f -- "$4" && + git-cat-file blob "$2$3" >"$4" && + chmod "$mode" -- "$4" && + exec git-update-cache --add -- "$4" ;; # # Added in both (check for same permissions) # @@ -54,11 +50,12 @@ case "${1:-.}${2:-.}${3:-.}" in echo "ERROR: File $4 added in both branches, permissions conflict $6->$7" exit 1 fi - echo "Adding $4 with perm $6" - mv $(git-unpack-file "$2") $4 - chmod "$6" $4 - git-update-cache --add -- $4 - exit 0;; + case "$6" in *7??) mode=+x;; *) mode=-x;; esac + echo "Adding $4 with perm $mode" + rm -f -- "$4" && + git-cat-file blob "$2" >"$4" && + chmod "$mode" -- "$4" && + exec git-update-cache --add -- "$4" ;; # # Modified in both, but differently ;( # @@ -76,16 +73,14 @@ case "${1:-.}${2:-.}${3:-.}" in fi exit 1 fi - chmod -- "$6" "$src2" if [ $ret -ne 0 ]; then echo "ERROR: Leaving conflict merge in $src2" exit 1 fi - cp -- "$src2" "$4" && chmod -- "$6" "$4" && git-update-cache --add -- "$4" && exit 0 - ;; - + case "$6" in *7??) mode=+x;; *) mode=-x;; esac + rm -f -- "$4" && cat "$src2" >"$4" && chmod "$mode" -- "$4" && + exec git-update-cache --add -- "$4" ;; *) - echo "Not handling case $1 -> $2 -> $3" - ;; + echo "Not handling case $4: $1 -> $2 -> $3" ;; esac exit 1