{"thread":{"id":"170","subject":"[PATCH] Give better default modes to merge results.","startedAt":"2005-04-20T09:55:23Z","lastAt":"2005-04-20T09:55:23Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"962","messageId":"7vsm1lkc1g.fsf@assigned-by-dhcp.cox.net","threadId":"170","inReplyTo":null,"subject":"[PATCH] Give better default modes to merge results.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-04-20T09:55:23Z","receivedAt":"2005-04-20T09:55:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"As shipped, the example git-merge-one-file-script often leaves\nthe merge result with not-so-useful mode bits, especially with\nglibc 2.0.7 or later whose mkstemp() creates temporary file with\nmode 0600.  This contradicts the way checkout-cache creates new\nfiles, which is to use 0666 (or 0777 for files with executable\nbit on) and let the umask mechanism to take care of adjusting it\nto the user's preference.\n\nThis patch fixes this problem by (1) passing the executable bits\nfor 3 stages from merge-cache to the merge script, and by (2)\nadjusting the example script to make use of that information.\n\nFor backward compatibility with existing merge-one-file-script\npeople may already have developed, the additional 3 arguments\nare passed after the filename (i.e. as $5, $6 and $7).  This\ndoes not logically look so nice, but the older scripts can and\nwould just ignore these new parameters.\n\nThe patch also fixes some shell quoting problems the original\nsample script had with the resulting filename \"$4\".  Unlike all\nthe other arguments, this must be quoted to prevent it from\nbeing split via shell's $IFS mechanism.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\n git-merge-one-file-script |   35 +++++++++++++++++++++++++++--------\n merge-cache.c             |   18 ++++++++++++++----\n 2 files changed, 41 insertions(+), 12 deletions(-)\n\n--- a/git-merge-one-file-script\n+++ b/git-merge-one-file-script\n@@ -6,7 +6,9 @@\n #   $2 - file in branch1 SHA1 (or empty)\n #   $3 - file in branch2 SHA1 (or empty)\n #   $4 - pathname in repository\n-#\n+#   $5 - original file executable bit ('x' or '-' or empty)\n+#   $6 - file in branch1  executable bit ('x' or '-' or empty)\n+#   $7 - file in branch2  executable bit ('x' or '-' or empty)\n #\n # Handle some trivial cases.. The _really_ trivial cases have\n # been handled already by read-tree, but that one doesn't\n@@ -24,17 +26,29 @@ case \"${1:-.}${2:-.}${3:-.}\" in\n #\n \"$1..\" | \"$1.$1\" | \"$1$1.\")\n \trm -f -- \"$4\"\n-\tupdate-cache --remove -- \"$4\"\n-\texit 0\n+\texec update-cache --remove -- \"$4\"\n \t;;\n \n #\n # added in one, or added identically in both\n #\n \".$2.\" | \"..$3\" | \".$2$2\")\n-\tmv $(unpack-file \"${2:-$3}\") \"$4\"\n-\tupdate-cache --add -- \"$4\" ;# needs filemode fix.\n-\texit 0\n+\n+\t# This part is convoluted but necessary to get a sane\n+\t# default mode bits.  We let the shell to honor default\n+\t# umask when creating the file, and then rely on chmod +x\n+\t# to again honor umask.  It used to \"mv\" the file created\n+\t# in mode 0600 by unpack-file to \"$4\", which was almost\n+\t# always wrong.\n+\n+\ttmp=$(unpack-file \"${2:-$3}\") &&\n+\trm -f \"$4\" &&\n+\tcat \"$tmp\" >\"$4\" &&\n+\tcase \"$6$7\" in\n+\t*x*) chmod +x \"$4\" ;;\n+\tesac &&\n+\trm -f \"$tmp\" || exit\n+\texec update-cache --add -- \"$4\"\n \t;;\n \n #\n@@ -50,11 +64,16 @@ case \"${1:-.}${2:-.}${3:-.}\" in\n \t\techo Leaving conflict merge in $src2\n \t\texit 1\n \tfi\n-\tcp \"$src2\" \"$4\" && update-cache --add -- \"$4\" && exit 0\n+\trm -f \"$4\" &&\n+\tcat \"$src2\" >\"$4\" &&\n+\tcase \"$5$6$7\" in\n+\t*x*) chmod +x \"$4\" ;;\n+\tesac || exit\n+\texec update-cache --add -- \"$4\"\n \t;;\n \n *)\n-\techo \"Not handling case $1 -> $2 -> $3\"\n+\techo \"Not handling case $1($5) -> $2($6) -> $3($7)\"\n \t;;\n esac\n exit 1\n--- a/merge-cache.c\n+++ b/merge-cache.c\n@@ -4,7 +4,7 @@\n #include \"cache.h\"\n \n static const char *pgm = NULL;\n-static const char *arguments[5];\n+static const char *arguments[8];\n \n static void run_program(void)\n {\n@@ -18,6 +18,9 @@ static void run_program(void)\n \t\t\t    arguments[2],\n \t\t\t    arguments[3],\n \t\t\t    arguments[4],\n+\t\t\t    arguments[5],\n+\t\t\t    arguments[6],\n+\t\t\t    arguments[7],\n \t\t\t    NULL);\n \t\tdie(\"unable to execute '%s'\", pgm);\n \t}\n@@ -36,17 +39,24 @@ static int merge_entry(int pos, const ch\n \targuments[2] = \"\";\n \targuments[3] = \"\";\n \targuments[4] = path;\n+\targuments[5] = \"\";\n+\targuments[6] = \"\";\n+\targuments[7] = \"\";\n \tfound = 0;\n \tdo {\n-\t\tstatic char hexbuf[4][60];\n+\t\tstatic char hexbuf[3][41];\n+\t\tstatic char xbit[3][2];\n \t\tstruct cache_entry *ce = active_cache[pos];\n \t\tint stage = ce_stage(ce);\n \n \t\tif (strcmp(ce->name, path))\n \t\t\tbreak;\n \t\tfound++;\n-\t\tstrcpy(hexbuf[stage], sha1_to_hex(ce->sha1));\n-\t\targuments[stage] = hexbuf[stage];\n+\t\tstrcpy(hexbuf[stage-1], sha1_to_hex(ce->sha1));\n+\t\targuments[stage] = hexbuf[stage-1];\n+\t\txbit[stage-1][0] = (ntohl(ce->ce_mode) & 0100) ? 'x' : '-';\n+\t\txbit[stage-1][1] = 0;\n+\t\targuments[stage+4] = xbit[stage-1];\n \t} while (++pos < active_nr);\n \tif (!found)\n \t\tdie(\"merge-cache: %s not in the cache\", path);\n\n\n\n"}]}