Skip to content

Commit

Permalink
[PATCH] make file merging respect permissions
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
James Bottomley authored and Linus Torvalds committed Apr 24, 2005
1 parent 58e28af commit e2b6a9d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 9 deletions.
47 changes: 39 additions & 8 deletions git-merge-one-file-script
Original file line number Diff line number Diff line change
Expand Up @@ -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 ;(
#
Expand All @@ -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
;;

*)
Expand Down
11 changes: 10 additions & 1 deletion merge-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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);
}
Expand All @@ -36,17 +39,23 @@ 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);

if (strcmp(ce->name, 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);
Expand Down

0 comments on commit e2b6a9d

Please sign in to comment.