{"thread":{"id":"12233","subject":"[RFC/PATCH] mergetool: clarify local/remote terminology","startedAt":"2008-02-21T05:12:56Z","lastAt":"2008-03-01T04:41:55Z","messageCount":10,"participants":["Jay Soffian","Jeff King","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"69452","messageId":"1203570776-62019-1-git-send-email-jaysoffian@gmail.com","threadId":"12233","inReplyTo":null,"subject":"[RFC/PATCH] mergetool: clarify local/remote terminology","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2008-02-21T05:12:56Z","receivedAt":"2008-02-21T05:12:56Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"Always calling the thing on the left-side of a merge \"local\" and on the\nright side \"remote\" isn't correct. You could be rebasing, in which case\nthe left side is the new base/upstream and the right side is the saved\ncommits which are being re-applied. So,\n\n- Use left/right instead of local/remote internally to make the code\n  clearer.\n\n- Add --left and --right options to allow the user to specify their own\n  preferred names for the left/right sides of the merge. Use these when\n  constructing the filenames that are passed to the external mergetool.\n\n- By default call left \"local\" and right \"upstream\", unless a rebase\n  is in progress in which case left=upstream and right=local.\n\nSigned-off-by: Jay Soffian <jaysoffian@gmail.com>\n---\nI think this makes things clearer. In particular I found it confusing when I ran\nmergetool during a rebase and the file tagged LOCAL was the new base, not my\nlocal changes, and REMOTE was actually my saved off commits. Fixing just that\nproblem is a simpler change, but I don't really think using local/remote is\nright anyway.\n\nI played around with trying to use the branch name for left side default name,\nbut again, this became confusing during a rebase, so I think local/upstream make\nthe most sense in general.\n\nThoughts?\n\n git-mergetool.sh |  118 ++++++++++++++++++++++++++++++++++++------------------\n 1 files changed, 79 insertions(+), 39 deletions(-)\n\ndiff --git a/git-mergetool.sh b/git-mergetool.sh\nindex cbbb707..a12b0a2 100755\n--- a/git-mergetool.sh\n+++ b/git-mergetool.sh\n@@ -8,7 +8,7 @@\n # at the discretion of Junio C Hamano.\n #\n \n-USAGE='[--tool=tool] [file to merge] ...'\n+USAGE='[--tool=tool] [--left=name] [--right=name] [file to merge] ...'\n SUBDIRECTORY_OK=Yes\n OPTIONS_SPEC=\n . git-sh-setup\n@@ -20,12 +20,12 @@ is_symlink () {\n     test \"$1\" = 120000\n }\n \n-local_present () {\n-    test -n \"$local_mode\"\n+left_present () {\n+    test -n \"$left_mode\"\n }\n \n-remote_present () {\n-    test -n \"$remote_mode\"\n+right_present () {\n+    test -n \"$right_mode\"\n }\n \n base_present () {\n@@ -35,9 +35,9 @@ base_present () {\n cleanup_temp_files () {\n     if test \"$1\" = --save-backup ; then\n \tmv -- \"$BACKUP\" \"$path.orig\"\n-\trm -f -- \"$LOCAL\" \"$REMOTE\" \"$BASE\"\n+\trm -f -- \"$LEFT\" \"$RIGHT\" \"$BASE\"\n     else\n-\trm -f -- \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$BACKUP\"\n+\trm -f -- \"$LEFT\" \"$RIGHT\" \"$BASE\" \"$BACKUP\"\n     fi\n }\n \n@@ -63,7 +63,8 @@ describe_file () {\n \n resolve_symlink_merge () {\n     while true; do\n-\tprintf \"Use (l)ocal or (r)emote, or (a)bort? \"\n+\tprintf \"Use (l)eft {%s} or (r)ight {%s}, or (a)bort? \" \\\n+\t\t\"$left_desc\" \"$right_desc\"\n \tread ans\n \tcase \"$ans\" in\n \t    [lL]*)\n@@ -154,73 +155,79 @@ merge_file () {\n \n     ext=\"$$$(expr \"$path\" : '.*\\(\\.[^/]*\\)$')\"\n     BACKUP=\"$path.BACKUP.$ext\"\n-    LOCAL=\"$path.LOCAL.$ext\"\n-    REMOTE=\"$path.REMOTE.$ext\"\n+    LEFT_DESC=`echo \"$left_desc\" | tr \"[:lower:]\" \"[:upper:]\" | tr -c '[:alnum:]\\n' _`\n+    RIGHT_DESC=`echo \"$right_desc\" | tr \"[:lower:]\" \"[:upper:]\" | tr -c '[:alnum:]\\n' _`\n+    LEFT=\"$path.$LEFT_DESC.$ext\"\n+    RIGHT=\"$path.$RIGHT_DESC.$ext\"\n     BASE=\"$path.BASE.$ext\"\n \n     mv -- \"$path\" \"$BACKUP\"\n     cp -- \"$BACKUP\" \"$path\"\n \n     base_mode=`git ls-files -u -- \"$path\" | awk '{if ($3==1) print $1;}'`\n-    local_mode=`git ls-files -u -- \"$path\" | awk '{if ($3==2) print $1;}'`\n-    remote_mode=`git ls-files -u -- \"$path\" | awk '{if ($3==3) print $1;}'`\n+    left_mode=`git ls-files -u -- \"$path\" | awk '{if ($3==2) print $1;}'`\n+    right_mode=`git ls-files -u -- \"$path\" | awk '{if ($3==3) print $1;}'`\n \n-    base_present   && git cat-file blob \":1:$prefix$path\" >\"$BASE\" 2>/dev/null\n-    local_present  && git cat-file blob \":2:$prefix$path\" >\"$LOCAL\" 2>/dev/null\n-    remote_present && git cat-file blob \":3:$prefix$path\" >\"$REMOTE\" 2>/dev/null\n+    base_present  && git cat-file blob \":1:$prefix$path\" >\"$BASE\" 2>/dev/null\n+    left_present  && git cat-file blob \":2:$prefix$path\" >\"$LEFT\" 2>/dev/null\n+    right_present && git cat-file blob \":3:$prefix$path\" >\"$RIGHT\" 2>/dev/null\n \n-    if test -z \"$local_mode\" -o -z \"$remote_mode\"; then\n+    if test -z \"$left_mode\" -o -z \"$right_mode\"; then\n \techo \"Deleted merge conflict for '$path':\"\n-\tdescribe_file \"$local_mode\" \"local\" \"$LOCAL\"\n-\tdescribe_file \"$remote_mode\" \"remote\" \"$REMOTE\"\n+\tdescribe_file \"$left_mode\" \"$left_desc\" \"$LEFT\"\n+\tdescribe_file \"$right_mode\" \"$right_desc\" \"$RIGHT\"\n \tresolve_deleted_merge\n \treturn\n     fi\n \n-    if is_symlink \"$local_mode\" || is_symlink \"$remote_mode\"; then\n+    if is_symlink \"$left_mode\" || is_symlink \"$right_mode\"; then\n \techo \"Symbolic link merge conflict for '$path':\"\n-\tdescribe_file \"$local_mode\" \"local\" \"$LOCAL\"\n-\tdescribe_file \"$remote_mode\" \"remote\" \"$REMOTE\"\n+\tdescribe_file \"$left_mode\" \"$left_desc\" \"$LEFT\"\n+\tdescribe_file \"$right_mode\" \"$right_desc\" \"$RIGHT\"\n \tresolve_symlink_merge\n \treturn\n     fi\n \n     echo \"Normal merge conflict for '$path':\"\n-    describe_file \"$local_mode\" \"local\" \"$LOCAL\"\n-    describe_file \"$remote_mode\" \"remote\" \"$REMOTE\"\n+    describe_file \"$left_mode\" \"$left_desc\" \"$LEFT\"\n+    describe_file \"$right_mode\" \"$right_desc\" \"$RIGHT\"\n     printf \"Hit return to start merge resolution tool (%s): \" \"$merge_tool\"\n     read ans\n \n     case \"$merge_tool\" in\n \tkdiff3)\n+\t    Left=$(echo \"$left_desc\" | \\\n+\t           awk '{printf(\"%s%s\",toupper(substr($0,1,1)),substr($0,2))}')\n+\t    Right=$(echo \"$right_desc\" | \\\n+\t            awk '{printf(\"%s%s\",toupper(substr($0,1,1)),substr($0,2))}')\n \t    if base_present ; then\n-\t\t(\"$merge_tool_path\" --auto --L1 \"$path (Base)\" --L2 \"$path (Local)\" --L3 \"$path (Remote)\" \\\n-\t\t    -o \"$path\" -- \"$BASE\" \"$LOCAL\" \"$REMOTE\" > /dev/null 2>&1)\n+\t\t(\"$merge_tool_path\" --auto --L1 \"$path (Base)\" --L2 \"$path ($Left)\" --L3 \"$path ($Right)\" \\\n+\t\t    -o \"$path\" -- \"$BASE\" \"$LEFT\" \"$RIGHT\" > /dev/null 2>&1)\n \t    else\n-\t\t(\"$merge_tool_path\" --auto --L1 \"$path (Local)\" --L2 \"$path (Remote)\" \\\n-\t\t    -o \"$path\" -- \"$LOCAL\" \"$REMOTE\" > /dev/null 2>&1)\n+\t\t(\"$merge_tool_path\" --auto --L1 \"$path ($Left)\" --L2 \"$path ($Right)\" \\\n+\t\t    -o \"$path\" -- \"$LEFT\" \"$RIGHT\" > /dev/null 2>&1)\n \t    fi\n \t    status=$?\n \t    remove_backup\n \t    ;;\n \ttkdiff)\n \t    if base_present ; then\n-\t\t\"$merge_tool_path\" -a \"$BASE\" -o \"$path\" -- \"$LOCAL\" \"$REMOTE\"\n+\t\t\"$merge_tool_path\" -a \"$BASE\" -o \"$path\" -- \"$LEFT\" \"$RIGHT\"\n \t    else\n-\t\t\"$merge_tool_path\" -o \"$path\" -- \"$LOCAL\" \"$REMOTE\"\n+\t\t\"$merge_tool_path\" -o \"$path\" -- \"$LEFT\" \"$RIGHT\"\n \t    fi\n \t    status=$?\n \t    save_backup\n \t    ;;\n \tmeld|vimdiff)\n \t    touch \"$BACKUP\"\n-\t    \"$merge_tool_path\" -- \"$LOCAL\" \"$path\" \"$REMOTE\"\n+\t    \"$merge_tool_path\" -- \"$LEFT\" \"$path\" \"$RIGHT\"\n \t    check_unchanged\n \t    save_backup\n \t    ;;\n \tgvimdiff)\n \t\ttouch \"$BACKUP\"\n-\t\t\"$merge_tool_path\" -f -- \"$LOCAL\" \"$path\" \"$REMOTE\"\n+\t\t\"$merge_tool_path\" -f -- \"$LEFT\" \"$path\" \"$RIGHT\"\n \t\tcheck_unchanged\n \t\tsave_backup\n \t\t;;\n@@ -231,13 +238,13 @@ merge_file () {\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\t    --merged-file \"$path\" -- \"$LEFT\" \"$BASE\" \"$RIGHT\"\n \t    else\n \t\t\"$merge_tool_path\" -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\" \"$REMOTE\"\n+\t\t    --merged-file \"$path\" -- \"$LEFT\" \"$RIGHT\"\n \t    fi\n \t    check_unchanged\n \t    save_backup\n@@ -245,9 +252,9 @@ merge_file () {\n \topendiff)\n \t    touch \"$BACKUP\"\n \t    if base_present; then\n-\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" -ancestor \"$BASE\" -merge \"$path\" | cat\n+\t\t\"$merge_tool_path\" \"$LEFT\" \"$RIGHT\" -ancestor \"$BASE\" -merge \"$path\" | cat\n \t    else\n-\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" -merge \"$path\" | cat\n+\t\t\"$merge_tool_path\" \"$LEFT\" \"$RIGHT\" -merge \"$path\" | cat\n \t    fi\n \t    check_unchanged\n \t    save_backup\n@@ -255,18 +262,18 @@ merge_file () {\n \tecmerge)\n \t    touch \"$BACKUP\"\n \t    if base_present; then\n-\t\t\"$merge_tool_path\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" --mode=merge3 --to=\"$path\"\n+\t\t\"$merge_tool_path\" \"$BASE\" \"$LEFT\" \"$RIGHT\" --mode=merge3 --to=\"$path\"\n \t    else\n-\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" --mode=merge2 --to=\"$path\"\n+\t\t\"$merge_tool_path\" \"$LEFT\" \"$RIGHT\" --mode=merge2 --to=\"$path\"\n \t    fi\n \t    check_unchanged\n \t    save_backup\n \t    ;;\n \temerge)\n \t    if base_present ; then\n-\t\t\"$merge_tool_path\" -f emerge-files-with-ancestor-command \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$(basename \"$path\")\"\n+\t\t\"$merge_tool_path\" -f emerge-files-with-ancestor-command \"$LEFT\" \"$RIGHT\" \"$BASE\" \"$(basename \"$path\")\"\n \t    else\n-\t\t\"$merge_tool_path\" -f emerge-files-command \"$LOCAL\" \"$REMOTE\" \"$(basename \"$path\")\"\n+\t\t\"$merge_tool_path\" -f emerge-files-command \"$LEFT\" \"$RIGHT\" \"$(basename \"$path\")\"\n \t    fi\n \t    status=$?\n \t    save_backup\n@@ -296,6 +303,30 @@ do\n \t\t    shift ;;\n \t    esac\n \t    ;;\n+\t-l|--left*)\n+\t    case \"$#,$1\" in\n+\t\t*,*=*)\n+\t\t    left_desc=`expr \"z$1\" : 'z-[^=]*=\\(.*\\)'`\n+\t\t    ;;\n+\t\t1,*)\n+\t\t    usage ;;\n+\t\t*)\n+\t\t    left_desc=\"$2\"\n+\t\t    shift ;;\n+\t    esac\n+\t    ;;\n+\t-r|--right*)\n+\t    case \"$#,$1\" in\n+\t\t*,*=*)\n+\t\t    right_desc=`expr \"z$1\" : 'z-[^=]*=\\(.*\\)'`\n+\t\t    ;;\n+\t\t1,*)\n+\t\t    usage ;;\n+\t\t*)\n+\t\t    right_desc=\"$2\"\n+\t\t    shift ;;\n+\t    esac\n+\t    ;;\n \t--)\n \t    break\n \t    ;;\n@@ -386,6 +417,15 @@ else\n     fi\n fi\n \n+if test -z \"$left_desc\" || test -z \"$right_desc\"; then\n+    if test -d \"$GIT_DIR/../.dotest\" || test -f \"$GIT_DIR/.dotest-merge/head-name\"; then\n+\tleft_desc=\"${left_desc:-upstream}\"\n+\tright_desc=\"${right_desc:-local}\"\n+    else\n+\tleft_desc=\"${left_desc:-local}\"\n+\tright_desc=\"${right_desc:-upstream}\"\n+    fi\n+fi\n \n if test $# -eq 0 ; then\n \tfiles=`git ls-files -u | sed -e 's/^[^\t]*\t//' | sort -u`\n-- \n1.5.4.2.236.g77b4.dirty\n"},{"id":"69886","messageId":"76718490802250631p262baf1bw23873e5fdbbb7180@mail.gmail.com","threadId":"12233","inReplyTo":"1203570776-62019-1-git-send-email-jaysoffian@gmail.com","subject":"Re: [RFC/PATCH] mergetool: clarify local/remote terminology","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2008-02-25T14:31:03Z","receivedAt":"2008-02-25T14:31:03Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"Anyone?\n\nOn Thu, Feb 21, 2008 at 12:12 AM, Jay Soffian <jaysoffian@gmail.com> wrote:\n> Always calling the thing on the left-side of a merge \"local\" and on the\n>  right side \"remote\" isn't correct. You could be rebasing, in which case\n>  the left side is the new base/upstream and the right side is the saved\n>  commits which are being re-applied. So,\n>\n>  - Use left/right instead of local/remote internally to make the code\n>   clearer.\n>\n>  - Add --left and --right options to allow the user to specify their own\n>   preferred names for the left/right sides of the merge. Use these when\n>   constructing the filenames that are passed to the external mergetool.\n>\n>  - By default call left \"local\" and right \"upstream\", unless a rebase\n>   is in progress in which case left=upstream and right=local.\n>\n>  Signed-off-by: Jay Soffian <jaysoffian@gmail.com>\n>  ---\n>  I think this makes things clearer. In particular I found it confusing when I ran\n>  mergetool during a rebase and the file tagged LOCAL was the new base, not my\n>  local changes, and REMOTE was actually my saved off commits. Fixing just that\n>  problem is a simpler change, but I don't really think using local/remote is\n>  right anyway.\n>\n>  I played around with trying to use the branch name for left side default name,\n>  but again, this became confusing during a rebase, so I think local/upstream make\n>  the most sense in general.\n>\n>  Thoughts?\n>\n>   git-mergetool.sh |  118 ++++++++++++++++++++++++++++++++++++------------------\n>   1 files changed, 79 insertions(+), 39 deletions(-)\n>\n>  diff --git a/git-mergetool.sh b/git-mergetool.sh\n>  index cbbb707..a12b0a2 100755\n>  --- a/git-mergetool.sh\n>  +++ b/git-mergetool.sh\n>  @@ -8,7 +8,7 @@\n>   # at the discretion of Junio C Hamano.\n>   #\n>\n>  -USAGE='[--tool=tool] [file to merge] ...'\n>  +USAGE='[--tool=tool] [--left=name] [--right=name] [file to merge] ...'\n>   SUBDIRECTORY_OK=Yes\n>   OPTIONS_SPEC=\n>   . git-sh-setup\n>  @@ -20,12 +20,12 @@ is_symlink () {\n>      test \"$1\" = 120000\n>   }\n>\n>  -local_present () {\n>  -    test -n \"$local_mode\"\n>  +left_present () {\n>  +    test -n \"$left_mode\"\n>   }\n>\n>  -remote_present () {\n>  -    test -n \"$remote_mode\"\n>  +right_present () {\n>  +    test -n \"$right_mode\"\n>   }\n>\n>   base_present () {\n>  @@ -35,9 +35,9 @@ base_present () {\n>   cleanup_temp_files () {\n>      if test \"$1\" = --save-backup ; then\n>         mv -- \"$BACKUP\" \"$path.orig\"\n>  -       rm -f -- \"$LOCAL\" \"$REMOTE\" \"$BASE\"\n>  +       rm -f -- \"$LEFT\" \"$RIGHT\" \"$BASE\"\n>      else\n>  -       rm -f -- \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$BACKUP\"\n>  +       rm -f -- \"$LEFT\" \"$RIGHT\" \"$BASE\" \"$BACKUP\"\n>      fi\n>   }\n>\n>  @@ -63,7 +63,8 @@ describe_file () {\n>\n>   resolve_symlink_merge () {\n>      while true; do\n>  -       printf \"Use (l)ocal or (r)emote, or (a)bort? \"\n>  +       printf \"Use (l)eft {%s} or (r)ight {%s}, or (a)bort? \" \\\n>  +               \"$left_desc\" \"$right_desc\"\n>         read ans\n>         case \"$ans\" in\n>             [lL]*)\n>  @@ -154,73 +155,79 @@ merge_file () {\n>\n>      ext=\"$$$(expr \"$path\" : '.*\\(\\.[^/]*\\)$')\"\n>      BACKUP=\"$path.BACKUP.$ext\"\n>  -    LOCAL=\"$path.LOCAL.$ext\"\n>  -    REMOTE=\"$path.REMOTE.$ext\"\n>  +    LEFT_DESC=`echo \"$left_desc\" | tr \"[:lower:]\" \"[:upper:]\" | tr -c '[:alnum:]\\n' _`\n>  +    RIGHT_DESC=`echo \"$right_desc\" | tr \"[:lower:]\" \"[:upper:]\" | tr -c '[:alnum:]\\n' _`\n>  +    LEFT=\"$path.$LEFT_DESC.$ext\"\n>  +    RIGHT=\"$path.$RIGHT_DESC.$ext\"\n>      BASE=\"$path.BASE.$ext\"\n>\n>      mv -- \"$path\" \"$BACKUP\"\n>      cp -- \"$BACKUP\" \"$path\"\n>\n>      base_mode=`git ls-files -u -- \"$path\" | awk '{if ($3==1) print $1;}'`\n>  -    local_mode=`git ls-files -u -- \"$path\" | awk '{if ($3==2) print $1;}'`\n>  -    remote_mode=`git ls-files -u -- \"$path\" | awk '{if ($3==3) print $1;}'`\n>  +    left_mode=`git ls-files -u -- \"$path\" | awk '{if ($3==2) print $1;}'`\n>  +    right_mode=`git ls-files -u -- \"$path\" | awk '{if ($3==3) print $1;}'`\n>\n>  -    base_present   && git cat-file blob \":1:$prefix$path\" >\"$BASE\" 2>/dev/null\n>  -    local_present  && git cat-file blob \":2:$prefix$path\" >\"$LOCAL\" 2>/dev/null\n>  -    remote_present && git cat-file blob \":3:$prefix$path\" >\"$REMOTE\" 2>/dev/null\n>  +    base_present  && git cat-file blob \":1:$prefix$path\" >\"$BASE\" 2>/dev/null\n>  +    left_present  && git cat-file blob \":2:$prefix$path\" >\"$LEFT\" 2>/dev/null\n>  +    right_present && git cat-file blob \":3:$prefix$path\" >\"$RIGHT\" 2>/dev/null\n>\n>  -    if test -z \"$local_mode\" -o -z \"$remote_mode\"; then\n>  +    if test -z \"$left_mode\" -o -z \"$right_mode\"; then\n>         echo \"Deleted merge conflict for '$path':\"\n>  -       describe_file \"$local_mode\" \"local\" \"$LOCAL\"\n>  -       describe_file \"$remote_mode\" \"remote\" \"$REMOTE\"\n>  +       describe_file \"$left_mode\" \"$left_desc\" \"$LEFT\"\n>  +       describe_file \"$right_mode\" \"$right_desc\" \"$RIGHT\"\n>         resolve_deleted_merge\n>         return\n>      fi\n>\n>  -    if is_symlink \"$local_mode\" || is_symlink \"$remote_mode\"; then\n>  +    if is_symlink \"$left_mode\" || is_symlink \"$right_mode\"; then\n>         echo \"Symbolic link merge conflict for '$path':\"\n>  -       describe_file \"$local_mode\" \"local\" \"$LOCAL\"\n>  -       describe_file \"$remote_mode\" \"remote\" \"$REMOTE\"\n>  +       describe_file \"$left_mode\" \"$left_desc\" \"$LEFT\"\n>  +       describe_file \"$right_mode\" \"$right_desc\" \"$RIGHT\"\n>         resolve_symlink_merge\n>         return\n>      fi\n>\n>      echo \"Normal merge conflict for '$path':\"\n>  -    describe_file \"$local_mode\" \"local\" \"$LOCAL\"\n>  -    describe_file \"$remote_mode\" \"remote\" \"$REMOTE\"\n>  +    describe_file \"$left_mode\" \"$left_desc\" \"$LEFT\"\n>  +    describe_file \"$right_mode\" \"$right_desc\" \"$RIGHT\"\n>      printf \"Hit return to start merge resolution tool (%s): \" \"$merge_tool\"\n>      read ans\n>\n>      case \"$merge_tool\" in\n>         kdiff3)\n>  +           Left=$(echo \"$left_desc\" | \\\n>  +                  awk '{printf(\"%s%s\",toupper(substr($0,1,1)),substr($0,2))}')\n>  +           Right=$(echo \"$right_desc\" | \\\n>  +                   awk '{printf(\"%s%s\",toupper(substr($0,1,1)),substr($0,2))}')\n>             if base_present ; then\n>  -               (\"$merge_tool_path\" --auto --L1 \"$path (Base)\" --L2 \"$path (Local)\" --L3 \"$path (Remote)\" \\\n>  -                   -o \"$path\" -- \"$BASE\" \"$LOCAL\" \"$REMOTE\" > /dev/null 2>&1)\n>  +               (\"$merge_tool_path\" --auto --L1 \"$path (Base)\" --L2 \"$path ($Left)\" --L3 \"$path ($Right)\" \\\n>  +                   -o \"$path\" -- \"$BASE\" \"$LEFT\" \"$RIGHT\" > /dev/null 2>&1)\n>             else\n>  -               (\"$merge_tool_path\" --auto --L1 \"$path (Local)\" --L2 \"$path (Remote)\" \\\n>  -                   -o \"$path\" -- \"$LOCAL\" \"$REMOTE\" > /dev/null 2>&1)\n>  +               (\"$merge_tool_path\" --auto --L1 \"$path ($Left)\" --L2 \"$path ($Right)\" \\\n>  +                   -o \"$path\" -- \"$LEFT\" \"$RIGHT\" > /dev/null 2>&1)\n>             fi\n>             status=$?\n>             remove_backup\n>             ;;\n>         tkdiff)\n>             if base_present ; then\n>  -               \"$merge_tool_path\" -a \"$BASE\" -o \"$path\" -- \"$LOCAL\" \"$REMOTE\"\n>  +               \"$merge_tool_path\" -a \"$BASE\" -o \"$path\" -- \"$LEFT\" \"$RIGHT\"\n>             else\n>  -               \"$merge_tool_path\" -o \"$path\" -- \"$LOCAL\" \"$REMOTE\"\n>  +               \"$merge_tool_path\" -o \"$path\" -- \"$LEFT\" \"$RIGHT\"\n>             fi\n>             status=$?\n>             save_backup\n>             ;;\n>         meld|vimdiff)\n>             touch \"$BACKUP\"\n>  -           \"$merge_tool_path\" -- \"$LOCAL\" \"$path\" \"$REMOTE\"\n>  +           \"$merge_tool_path\" -- \"$LEFT\" \"$path\" \"$RIGHT\"\n>             check_unchanged\n>             save_backup\n>             ;;\n>         gvimdiff)\n>                 touch \"$BACKUP\"\n>  -               \"$merge_tool_path\" -f -- \"$LOCAL\" \"$path\" \"$REMOTE\"\n>  +               \"$merge_tool_path\" -f -- \"$LEFT\" \"$path\" \"$RIGHT\"\n>                 check_unchanged\n>                 save_backup\n>                 ;;\n>  @@ -231,13 +238,13 @@ merge_file () {\n>                     -R 'Accel.SaveAsMerged: \"Ctrl-S\"' \\\n>                     -R 'Accel.Search: \"Ctrl+F\"' \\\n>                     -R 'Accel.SearchForward: \"Ctrl-G\"' \\\n>  -                   --merged-file \"$path\" -- \"$LOCAL\" \"$BASE\" \"$REMOTE\"\n>  +                   --merged-file \"$path\" -- \"$LEFT\" \"$BASE\" \"$RIGHT\"\n>             else\n>                 \"$merge_tool_path\" -X --show-merged-pane \\\n>                     -R 'Accel.SaveAsMerged: \"Ctrl-S\"' \\\n>                     -R 'Accel.Search: \"Ctrl+F\"' \\\n>                     -R 'Accel.SearchForward: \"Ctrl-G\"' \\\n>  -                   --merged-file \"$path\" -- \"$LOCAL\" \"$REMOTE\"\n>  +                   --merged-file \"$path\" -- \"$LEFT\" \"$RIGHT\"\n>             fi\n>             check_unchanged\n>             save_backup\n>  @@ -245,9 +252,9 @@ merge_file () {\n>         opendiff)\n>             touch \"$BACKUP\"\n>             if base_present; then\n>  -               \"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" -ancestor \"$BASE\" -merge \"$path\" | cat\n>  +               \"$merge_tool_path\" \"$LEFT\" \"$RIGHT\" -ancestor \"$BASE\" -merge \"$path\" | cat\n>             else\n>  -               \"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" -merge \"$path\" | cat\n>  +               \"$merge_tool_path\" \"$LEFT\" \"$RIGHT\" -merge \"$path\" | cat\n>             fi\n>             check_unchanged\n>             save_backup\n>  @@ -255,18 +262,18 @@ merge_file () {\n>         ecmerge)\n>             touch \"$BACKUP\"\n>             if base_present; then\n>  -               \"$merge_tool_path\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" --mode=merge3 --to=\"$path\"\n>  +               \"$merge_tool_path\" \"$BASE\" \"$LEFT\" \"$RIGHT\" --mode=merge3 --to=\"$path\"\n>             else\n>  -               \"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" --mode=merge2 --to=\"$path\"\n>  +               \"$merge_tool_path\" \"$LEFT\" \"$RIGHT\" --mode=merge2 --to=\"$path\"\n>             fi\n>             check_unchanged\n>             save_backup\n>             ;;\n>         emerge)\n>             if base_present ; then\n>  -               \"$merge_tool_path\" -f emerge-files-with-ancestor-command \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$(basename \"$path\")\"\n>  +               \"$merge_tool_path\" -f emerge-files-with-ancestor-command \"$LEFT\" \"$RIGHT\" \"$BASE\" \"$(basename \"$path\")\"\n>             else\n>  -               \"$merge_tool_path\" -f emerge-files-command \"$LOCAL\" \"$REMOTE\" \"$(basename \"$path\")\"\n>  +               \"$merge_tool_path\" -f emerge-files-command \"$LEFT\" \"$RIGHT\" \"$(basename \"$path\")\"\n>             fi\n>             status=$?\n>             save_backup\n>  @@ -296,6 +303,30 @@ do\n>                     shift ;;\n>             esac\n>             ;;\n>  +       -l|--left*)\n>  +           case \"$#,$1\" in\n>  +               *,*=*)\n>  +                   left_desc=`expr \"z$1\" : 'z-[^=]*=\\(.*\\)'`\n>  +                   ;;\n>  +               1,*)\n>  +                   usage ;;\n>  +               *)\n>  +                   left_desc=\"$2\"\n>  +                   shift ;;\n>  +           esac\n>  +           ;;\n>  +       -r|--right*)\n>  +           case \"$#,$1\" in\n>  +               *,*=*)\n>  +                   right_desc=`expr \"z$1\" : 'z-[^=]*=\\(.*\\)'`\n>  +                   ;;\n>  +               1,*)\n>  +                   usage ;;\n>  +               *)\n>  +                   right_desc=\"$2\"\n>  +                   shift ;;\n>  +           esac\n>  +           ;;\n>         --)\n>             break\n>             ;;\n>  @@ -386,6 +417,15 @@ else\n>      fi\n>   fi\n>\n>  +if test -z \"$left_desc\" || test -z \"$right_desc\"; then\n>  +    if test -d \"$GIT_DIR/../.dotest\" || test -f \"$GIT_DIR/.dotest-merge/head-name\"; then\n>  +       left_desc=\"${left_desc:-upstream}\"\n>  +       right_desc=\"${right_desc:-local}\"\n>  +    else\n>  +       left_desc=\"${left_desc:-local}\"\n>  +       right_desc=\"${right_desc:-upstream}\"\n>  +    fi\n>  +fi\n>\n>   if test $# -eq 0 ; then\n>         files=`git ls-files -u | sed -e 's/^[^  ]*      //' | sort -u`\n>  --\n>  1.5.4.2.236.g77b4.dirty\n>\n>\n"},{"id":"69899","messageId":"20080225184648.GC15131@sigill.intra.peff.net","threadId":"12233","inReplyTo":"76718490802250631p262baf1bw23873e5fdbbb7180@mail.gmail.com","subject":"Re: [RFC/PATCH] mergetool: clarify local/remote terminology","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-02-25T18:46:48Z","receivedAt":"2008-02-25T18:46:48Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Feb 25, 2008 at 09:31:03AM -0500, Jay Soffian wrote:\n\n> Anyone?\n> \n> On Thu, Feb 21, 2008 at 12:12 AM, Jay Soffian <jaysoffian@gmail.com> wrote:\n> > Always calling the thing on the left-side of a merge \"local\" and on the\n> >  right side \"remote\" isn't correct. You could be rebasing, in which case\n> >  the left side is the new base/upstream and the right side is the saved\n> >  commits which are being re-applied. So,\n\nI have been annoyed by this in the past, too. And I think your change is\nprobably an improvement (though I haven't tried it yet). As a user, what\nI would _really_ like to see, though, is simply the branch names:\n\"origin/next\" versus \"next\". I looked at using the GITHEAD_* mechanism\nin the past, but that relies on the environment, which can't get\ndirectly to mergetool. See this thread:\n\nhttp://mid.gmane.org/20070820075318.GA12478@coredump.intra.peff.net\n\nI think the right thing to do is the oft-discussed-but-never-implemented\n\"what's happening right now\" file/command that would say:\n\n  1. there's a rebase happening now\n  2. the upstream branch is X\n  3. the rebased branch is Y\n\nbut that could also of course say\n\n  1. there's a merge happening now\n  2. the first parent is X\n  3. the second parent is Y\n\nand so on (including \"we're in a git-am, git-cherry-pick, etc\").\n\nI'll try out your patch and comment next time I use it.\n\n-Peff\n"},{"id":"69905","messageId":"76718490802251107y44ff2d6ahf5446ae0408c67b0@mail.gmail.com","threadId":"12233","inReplyTo":"20080225184648.GC15131@sigill.intra.peff.net","subject":"Re: [RFC/PATCH] mergetool: clarify local/remote terminology","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2008-02-25T19:07:11Z","receivedAt":"2008-02-25T19:07:11Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Mon, Feb 25, 2008 at 1:46 PM, Jeff King <peff@peff.net> wrote:\n\n>  I have been annoyed by this in the past, too. And I think your change is\n>  probably an improvement (though I haven't tried it yet). As a user, what\n>  I would _really_ like to see, though, is simply the branch names:\n>  \"origin/next\" versus \"next\".\n\nI was playing with that, figuring out branch names in the same way that the\ncode in bashcompletions computes ps1. However, what would you want to see if\nyou're doing an interactive rebase of say HEAD vs HEAD~5. They are both the\nsame branch, so what would you want to see?\n\n>  I looked at using the GITHEAD_* mechanism\n>  in the past, but that relies on the environment, which can't get\n>  directly to mergetool. See this thread:\n>\n>  http://mid.gmane.org/20070820075318.GA12478@coredump.intra.peff.net\n>\n>  I think the right thing to do is the oft-discussed-but-never-implemented\n>  \"what's happening right now\" file/command that would say:\n>\n>   1. there's a rebase happening now\n>   2. the upstream branch is X\n>   3. the rebased branch is Y\n>\n>  but that could also of course say\n>\n>   1. there's a merge happening now\n>   2. the first parent is X\n>   3. the second parent is Y\n>\n>  and so on (including \"we're in a git-am, git-cherry-pick, etc\").\n\nOkay, I'll look into that.\n\n>  I'll try out your patch and comment next time I use it.\n\nAppreciated.\n\nj.\n"},{"id":"69907","messageId":"20080225192106.GB19666@sigill.intra.peff.net","threadId":"12233","inReplyTo":"76718490802251107y44ff2d6ahf5446ae0408c67b0@mail.gmail.com","subject":"Re: [RFC/PATCH] mergetool: clarify local/remote terminology","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-02-25T19:21:06Z","receivedAt":"2008-02-25T19:21:06Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Feb 25, 2008 at 02:07:11PM -0500, Jay Soffian wrote:\n\n> I was playing with that, figuring out branch names in the same way that the\n> code in bashcompletions computes ps1. However, what would you want to see if\n> you're doing an interactive rebase of say HEAD vs HEAD~5. They are both the\n> same branch, so what would you want to see?\n\nProbably HEAD and HEAD~5 (perhaps along with their oneline logs). I\nthink the best we can do is \"whatever the user said to get us here\"\nwhich is not something you can calculate after the fact; you have to\nremember what the user said.\n\n-Peff\n"},{"id":"69915","messageId":"76718490802251209u240bc0b2s8e268c7f1943c3d9@mail.gmail.com","threadId":"12233","inReplyTo":"20080225192106.GB19666@sigill.intra.peff.net","subject":"Re: [RFC/PATCH] mergetool: clarify local/remote terminology","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2008-02-25T20:09:04Z","receivedAt":"2008-02-25T20:09:04Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Mon, Feb 25, 2008 at 2:21 PM, Jeff King <peff@peff.net> wrote:\n\n>  Probably HEAD and HEAD~5 (perhaps along with their oneline logs). I\n>  think the best we can do is \"whatever the user said to get us here\"\n>  which is not something you can calculate after the fact; you have to\n>  remember what the user said.\n\nRight, so the porcelain would have to save this information somewhere\nfor mergetool to access (yes/no/maybe?).\n\nAnyway, that's why the first iteration of my patch takes --left\nand --right arguments so at least you can tell it how you got\nthere.\n\nj.\n"},{"id":"69916","messageId":"20080225201102.GA21928@coredump.intra.peff.net","threadId":"12233","inReplyTo":"76718490802251209u240bc0b2s8e268c7f1943c3d9@mail.gmail.com","subject":"Re: [RFC/PATCH] mergetool: clarify local/remote terminology","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-02-25T20:11:02Z","receivedAt":"2008-02-25T20:11:02Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Feb 25, 2008 at 03:09:04PM -0500, Jay Soffian wrote:\n\n> >  Probably HEAD and HEAD~5 (perhaps along with their oneline logs). I\n> >  think the best we can do is \"whatever the user said to get us here\"\n> >  which is not something you can calculate after the fact; you have to\n> >  remember what the user said.\n> \n> Right, so the porcelain would have to save this information somewhere\n> for mergetool to access (yes/no/maybe?).\n\nYes (that's what would go into a .git/status type of file).\n\n> Anyway, that's why the first iteration of my patch takes --left\n> and --right arguments so at least you can tell it how you got\n> there.\n\nYes, I saw that. The problem is that git-mergetool is invoked by the\nuser. Is it really improving the usability to have to manually specify\n--left and --right? Saving and restoring the state seems like the only\nuseful option.\n\n-Peff\n"},{"id":"70225","messageId":"20080228084328.GA18350@coredump.intra.peff.net","threadId":"12233","inReplyTo":"20080225184648.GC15131@sigill.intra.peff.net","subject":"Re: [RFC/PATCH] mergetool: clarify local/remote terminology","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-02-28T08:43:28Z","receivedAt":"2008-02-28T08:43:28Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Feb 25, 2008 at 01:46:48PM -0500, Jeff King wrote:\n\n> > On Thu, Feb 21, 2008 at 12:12 AM, Jay Soffian <jaysoffian@gmail.com> wrote:\n> > > Always calling the thing on the left-side of a merge \"local\" and on the\n> > >  right side \"remote\" isn't correct. You could be rebasing, in which case\n> > >  the left side is the new base/upstream and the right side is the saved\n> > >  commits which are being re-applied. So,\n> \n> I'll try out your patch and comment next time I use it.\n\nI finally got a chance to use this today (hey, I don't get a lot of\nconflicts!).\n\nI like it; I think it made it a lot more obvious which side was which\nduring the rebase. I checked with cherry-pick, as well; it more or less\nmakes sense, except that the cherry-picked commit is called \"upstream.\"\nWhich sort of makes sense, but it would be nice to call it something\nmore obvious. Unfortunately I'm not sure that there is a good way to\ndetermine we are in a failed cherry-pick (probably a failed 'revert' is\nin a similar situation).\n\nSo like I said before, I think the eventual \"right\" thing is to have a\nmore verbose status file. But in the meantime, I think this patch is\nsensible.\n\n-Peff\n"},{"id":"70362","messageId":"7v3arcfh54.fsf@gitster.siamese.dyndns.org","threadId":"12233","inReplyTo":"20080228084328.GA18350@coredump.intra.peff.net","subject":"Re: [RFC/PATCH] mergetool: clarify local/remote terminology","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-02-29T05:47:35Z","receivedAt":"2008-02-29T05:47:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> I like it; I think it made it a lot more obvious which side was which\n> during the rebase. I checked with cherry-pick, as well; it more or less\n> makes sense, except that the cherry-picked commit is called \"upstream.\"\n\nWhile I like the fact that somebody is trying to tackle the\nconsistency issue, I do not like the approach itself.  Fudging\nthe issue at the merge-tool UI level may make things appear more\nconsistent when viewing the merge from within merge-tool, but it\nmakes the views merge-tool gives and vi/less gives inconsistent.\n\nIt would be a lot more sensible to make sure that we always show\nthe side that the end-user modified first and then the side the\nother party changed.\n\nA regular merge, cherry-pick and revert all start from user's\nside and play the change from the other side, and conflicted\nhunks are shown in the right order.  It is only \"rebase\" (with\nor without -m) that gets it wrong.  Even though it internally\noperates as if our own changes are coming from the other side,\nwe should show our change first and then theirs to make it\nconsistent and easier to read.\n\nSo how about doing it like this, instead?  I am not proud of the\nuse of an environment variable to pass this control around, but\nthe idea should be obvious.\n\nNote that some tests are written to expect the current hunk\norder and will start failing, so if we were to go this route, we\nwould need to adjust them as well.\n\n--\n\n git-rebase.sh |    3 +++\n ll-merge.c    |    6 ++++++\n 2 files changed, 9 insertions(+), 0 deletions(-)\n\ndiff --git a/git-rebase.sh b/git-rebase.sh\nindex bdcea0e..422879f 100755\n--- a/git-rebase.sh\n+++ b/git-rebase.sh\n@@ -48,6 +48,9 @@ prec=4\n verbose=\n git_am_opt=\n \n+GITHEAD_SWAP_CONFLICT=in-rebase\n+export GITHEAD_SWAP_CONFLICT\n+\n continue_merge () {\n \ttest -n \"$prev_head\" || die \"prev_head must be defined\"\n \ttest -d \"$dotest\" || die \"$dotest directory does not exist\"\ndiff --git a/ll-merge.c b/ll-merge.c\nindex 5ae7433..1d0040f 100644\n--- a/ll-merge.c\n+++ b/ll-merge.c\n@@ -76,6 +76,12 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,\n \t\t\t\t       virtual_ancestor);\n \t}\n \n+\tif (getenv(\"GITHEAD_SWAP_CONFLICT\")) {\n+\t\tmmfile_t *s;\n+\t\tconst char *n;\n+\t\ts = src1; src1 = src2; src2 = s;\n+\t\tn = name1; name1 = name2; name2 = n;\n+\t}\n \tmemset(&xpp, 0, sizeof(xpp));\n \treturn xdl_merge(orig,\n \t\t\t src1, name1,\n\n"},{"id":"70465","messageId":"20080301044155.GA9010@coredump.intra.peff.net","threadId":"12233","inReplyTo":"7v3arcfh54.fsf@gitster.siamese.dyndns.org","subject":"Re: [RFC/PATCH] mergetool: clarify local/remote terminology","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-03-01T04:41:55Z","receivedAt":"2008-03-01T04:41:55Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Feb 28, 2008 at 09:47:35PM -0800, Junio C Hamano wrote:\n\n> While I like the fact that somebody is trying to tackle the\n> consistency issue, I do not like the approach itself.  Fudging\n> the issue at the merge-tool UI level may make things appear more\n> consistent when viewing the merge from within merge-tool, but it\n> makes the views merge-tool gives and vi/less gives inconsistent.\n> \n> It would be a lot more sensible to make sure that we always show\n> the side that the end-user modified first and then the side the\n> other party changed.\n\nI hadn't considered that, because I never pay attention to the order of\nchanges between the conflict markers; I look at the nice \"HEAD\" and\n\"abcdef... commit subject\" messages.\n\nBut then I don't do a lot of conflict resolution. Usually I either work\nwith tiny teams on a central-ish repository, or work on projects where I\nam just a contributor.\n\nSo I agree that a consistent view makes sense, and I can see that\nordering of hunks is a sensible context clue. However, should this not\nextend further, to the index numbering? Or do we not care, because\nmortals rarely touch the index? What about \"git-rebase --strategy=ours\",\nwhich really means \"theirs\"?\n\nUnfortunately just swapping the arguments to git-merge-* in\ngit-rebase.sh doesn't quite work (\"merge-ours\" doesn't actually load the\nindex and say \"pick the 'ours' stage\"; it just says \"whatever is in the\nworking tree is fine.\").\n\n-Peff\n"}]}