Code

[PATCH] make file merging respect permissions
authorJames Bottomley <James.Bottomley@SteelEye.com>
Sun, 24 Apr 2005 03:50:10 +0000 (20:50 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sun, 24 Apr 2005 03:50:10 +0000 (20:50 -0700)
1) permissions aren't respected in the merge script (primarily because
they're never passed in to it in the first place).  Fix that and also
check for permission conflicts in the merge

2) the delete of a file in both branches may indeed be just that, but it
could also be the indicator of a rename conflict (file moved to
different locations in both branches), so error out and ask the
committer for guidance.

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
git-merge-one-file-script
merge-cache.c

index b2adc5fc4583e6089f4b38a47e1a73caad183f20..8189253022f5df3672ae0933aaea67dae2aff898 100755 (executable)
@@ -20,23 +20,45 @@ mkdir -p "$dir"
 
 case "${1:-.}${2:-.}${3:-.}" in
 #
-# deleted in both, or deleted in one and unchanged in the other
+# deleted in both
+#
+"$1..")
+       echo "ERROR: $4 is removed in both branches"
+       echo "ERROR: This is a potential rename conflict"
+       exit 1;;
+#
+# deleted in one and unchanged in the other
 #
 "$1.." | "$1.$1" | "$1$1.")
        rm -f -- "$4"
+       echo "Removing $4"
        update-cache --remove -- "$4"
        exit 0
        ;;
 
 #
-# added in one, or added identically in both
+# added in one
 #
-".$2." | "..$3" | ".$2$2")
-       mv $(unpack-file "${2:-$3}") $4
+".$2." | "..$3" )
+       echo "Adding $4 with perm $6$7"
+       mv $(unpack-file "$2$3") $4
+       chmod "$6$7" $4
        update-cache --add -- $4
        exit 0
        ;;
-
+#
+# Added in both (check for same permissions)
+#
+".$2$2")
+       if [ "$6" != "$7" ]; then
+               echo "ERROR: File $4 added in both branches, permissions conflict $6->$7"
+               exit 1
+       fi
+       echo "Adding $4 with perm $6"
+       mv $(unpack-file "$2") $4
+       chmod "$6" $4
+       update-cache --add -- $4
+       exit 0;;
 #
 # Modified in both, but differently ;(
 #
@@ -46,11 +68,20 @@ case "${1:-.}${2:-.}${3:-.}" in
        src1=$(unpack-file $2)
        src2=$(unpack-file $3)
        merge "$src2" "$orig" "$src1"
-       if [ $? -ne 0 ]; then
-               echo Leaving conflict merge in $src2
+       ret=$?
+       if [ "$6" != "$7" ]; then
+               echo "ERROR: Permissions $5->$6->$7 don't match merging $src2"
+               if [ $ret -ne 0 ]; then
+                       echo "ERROR: Leaving conflict merge in $src2"
+               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" && update-cache --add -- "$4" && exit 0
+       cp -- "$src2" "$4" && chmod -- "$6" "$4" &&  update-cache --add -- "$4" && exit 0
        ;;
 
 *)
index 68ac4ab2d926005a5a729017c1bcb70a30634bd8..11079b1cda9c50856a636a19bc41204903f1b522 100644 (file)
@@ -4,7 +4,7 @@
 #include "cache.h"
 
 static const char *pgm = NULL;
-static const char *arguments[5];
+static const char *arguments[8];
 
 static void run_program(void)
 {
@@ -18,6 +18,9 @@ static void run_program(void)
                            arguments[2],
                            arguments[3],
                            arguments[4],
+                           arguments[5],
+                           arguments[6],
+                           arguments[7],
                            NULL);
                die("unable to execute '%s'", pgm);
        }
@@ -36,9 +39,13 @@ static int merge_entry(int pos, const char *path)
        arguments[2] = "";
        arguments[3] = "";
        arguments[4] = path;
+       arguments[5] = "";
+       arguments[6] = "";
+       arguments[7] = "";
        found = 0;
        do {
                static char hexbuf[4][60];
+               static char ownbuf[4][60];
                struct cache_entry *ce = active_cache[pos];
                int stage = ce_stage(ce);
 
@@ -46,7 +53,9 @@ static int merge_entry(int pos, const char *path)
                        break;
                found++;
                strcpy(hexbuf[stage], sha1_to_hex(ce->sha1));
+               sprintf(ownbuf[stage], "%o", ntohl(ce->ce_mode) & (~S_IFMT));
                arguments[stage] = hexbuf[stage];
+               arguments[stage + 4] = ownbuf[stage];
        } while (++pos < active_nr);
        if (!found)
                die("merge-cache: %s not in the cache", path);