{"thread":{"id":"7103","subject":"[PATCH] Add git-mergetool to run an appropriate merge conflict resolution program","startedAt":"2007-03-06T05:07:28Z","lastAt":"2007-03-29T14:20:44Z","messageCount":7,"participants":["Theodore Ts'o","Junio C Hamano","Theodore Tso","Linus Torvalds"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"36416","messageId":"E1HORtY-0000zK-8B@candygram.thunk.org","threadId":"7103","inReplyTo":null,"subject":"[PATCH] Add git-mergetool to run an appropriate merge conflict resolution program","fromName":"Theodore Ts'o","fromEmail":"tytso@mit.edu","sentAt":"2007-03-06T05:07:28Z","receivedAt":"2007-03-06T05:07:28Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"The git-mergetool program can be used to automatically run an appropriate\nmerge resolution program to resolve merge conflicts.  It will automatically\nrun one of kdiff3, tkdiff, meld, xxdiff, or emacs emerge programs.\n\nSigned-off-by: \"Theodore Ts'o\" <tytso@mit.edu>\n---\n .gitignore                      |    1 +\n Documentation/config.txt        |    5 +\n Documentation/git-mergetool.txt |   46 +++++++++\n Makefile                        |    2 +-\n git-mergetool.sh                |  208 +++++++++++++++++++++++++++++++++++++++\n 5 files changed, 261 insertions(+), 1 deletions(-)\n create mode 100644 Documentation/git-mergetool.txt\n create mode 100755 git-mergetool.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex 0eaba0a..27797d1 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -75,6 +75,7 @@ git-merge-ours\n git-merge-recursive\n git-merge-resolve\n git-merge-stupid\n+git-mergetool\n git-mktag\n git-mktree\n git-name-rev\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 5408dd6..0a72e41 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -453,6 +453,11 @@ merge.summary::\n \tWhether to include summaries of merged commits in newly created\n \tmerge commit messages. False by default.\n \n+merge.tool::\n+\tControls which merge resolution program is used by \n+\tgitlink:git-mergetool[l].  Valid values are: \"kdiff3\", \"tkdiff\", \n+\t\"meld\", \"xxdiff\", \"emerge\"\n+\n merge.verbosity::\n \tControls the amount of output shown by the recursive merge\n \tstrategy.  Level 0 outputs nothing except a final error\ndiff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt\nnew file mode 100644\nindex 0000000..8cc00fb\n--- /dev/null\n+++ b/Documentation/git-mergetool.txt\n@@ -0,0 +1,46 @@\n+git-mergetool(1)\n+================\n+\n+NAME\n+----\n+git-mergetool - Forward-port local commits to the updated upstream head\n+\n+SYNOPSIS\n+--------\n+'git-mergetool' [--tool=<tool>] [<file>]...\n+\n+DESCRIPTION\n+-----------\n+\n+Use 'git mergetool' to run one of several merge utilities to resolve\n+merge conflicts.  It is typically run after gitlink:git-merge[1].\n+\n+If one or more <file> parameters are given, the merge tool program will\n+be run to resolve differences on each file.  If no <file> names are\n+specified, 'git mergetool' will run the merge tool program on every file\n+with merge conflicts.  \n+\n+OPTIONS\n+-------\n+-t or --tool=<tool>::\n+\tUse the merge resolution program specified by <tool>.   \n+\tValid merge tools are:\n+\tkdiff3, tkdiff, meld, xxdiff, and emerge.\n+\n+\tIf a merge resolution program is not specified, 'git mergetool' \n+\twill use the configuration variable merge.tool.  If the\n+\tconfiguration variable merge.tool is not set, 'git mergetool' \n+\twill pick a suitable default.\n+\n+Author\n+------\n+Written by Theodore Y Ts'o <tytso@mit.edu>\n+\n+Documentation\n+--------------\n+Documentation by Theodore Y Ts'o.\n+\n+GIT\n+---\n+Part of the gitlink:git[7] suite\n+\ndiff --git a/Makefile b/Makefile\nindex a221bdc..502f660 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -177,7 +177,7 @@ SCRIPT_SH = \\\n \tgit-clean.sh git-clone.sh git-commit.sh \\\n \tgit-fetch.sh git-gc.sh \\\n \tgit-ls-remote.sh \\\n-\tgit-merge-one-file.sh git-parse-remote.sh \\\n+\tgit-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \\\n \tgit-pull.sh git-rebase.sh \\\n \tgit-repack.sh git-request-pull.sh git-reset.sh \\\n \tgit-revert.sh git-sh-setup.sh \\\ndiff --git a/git-mergetool.sh b/git-mergetool.sh\nnew file mode 100755\nindex 0000000..b961719\n--- /dev/null\n+++ b/git-mergetool.sh\n@@ -0,0 +1,208 @@\n+#!/bin/sh\n+#\n+# This program resolves merge conflicts in git\n+#\n+# Copyright (c) 2006 Theodore Y. Ts'o\n+#\n+# This file is licensed under the GPL v2, or a later version\n+# at the discretion of Linus Torvalds.\n+#\n+\n+usage () {\n+    echo \"Usage: git mergetool [--tool=tool] [file to merge] ...\"\n+    exit 1\n+}\n+\n+merge_file () {\n+\tpath=\"$1\"\n+\n+\tif test ! -f \"$path\" ; then\n+\t\techo \"$path: file not found\"\n+\t\texit 1\n+\tfi\n+\n+\tf=`git-ls-files -u \"$path\"`\n+\tif test -z \"$f\" ; then\n+\t\techo \"$path: file does not need merging\"\n+\t\texit 1\n+\tfi\n+\n+\tBACKUP=\"$path.BACKUP.$$\"\n+\tLOCAL=\"$path.LOCAL.$$\"\n+\tREMOTE=\"$path.REMOTE.$$\"\n+\tBASE=\"$path.BASE.$$\"\n+\n+\tmv \"$path\" \"$BACKUP\"\n+\tcp \"$BACKUP\" \"$path\"\n+\n+\tgit cat-file blob \":1:$path\" > \"$BASE\"\n+\tgit cat-file blob \":2:$path\" > \"$LOCAL\"\n+\tgit cat-file blob \":3:$path\" > \"$REMOTE\"\n+\n+\tcase \"$merge_tool\" in\n+\t    kdiff3)\n+\t\t(kdiff3 --auto --L1 \"$path (Base)\" -L2 \"$path (Local)\" --L3 \"$path (Remote)\" \\\n+\t\t    \"$BASE\" \"$LOCAL\" \"$REMOTE\" -o \"$path\" > /dev/null 2>&1)\n+\t\tstatus=$?\n+\t\tif test \"$status\" -eq 0; then\n+\t\t    rm \"$BACKUP\"\n+\t\tfi\n+\t\t;;\n+\t    tkdiff)\n+\t\ttkdiff \"$LOCAL\" \"$REMOTE\" -a \"$BASE\" -o \"$path\"\n+\t\tstatus=$?\n+\t\tif test \"$status\" -eq 0; then\n+\t\t    mv \"$BACKUP\" \"$path.orig\"\n+\t\tfi\n+\t\t;;\n+\t    meld)\n+\t        touch \"$BACKUP\"\n+\t\tmeld \"$LOCAL\" \"$path\" \"$REMOTE\"\n+\t\tif test \"$path\" -nt \"$BACKUP\" ; then \n+\t\t\tstatus=0;\n+\t\telse\n+\t\t\twhile true; do\n+\t\t\t        echo \"$path seems unchanged.\"\n+\t\t\t        echo -n \"Was the merge successful? [y/n] \"\n+\t\t\t        read answer < /dev/tty\n+\t\t\t        case \"$answer\" in\n+\t\t\t        \ty*|Y*) status=0; break ;;\n+\t\t\t\t\tn*|N*) status=1; break ;;\n+\t\t\t\tesac\n+\t\t\tdone\n+\t\tfi\n+\t\tif test \"$status\" -eq 0; then\n+\t\t    mv \"$BACKUP\" \"$path.orig\"\n+\t\tfi\n+\t\t;;\n+\t    xxdiff)\n+\t    \ttouch \"$BACKUP\"\n+\t\txxdiff -X --show-merged-pane \\\n+\t\t    -R 'Accel.SaveAsMerged: \"Ctrl-S\"' \\\n+\t\t    -R 'Accel.Search: \"Ctrl+F\"' \\\n+\t\t    -R 'Accel.SearchForward: \"Ctrl-G\"' \\\n+\t\t    --merged-file \"$path\" \"$LOCAL\" \"$BASE\" \"$REMOTE\"\n+\t\tif test \"$path\" -nt \"$BACKUP\" ; then \n+\t\t\tstatus=0;\n+\t\telse\n+\t\t\twhile true; do\n+\t\t\t        echo \"$path seems unchanged.\"\n+\t\t\t        echo -n \"Was the merge successful? [y/n] \"\n+\t\t\t        read answer < /dev/tty\n+\t\t\t        case \"$answer\" in\n+\t\t\t        \ty*|Y*) status=0; break ;;\n+\t\t\t\t\tn*|N*) status=1; break ;;\n+\t\t\t\tesac\n+\t\t\tdone\n+\t\tfi\n+\t\tif test \"$status\" -eq 0; then\n+\t\t    mv \"$BACKUP\" \"$path.orig\"\n+\t\tfi\n+\t        ;;\n+\t    emerge)\n+\t\temacs -f emerge-files-with-ancestor-command \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$path\"\n+\t\tstatus=$?\n+\t\tif test \"$status\" -eq 0; then\n+\t\t    mv \"$BACKUP\" \"$path.orig\"\n+\t\tfi\n+\t\t;;\n+\tesac\n+\trm -f \"$LOCAL\" \"$REMOTE\" \"$BASE\"\n+\tif test \"$status\" -ne 0; then\n+\t\techo \"merge of $path failed\" 1>&2\n+\t\tmv \"$BACKUP\" \"$path\"\n+\t\texit 1\n+\tfi\n+\tgit add \"$path\"\n+}\n+\n+while case $# in 0) break ;; esac\n+do\n+\tcase \"$1\" in\n+\t-t|--tool*)\n+\t\tcase \"$#,$1\" in\n+\t\t*,*=*)\n+\t\t\tmerge_tool=`expr \"z$1\" : 'z-[^=]*=\\(.*\\)'`\n+\t\t\t;;\n+\t\t1,*)\n+\t\t\tusage ;;\n+\t\t*)\n+\t\t\tmerge_tool=\"$2\"\n+\t\t\tshift ;;\n+\t\tesac\n+\t\t;;\n+\t--)\n+\t\tbreak\n+\t\t;;\n+\t-*)\n+\t\tusage\n+\t\t;;\n+\t*)\n+\t\tbreak\n+\t\t;;\n+\tesac\n+\tshift\n+done\n+\n+if test -z \"$merge_tool\"; then\n+    merge_tool=`git-config merge.tool`\n+    if test $merge_tool = kdiff3 -o $merge_tool = tkdiff -o \\\n+\t$merge_tool = xxdiff -o $merge_tool = meld ; then\n+\tunset merge_tool\n+    fi\n+fi\n+\n+if test -z \"$merge_tool\" ; then\n+    if type kdiff3 >/dev/null 2>&1 && test -n \"$DISPLAY\"; then\n+\tmerge_tool=\"kdiff3\";\n+    elif type tkdiff >/dev/null 2>&1 && test -n \"$DISPLAY\"; then\n+    \tmerge_tool=tkdiff\n+    elif type xxdiff >/dev/null 2>&1 && test -n \"$DISPLAY\"; then\n+    \tmerge_tool=xxdiff\n+    elif type meld >/dev/null 2>&1 && test -n \"$DISPLAY\"; then\n+        merge_tool=meld\n+    elif type emacs >/dev/null 2>&1; then\n+        merge_tool=emerge\n+    else\n+\techo \"No available merge tools available.\"\n+\texit 1\n+    fi\n+fi\n+\n+case \"$merge_tool\" in\n+    kdiff3|tkdiff|meld|xxdiff)\n+    \tif ! type \"$merge_tool\" > /dev/null 2>&1; then\n+\t    echo \"The merge tool $merge_tool is not available\"\n+\t    exit 1\n+\tfi\n+\t;;\n+    emerge)\n+    \tif ! type \"emacs\" > /dev/null 2>&1; then\n+\t    echo \"Emacs is not available\"\n+\t    exit 1\n+\tfi\n+\t;;\n+    *)\n+    \techo \"Unknown merge tool: $merge_tool\"\n+\texit 1\n+\t;;\n+esac\n+\n+if test $# -eq 0 ; then\n+\tfiles=`git ls-files -u --abbrev=8 | colrm 1 24 | sort -u`\n+\tif test -z \"$files\" ; then\n+\t\techo \"No files need merging\"\n+\t\texit 0\n+\tfi\n+\techo Merging the files: $files\n+\tgit ls-files -u --abbrev=8 | colrm 1 24 | sort -u | while read i\n+\tdo\n+\t\tmerge_file \"$i\" < /dev/tty > /dev/tty\n+\tdone\n+else\n+\twhile test $# -gt 0; do\n+\t\tmerge_file \"$1\"\n+\t\tshift\n+\tdone\n+fi\n+exit 0 \n-- \n1.5.0.2.312.g5ced-dirty\n"},{"id":"36417","messageId":"7vr6s3sz8r.fsf@assigned-by-dhcp.cox.net","threadId":"7103","inReplyTo":"E1HORtY-0000zK-8B@candygram.thunk.org","subject":"Re: [PATCH] Add git-mergetool to run an appropriate merge conflict resolution program","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-06T05:43:48Z","receivedAt":"2007-03-06T05:43:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Theodore Ts'o\" <tytso@mit.edu> writes:\n\n> +git-mergetool(1)\n> +================\n> +\n> +NAME\n> +----\n> +git-mergetool - Forward-port local commits to the updated upstream head\n> +\n\nHmph.  We already have a tool to achieve such a goal, and that\nis called git-rebase.  Why would we want your program? ;-)\n\n> diff --git a/git-mergetool.sh b/git-mergetool.sh\n> new file mode 100755\n> index 0000000..b961719\n> --- /dev/null\n> +++ b/git-mergetool.sh\n> @@ -0,0 +1,208 @@\n> +#!/bin/sh\n> +#\n> +# This program resolves merge conflicts in git\n> +#\n> +# Copyright (c) 2006 Theodore Y. Ts'o\n> +#\n> +# This file is licensed under the GPL v2, or a later version\n> +# at the discretion of Linus Torvalds.\n\nHeh ;-).\n\n> +#\n> +\n> +usage () {\n> +    echo \"Usage: git mergetool [--tool=tool] [file to merge] ...\"\n> +    exit 1\n> +}\n\nDo we want to do this by hand ourselves, or dot-source sh-setup\nlike others?  You would also get die() for free.\n\n> +merge_file () {\n> ...\n> +\n> +\tif test ! -f \"$path\" ; then\n> +\t\techo \"$path: file not found\"\n> +\t\texit 1\n> +\tfi\n> +\n> +\tf=`git-ls-files -u \"$path\"`\n> +\tif test -z \"$f\" ; then\n> +\t\techo \"$path: file does not need merging\"\n> +\t\texit 1\n> +\tfi\n\nYou should be able to set IFS to exclude SP and then you only\nhave to say you do not support LF and HT, both of which are much\nless likely than SP to be in the pathname.\n\n> +\tmv \"$path\" \"$BACKUP\"\n> +\tcp \"$BACKUP\" \"$path\"\n\nWhat if $path is a symlink blob?  ;-)\n\n> +\tgit cat-file blob \":1:$path\" > \"$BASE\"\n> +\tgit cat-file blob \":2:$path\" > \"$LOCAL\"\n> +\tgit cat-file blob \":3:$path\" > \"$REMOTE\"\n\n> +\tcase \"$merge_tool\" in\n> +\t    kdiff3)\n> ...\n> +\t    tkdiff)\n> ...\n> +\t    meld)\n> ...\n> +\t    xxdiff)\n> ...\n\nIt is depressing to see that the differences between the command\nlines of these have to be much larger than just the command name\nand order of three (or four if we count the result) paths\nparameters.  I was hoping that we could do something like:\n\n\tmergetool -t='newmerge $BASE $LOCAL $REMOTE'\n\n> +\t\txxdiff -X --show-merged-pane \\\n> +\t\t    -R 'Accel.SaveAsMerged: \"Ctrl-S\"' \\\n> +\t\t    -R 'Accel.Search: \"Ctrl+F\"' \\\n> +\t\t    -R 'Accel.SearchForward: \"Ctrl-G\"' \\\n\nDo these configuration belong to individual scripts like this?\n\n> +if test -z \"$merge_tool\" ; then\n> +    if type kdiff3 >/dev/null 2>&1 && test -n \"$DISPLAY\"; then\n> +\tmerge_tool=\"kdiff3\";\n> +    elif type tkdiff >/dev/null 2>&1 && test -n \"$DISPLAY\"; then\n> +    \tmerge_tool=tkdiff\n> +    elif type xxdiff >/dev/null 2>&1 && test -n \"$DISPLAY\"; then\n> +    \tmerge_tool=xxdiff\n> +    elif type meld >/dev/null 2>&1 && test -n \"$DISPLAY\"; then\n> +        merge_tool=meld\n> +    elif type emacs >/dev/null 2>&1; then\n> +        merge_tool=emerge\n> +    else\n> +\techo \"No available merge tools available.\"\n\nCurious choice of words...\n\n> +if test $# -eq 0 ; then\n> +\tfiles=`git ls-files -u --abbrev=8 | colrm 1 24 | sort -u`\n\nCareful.  I think --abbrev=8 just means use at least 8 but more\nas needed to make them unique.  sed -e 's/^[^\t]*\t//'\n(whitespace are HTs) would be safer and simpler, as you are not\ndealing with a pathname that has LF in it anyway.\n"},{"id":"36460","messageId":"20070306124002.GA18370@thunk.org","threadId":"7103","inReplyTo":"7vr6s3sz8r.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add git-mergetool to run an appropriate merge conflict resolution program","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-03-06T12:40:02Z","receivedAt":"2007-03-06T12:40:02Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Mon, Mar 05, 2007 at 09:43:48PM -0800, Junio C Hamano wrote:\n> \"Theodore Ts'o\" <tytso@mit.edu> writes:\n> \n> > +git-mergetool(1)\n> > +================\n> > +\n> > +NAME\n> > +----\n> > +git-mergetool - Forward-port local commits to the updated upstream head\n> > +\n> \n> Hmph.  We already have a tool to achieve such a goal, and that\n> is called git-rebase.  Why would we want your program? ;-)\n\nOops, sorry, I thought I had fixed that.  Guess you figured out which\nprogram I used as a man page template, huh?  :-)\n\n> > +# This file is licensed under the GPL v2, or a later version\n> > +# at the discretion of Linus Torvalds.\n> \n> Heh ;-).\n\nHey, that's what the COPYING file requested, and it was late when I\nstarted doing the git package integration, hence the stupid think-o\nwith the man page.  :-)\n\nI assume you would prefer that it read Junio instead?  Should we\nchange the COPYING while we're at it, perhaps after consulting with\nLinus since he still owns so a fair amount of the copyright on git?\nIt seems that if we're going to pre-collect permissions to move to\nGPLv3, it ought to be either you or him....\n\n> Do we want to do this by hand ourselves, or dot-source sh-setup\n> like others?  You would also get die() for free.\n\nGood point, I'll use git-sh-setup.\n\n> You should be able to set IFS to exclude SP and then you only\n> have to say you do not support LF and HT, both of which are much\n> less likely than SP to be in the pathname.\n\nDo we have any coding guidelines about what characters we have to\nsupport in filenames?  I had assumed that we should support at least\nSP and HT, but life does get easier if we don't need to worry about HT.\n\n> > +\tmv \"$path\" \"$BACKUP\"\n> > +\tcp \"$BACKUP\" \"$path\"\n> \n> What if $path is a symlink blob?  ;-)\n\nYeah, I need to add special case code for symlinks.\n\n> > +\tcase \"$merge_tool\" in\n> > +\t    kdiff3)\n> > ...\n> > +\t    tkdiff)\n> > ...\n> > +\t    meld)\n> > ...\n> > +\t    xxdiff)\n> > ...\n> \n> It is depressing to see that the differences between the command\n> lines of these have to be much larger than just the command name\n> and order of three (or four if we count the result) paths\n> parameters.  \n\n\nYep, it is depressing.  There is no standard calling convention, and\nthere is no standard exit status convention, either.  Hence the\nrequirement for meld and xxdiff to check to see if the file has\nchanged.  Grump....\n\n> > +\t\txxdiff -X --show-merged-pane \\\n> > +\t\t    -R 'Accel.SaveAsMerged: \"Ctrl-S\"' \\\n> > +\t\t    -R 'Accel.Search: \"Ctrl+F\"' \\\n> > +\t\t    -R 'Accel.SearchForward: \"Ctrl-G\"' \\\n> \n> Do these configuration belong to individual scripts like this?\n\nThe problem is that if you don't do this, using xxdiff is user-hostile\nin the extreme.  The problem isn't so much that the save command has\nno accelerators, but the Save menu gives you five (5!) save options.\nYou can save the merged file as:\n\n\t* The right file\n\t* The middle file\n\t* The left file\n\t* The file that was specified as the output on the command-line\n\t* Some user-specified file (save-as)\n\nSo without those resource changes, the user would have to click on the\nFile menu, and drag down to the \"correct\" save option or the file with\nthe resolved merge conflicts would get saved to some random place.\n\nGaaah.  I thought xxdiff was user hostile in the extreme, but Martin\nLanghoff really wanted it, and he was right that xxdiff will give you\na built-in character-diff so you can see what changed on the\nindividual line.  So the resource changes were in my opinion the\nminimum necessary so that the user would have some chance of seeing\nwhich one of the five save options would actually do the right thing\nwith respect to git-mergetool.\n\n> > +\techo \"No available merge tools available.\"\n> \n> Curious choice of words...\n> \n\nYeah, that should probably read \"merge conflict resolution programs\",\neven though that's a lot more words.\n\n> > +if test $# -eq 0 ; then\n> > +\tfiles=`git ls-files -u --abbrev=8 | colrm 1 24 | sort -u`\n> \n> Careful.  I think --abbrev=8 just means use at least 8 but more\n> as needed to make them unique.  sed -e 's/^[^\t]*\t//'\n> (whitespace are HTs) would be safer and simpler, as you are not\n> dealing with a pathname that has LF in it anyway.\n\nOK, I can do that.  Alternatively I guess I could submit a patch which\ncaused git-ls-files to only list the files that still needed merging.\n(i.e., git-ls-files -u --nostage\".)  Do you have any preferences?\n\n\t\t\t\t\t\t- Ted\n"},{"id":"36485","messageId":"Pine.LNX.4.64.0703061454350.5963@woody.linux-foundation.org","threadId":"7103","inReplyTo":"20070306124002.GA18370@thunk.org","subject":"Re: [PATCH] Add git-mergetool to run an appropriate merge conflict resolution program","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-03-06T22:55:58Z","receivedAt":"2007-03-06T22:55:58Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Tue, 6 Mar 2007, Theodore Tso wrote:\n> \n> I assume you would prefer that it read Junio instead?  Should we\n> change the COPYING while we're at it, perhaps after consulting with\n> Linus since he still owns so a fair amount of the copyright on git?\n> It seems that if we're going to pre-collect permissions to move to\n> GPLv3, it ought to be either you or him....\n\nI'm ok with Junio controlling it as far as I'm concerned. After all, he's \nbeen the maintainer for the last two years, so he gets the blame, and he'd \nbetter get the credit too.\n\n\t\t\tLinus\n"},{"id":"36487","messageId":"7vk5xunffk.fsf@assigned-by-dhcp.cox.net","threadId":"7103","inReplyTo":"20070306124002.GA18370@thunk.org","subject":"Re: [PATCH] Add git-mergetool to run an appropriate merge conflict resolution program","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-06T23:02:55Z","receivedAt":"2007-03-06T23:02:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Theodore Tso <tytso@mit.edu> writes:\n\n>> > +# This file is licensed under the GPL v2, or a later version\n>> > +# at the discretion of Linus Torvalds.\n>> \n>> Heh ;-).\n>\n> Hey, that's what the COPYING file requested, and it was late when I\n> started doing the git package integration, hence the stupid think-o\n> with the man page.  :-)\n>\n> I assume you would prefer that it read Junio instead?\n\nOh, no, sorry.  The text itself is just fine as is, if that is\nthe way you want.\n\nI just laughed out because I remembered the list discussion\n(which might also have cc'ed the kernel list, but I do not\nremember) about possible relicensing schenario, where Linus\nmentioned that exact clause in the COPYING file, saying that his\ndiscretion would by now be to let me decide ;-).\n\n>> You should be able to set IFS to exclude SP and then you only\n>> have to say you do not support LF and HT, both of which are much\n>> less likely than SP to be in the pathname.\n>\n> Do we have any coding guidelines about what characters we have to\n> support in filenames?  I had assumed that we should support at least\n> SP and HT, but life does get easier if we don't need to worry about HT.\n\nThe core scripts, at least the ones I personally use, are meant\nto handle all characters, including SP, HT and LF, so if there\nwere any guidelines that would be it.  However, your particular\ncase to interface with external editor needs `eval` with sq\nmagic if it needs to be coded in portable bourne, which can be\ndone, but I suspect it is not worth doing, as we would not see\nHT in pathnames in the practice.  UNIXy folks tend to avoid any\nwhitespaces in the filenames, and Windows folks cannot use HT in\npathnames as far as I understand.\n\n> Yeah, that should probably read \"merge conflict resolution programs\",\n> even though that's a lot more words.\n>\n>> > +if test $# -eq 0 ; then\n>> > +\tfiles=`git ls-files -u --abbrev=8 | colrm 1 24 | sort -u`\n>> \n>> Careful.  I think --abbrev=8 just means use at least 8 but more\n>> as needed to make them unique.  sed -e 's/^[^\t]*\t//'\n>> (whitespace are HTs) would be safer and simpler, as you are not\n>> dealing with a pathname that has LF in it anyway.\n>\n> OK, I can do that.  Alternatively I guess I could submit a patch which\n> caused git-ls-files to only list the files that still needed merging.\n> (i.e., git-ls-files -u --nostage\".)  Do you have any preferences?\n\nThe latter would be more useful in general, and something I\nshould have done long time ago to help scripts.  Thanks.\n"},{"id":"38280","messageId":"7vabxwbszq.fsf@assigned-by-dhcp.cox.net","threadId":"7103","inReplyTo":"E1HORtY-0000zK-8B@candygram.thunk.org","subject":"Re: [PATCH] Add git-mergetool to run an appropriate merge conflict resolution program","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-29T03:58:49Z","receivedAt":"2007-03-29T03:58:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"I had a chance to use git-mergetool in real life for the first\ntime today, when I merged 'maint' into 'master'.  It has a\nsymlink vs symlink conflict, so I got something like this:\n\n================================================================\nMerging the files: RelNotes\n\nSymlink merge conflict for RelNotes:\n    'RelNotes' is a symlink containing 'Documentation/RelNotes-1.5.1.txt' in the local branch\n    'RelNotes' is a symlink containing 'Documentation/RelNotes-1.5.0.6.txt' in the remote branch\nUse (r)emote or (l)ocal, or (a)bort?\n================================================================\n\nA few observations.\n\n(1) Saying \"a\" <Return> does not let me exit.  It keeps asking\n    the same question.\n\n(2) The word \"symlink\" might be less geekish if worded \"symbolic\n    link\".\n\n(3) The message look very long, and repeats the same information.\n\n(4) The status info gives local and then remote, but the choice\n    is between remote and local.\n\nThe attached is a minimum fix for the above issues, but not for\nimmediate application, as I am sure the rewording would make\nmessages inconsistent with other cases.  The updated output\nwould look like this:\n\n================================================================\nMerging the files: RelNotes\n\nSymbolic link merge conflict for 'RelNotes':\n  local: a symbolic link -> 'Documentation/RelNotes-1.5.1.txt'\n  remote: a symbolic link -> 'Documentation/RelNotes-1.5.0.6.txt'\nUse (l)ocal or (r)emote, or (a)bort? l\n================================================================\n\n---\n git-mergetool.sh |   19 ++++++++-----------\n 1 files changed, 8 insertions(+), 11 deletions(-)\n\ndiff --git a/git-mergetool.sh b/git-mergetool.sh\nindex 7942fd0..0b30133 100755\n--- a/git-mergetool.sh\n+++ b/git-mergetool.sh\n@@ -44,27 +44,24 @@ function describe_file () {\n     branch=\"$2\"\n     file=\"$3\"\n \n-    echo -n \"    \"\n+    echo -n \"  ${branch}: \"\n     if test -z \"$mode\"; then\n-\techo -n \"'$path' was deleted\"\n+\techo \"deleted\"\n     elif is_symlink \"$mode\" ; then\n-\techo -n \"'$path' is a symlink containing '\"\n-\tcat \"$file\"\n-\techo -n \"'\"\n+\techo \"a symbolic link -> '$(cat \"$file\")'\"\n     else\n \tif base_present; then\n-\t    echo -n \"'$path' was created\"\n+\t    echo \"created\"\n \telse\n-\t    echo -n \"'$path' was modified\"\n+\t    echo \"modified\"\n \tfi\n     fi\n-    echo \" in the $branch branch\"\n }\n \n \n resolve_symlink_merge () {\n     while /bin/true; do\n-\techo -n \"Use (r)emote or (l)ocal, or (a)bort? \"\n+\techo -n \"Use (l)ocal or (r)emote, or (a)bort? \"\n \tread ans\n \tcase \"$ans\" in\n \t    [lL]*)\n@@ -79,7 +76,7 @@ resolve_symlink_merge () {\n \t\tcleanup_temp_files --save-backup\n \t\treturn\n \t\t;;\n-\t    [qQ]*)\n+\t    [aAqQ]*)\n \t\texit 1\n \t\t;;\n \t    esac\n@@ -147,7 +144,7 @@ merge_file () {\n     fi\n \n     if is_symlink \"$local_mode\" || is_symlink \"$remote_mode\"; then\n-\techo \"Symlink merge conflict for $path:\"\n+\techo \"Symbolic link conflict for '$path':\"\n \tdescribe_file \"$local_mode\" \"local\" \"$LOCAL\"\n \tdescribe_file \"$remote_mode\" \"remote\" \"$REMOTE\"\n \tresolve_symlink_merge\n"},{"id":"38314","messageId":"20070329142044.GH2913@thunk.org","threadId":"7103","inReplyTo":"7vabxwbszq.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add git-mergetool to run an appropriate merge conflict resolution program","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-03-29T14:20:44Z","receivedAt":"2007-03-29T14:20:44Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Wed, Mar 28, 2007 at 08:58:49PM -0700, Junio C Hamano wrote:\n> I had a chance to use git-mergetool in real life for the first\n> time today, when I merged 'maint' into 'master'.  It has a\n> symlink vs symlink conflict, so I got something like this:\n> \n> A few observations.\n> \n> (1) Saying \"a\" <Return> does not let me exit.  It keeps asking\n>     the same question.\n\nYeah, I fixed that last night, along with a bunch of other git\nmergetool cleanups.  I was about to request you to do a pull when I\nnoticed your e-mail. \n\n> (2) The word \"symlink\" might be less geekish if worded \"symbolic\n>     link\".\n> \n> (3) The message look very long, and repeats the same information.\n> \n> (4) The status info gives local and then remote, but the choice\n>     is between remote and local.\n> \n> The attached is a minimum fix for the above issues, but not for\n> immediate application, as I am sure the rewording would make\n> messages inconsistent with other cases.  \n\nOK, let me fix up the display and try to clean up the other messages.\nI agree that your output looks much nicer.\n\n\t\t\t\t\t\t- Ted\n"}]}