git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Enable auto-merge for meld to follow the vim-diff beharior
@ 2020-05-08  1:25 sunlin via GitGitGadget
  2020-06-08  9:49 ` Pratyush Yadav
  2020-06-09  3:19 ` [PATCH v2] " sunlin via GitGitGadget
  0 siblings, 2 replies; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-05-08  1:25 UTC (permalink / raw)
  To: git; +Cc: sunlin, lin.sun

From: "lin.sun" <lin.sun@zoom.us>

The mergetool "meld" does NOT merge the no-conflict changes, while the
mergetool "vimdiff" will merge the no-conflict parts and highlight the
conflict parts.
This patch will make the mergetool "meld" similar to "vimdiff",
auto-merge the no-conflict parts, highlight conflict parts.

Signed-off-by: Lin Sun <sunlin7@yahoo.com>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v1
Pull-Request: https://github.com/git/git/pull/781

 mergetools/meld | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f883..318653cc9f7 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -10,10 +10,10 @@ merge_cmd () {
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" --auto-merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" --auto-merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* Re: [PATCH] Enable auto-merge for meld to follow the vim-diff beharior
  2020-05-08  1:25 [PATCH] Enable auto-merge for meld to follow the vim-diff beharior sunlin via GitGitGadget
@ 2020-06-08  9:49 ` Pratyush Yadav
  2020-06-09  3:19 ` [PATCH v2] " sunlin via GitGitGadget
  1 sibling, 0 replies; 74+ messages in thread
From: Pratyush Yadav @ 2020-06-08  9:49 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, lin.sun

Hi Lin,

I'm not familiar with the code so I'll let someone else comment on that. 
But...

On 08/05/20 01:25AM, sunlin via GitGitGadget wrote:
> From: "lin.sun" <lin.sun@zoom.us>
> 
> The mergetool "meld" does NOT merge the no-conflict changes, while the
> mergetool "vimdiff" will merge the no-conflict parts and highlight the
> conflict parts.
> This patch will make the mergetool "meld" similar to "vimdiff",
> auto-merge the no-conflict parts, highlight conflict parts.
> 
> Signed-off-by: Lin Sun <sunlin7@yahoo.com>

... your name and email in "From:" and "Signed-off-by:" should be the 
same. So either use "lin.sun" <lin.sun@zoom.us> in both places or use 
Lin Sun <sunlin7@yahoo.com> in both.

-- 
Regards,
Pratyush Yadav

^ permalink raw reply	[flat|nested] 74+ messages in thread

* [PATCH v2] Enable auto-merge for meld to follow the vim-diff beharior
  2020-05-08  1:25 [PATCH] Enable auto-merge for meld to follow the vim-diff beharior sunlin via GitGitGadget
  2020-06-08  9:49 ` Pratyush Yadav
@ 2020-06-09  3:19 ` sunlin via GitGitGadget
  2020-06-29  7:07   ` [PATCH v3] " sunlin via GitGitGadget
  1 sibling, 1 reply; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-06-09  3:19 UTC (permalink / raw)
  To: git; +Cc: sunlin, lin.sun

From: "lin.sun" <lin.sun@zoom.us>

The mergetool "meld" does NOT merge the no-conflict changes, while the
mergetool "vimdiff" will merge the no-conflict parts and highlight the
conflict parts.
This patch will make the mergetool "meld" similar to "vimdiff",
auto-merge the no-conflict parts, highlight conflict parts.

Signed-off-by: Lin Sun <lin.sun@zoom.us>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v2
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v1:

 1:  739e69e6631 ! 1:  6e98a10bfa9 Enable auto-merge for meld to follow the vim-diff beharior
     @@ Commit message
          This patch will make the mergetool "meld" similar to "vimdiff",
          auto-merge the no-conflict parts, highlight conflict parts.
      
     -    Signed-off-by: Lin Sun <sunlin7@yahoo.com>
     +    Signed-off-by: Lin Sun <lin.sun@zoom.us>
      
       ## mergetools/meld ##
      @@ mergetools/meld: merge_cmd () {


 mergetools/meld | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f883..318653cc9f7 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -10,10 +10,10 @@ merge_cmd () {
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" --auto-merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" --auto-merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* [PATCH v3] Enable auto-merge for meld to follow the vim-diff beharior
  2020-06-09  3:19 ` [PATCH v2] " sunlin via GitGitGadget
@ 2020-06-29  7:07   ` sunlin via GitGitGadget
  2020-06-29 12:32     ` Fwd: " Git Gadget
                       ` (2 more replies)
  0 siblings, 3 replies; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-06-29  7:07 UTC (permalink / raw)
  To: git; +Cc: sunlin, lin.sun

From: "lin.sun" <lin.sun@zoom.us>

The mergetool "meld" does NOT merge the no-conflict changes, while the
mergetool "vimdiff" will merge the no-conflict parts and highlight the
conflict parts.
This patch will make the mergetool "meld" similar to "vimdiff",
auto-merge the no-conflict parts, highlight conflict parts.

Signed-off-by: Lin Sun <lin.sun@zoom.us>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v3
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v2:

 1:  6e98a10bfa ! 1:  3b70fd0bfc Enable auto-merge for meld to follow the vim-diff beharior
     @@ Commit message
      
       ## mergetools/meld ##
      @@ mergetools/meld: merge_cmd () {
     + 	then
     + 		check_meld_for_output_version
     + 	fi
     ++	if test -z "${meld_has_auto_merge_option:+set}"
     ++	then
     ++		check_meld_for_auto_merge_version
     ++	fi
     ++
     ++	option_auto_merge=
     ++	if test "$meld_has_auto_merge_option" = true
     ++	then
     ++		option_auto_merge="--auto-merge"
     ++	fi
       
       	if test "$meld_has_output_option" = true
       	then
      -		"$merge_tool_path" --output="$MERGED" \
     -+		"$merge_tool_path" --auto-merge --output="$MERGED" \
     ++		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
       			"$LOCAL" "$BASE" "$REMOTE"
       	else
      -		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
     -+		"$merge_tool_path" --auto-merge "$LOCAL" "$MERGED" "$REMOTE"
     ++		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
       	fi
       }
       
     +@@ mergetools/meld: check_meld_for_output_version () {
     + 		meld_has_output_option=false
     + 	fi
     + }
     ++
     ++# Check whether we should use 'meld --auto-merge ...'
     ++check_meld_for_auto_merge_version () {
     ++	meld_path="$(git config mergetool.meld.path)"
     ++	meld_path="${meld_path:-meld}"
     ++
     ++	if meld_has_auto_merge_option=$(git config --bool mergetool.meld.hasAutoMerge)
     ++	then
     ++		: use configured value
     ++	elif "$meld_path" --help 2>&1 |
     ++		grep -e '--auto-merge' -e '\[OPTION\.\.\.\]' >/dev/null
     ++	then
     ++		: old ones mention --auto-merge and new ones just say OPTION...
     ++		meld_has_auto_merge_option=true
     ++	else
     ++		meld_has_auto_merge_option=false
     ++	fi
     ++}


 mergetools/meld | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..91b65ff22c 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -7,13 +7,23 @@ merge_cmd () {
 	then
 		check_meld_for_output_version
 	fi
+	if test -z "${meld_has_auto_merge_option:+set}"
+	then
+		check_meld_for_auto_merge_version
+	fi
+
+	option_auto_merge=
+	if test "$meld_has_auto_merge_option" = true
+	then
+		option_auto_merge="--auto-merge"
+	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
@@ -34,3 +44,21 @@ check_meld_for_output_version () {
 		meld_has_output_option=false
 	fi
 }
+
+# Check whether we should use 'meld --auto-merge ...'
+check_meld_for_auto_merge_version () {
+	meld_path="$(git config mergetool.meld.path)"
+	meld_path="${meld_path:-meld}"
+
+	if meld_has_auto_merge_option=$(git config --bool mergetool.meld.hasAutoMerge)
+	then
+		: use configured value
+	elif "$meld_path" --help 2>&1 |
+		grep -e '--auto-merge' -e '\[OPTION\.\.\.\]' >/dev/null
+	then
+		: old ones mention --auto-merge and new ones just say OPTION...
+		meld_has_auto_merge_option=true
+	else
+		meld_has_auto_merge_option=false
+	fi
+}

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* Fwd: [PATCH v3] Enable auto-merge for meld to follow the vim-diff beharior
  2020-06-29  7:07   ` [PATCH v3] " sunlin via GitGitGadget
@ 2020-06-29 12:32     ` Git Gadget
  2020-06-30  0:06     ` Junio C Hamano
  2020-06-30 11:26     ` [PATCH v4] " sunlin via GitGitGadget
  2 siblings, 0 replies; 74+ messages in thread
From: Git Gadget @ 2020-06-29 12:32 UTC (permalink / raw)
  To: git, lin.sun, sunlin

Re-sending, as this mail seems to have been dropped by vger.

---------- Forwarded message ---------
From: sunlin via GitGitGadget <gitgitgadget@gmail.com>
Date: Mon, Jun 29, 2020 at 9:07 AM
Subject: [PATCH v3] Enable auto-merge for meld to follow the vim-diff beharior
To: <git@vger.kernel.org>
Cc: sunlin <sunlin7@yahoo.com>, lin.sun <lin.sun@zoom.us>


From: "lin.sun" <lin.sun@zoom.us>

The mergetool "meld" does NOT merge the no-conflict changes, while the
mergetool "vimdiff" will merge the no-conflict parts and highlight the
conflict parts.
This patch will make the mergetool "meld" similar to "vimdiff",
auto-merge the no-conflict parts, highlight conflict parts.

Signed-off-by: Lin Sun <lin.sun@zoom.us>
---
    Enable auto-merge for meld to follow the vimdiff beharior

    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git
pr-git-781/sunlin7/master-v3
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v2:

 1:  6e98a10bfa ! 1:  3b70fd0bfc Enable auto-merge for meld to follow
the vim-diff beharior
     @@ Commit message

       ## mergetools/meld ##
      @@ mergetools/meld: merge_cmd () {
     +  then
     +          check_meld_for_output_version
     +  fi
     ++ if test -z "${meld_has_auto_merge_option:+set}"
     ++ then
     ++         check_meld_for_auto_merge_version
     ++ fi
     ++
     ++ option_auto_merge=
     ++ if test "$meld_has_auto_merge_option" = true
     ++ then
     ++         option_auto_merge="--auto-merge"
     ++ fi

        if test "$meld_has_output_option" = true
        then
      -         "$merge_tool_path" --output="$MERGED" \
     -+         "$merge_tool_path" --auto-merge --output="$MERGED" \
     ++         "$merge_tool_path" $option_auto_merge --output="$MERGED" \
                        "$LOCAL" "$BASE" "$REMOTE"
        else
      -         "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
     -+         "$merge_tool_path" --auto-merge "$LOCAL" "$MERGED" "$REMOTE"
     ++         "$merge_tool_path" $option_auto_merge "$LOCAL"
"$MERGED" "$REMOTE"
        fi
       }

     +@@ mergetools/meld: check_meld_for_output_version () {
     +          meld_has_output_option=false
     +  fi
     + }
     ++
     ++# Check whether we should use 'meld --auto-merge ...'
     ++check_meld_for_auto_merge_version () {
     ++ meld_path="$(git config mergetool.meld.path)"
     ++ meld_path="${meld_path:-meld}"
     ++
     ++ if meld_has_auto_merge_option=$(git config --bool
mergetool.meld.hasAutoMerge)
     ++ then
     ++         : use configured value
     ++ elif "$meld_path" --help 2>&1 |
     ++         grep -e '--auto-merge' -e '\[OPTION\.\.\.\]' >/dev/null
     ++ then
     ++         : old ones mention --auto-merge and new ones just say OPTION...
     ++         meld_has_auto_merge_option=true
     ++ else
     ++         meld_has_auto_merge_option=false
     ++ fi
     ++}


 mergetools/meld | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..91b65ff22c 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -7,13 +7,23 @@ merge_cmd () {
        then
                check_meld_for_output_version
        fi
+       if test -z "${meld_has_auto_merge_option:+set}"
+       then
+               check_meld_for_auto_merge_version
+       fi
+
+       option_auto_merge=
+       if test "$meld_has_auto_merge_option" = true
+       then
+               option_auto_merge="--auto-merge"
+       fi

        if test "$meld_has_output_option" = true
        then
-               "$merge_tool_path" --output="$MERGED" \
+               "$merge_tool_path" $option_auto_merge --output="$MERGED" \
                        "$LOCAL" "$BASE" "$REMOTE"
        else
-               "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+               "$merge_tool_path" $option_auto_merge "$LOCAL"
"$MERGED" "$REMOTE"
        fi
 }

@@ -34,3 +44,21 @@ check_meld_for_output_version () {
                meld_has_output_option=false
        fi
 }
+
+# Check whether we should use 'meld --auto-merge ...'
+check_meld_for_auto_merge_version () {
+       meld_path="$(git config mergetool.meld.path)"
+       meld_path="${meld_path:-meld}"
+
+       if meld_has_auto_merge_option=$(git config --bool
mergetool.meld.hasAutoMerge)
+       then
+               : use configured value
+       elif "$meld_path" --help 2>&1 |
+               grep -e '--auto-merge' -e '\[OPTION\.\.\.\]' >/dev/null
+       then
+               : old ones mention --auto-merge and new ones just say OPTION...
+               meld_has_auto_merge_option=true
+       else
+               meld_has_auto_merge_option=false
+       fi
+}

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
--
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* Re: [PATCH v3] Enable auto-merge for meld to follow the vim-diff beharior
  2020-06-29  7:07   ` [PATCH v3] " sunlin via GitGitGadget
  2020-06-29 12:32     ` Fwd: " Git Gadget
@ 2020-06-30  0:06     ` Junio C Hamano
  2020-06-30  7:42       ` David Aguilar
  2020-06-30 11:26     ` [PATCH v4] " sunlin via GitGitGadget
  2 siblings, 1 reply; 74+ messages in thread
From: Junio C Hamano @ 2020-06-30  0:06 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, lin.sun

"sunlin via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: "lin.sun" <lin.sun@zoom.us>

The way this "name <addr>" is spelled must match the name used on
the Signed-off-by: line below.

> The mergetool "meld" does NOT merge the no-conflict changes, while the
> mergetool "vimdiff" will merge the no-conflict parts and highlight the
> conflict parts.

OK.

Have a blank line between paragraphs here.

> This patch will make the mergetool "meld" similar to "vimdiff",
> auto-merge the no-conflict parts, highlight conflict parts.

Give an order to the codebase to be like so, e.g.:

    Make the mergetool used with "meld" backend behave similarly to
    how "vimdiff" beheaves by telling it to auto-merge parts without
    conflicts and highlight the parts with conflicts.

or somethin glike that.

> Signed-off-by: Lin Sun <lin.sun@zoom.us>
> ---
>     Enable auto-merge for meld to follow the vimdiff beharior
>     
>     Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
>     the mergetool "vimdiff" will merge the no-conflict changes and highlight
>     the conflict parts. This patch will make the mergetool "meld" similar to
>     "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

That repeats the log message and does not add much useful info.

>  mergetools/meld | 32 ++++++++++++++++++++++++++++++--
>  1 file changed, 30 insertions(+), 2 deletions(-)
>
> diff --git a/mergetools/meld b/mergetools/meld
> index 7a08470f88..91b65ff22c 100644
> --- a/mergetools/meld
> +++ b/mergetools/meld
> @@ -7,13 +7,23 @@ merge_cmd () {
>  	then
>  		check_meld_for_output_version
>  	fi
> +	if test -z "${meld_has_auto_merge_option:+set}"
> +	then
> +		check_meld_for_auto_merge_version
> +	fi

The detection part looks clumsy and inefficient.  More about it later.

> +	option_auto_merge=
> +	if test "$meld_has_auto_merge_option" = true
> +	then
> +		option_auto_merge="--auto-merge"
> +	fi
>  
>  	if test "$meld_has_output_option" = true
>  	then
> -		"$merge_tool_path" --output="$MERGED" \
> +		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
>  			"$LOCAL" "$BASE" "$REMOTE"
>  	else
> -		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
> +		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
>  	fi
>  }

The part that chooses whether to pass --auto-merge or not and
adjusts the command line options does look sensible.

I wonder if the same "hasAutoMerge" option can be used by those who
do *not* want the new --auto-merge behaviour to opt out of this
change.  Is there a reason why "meld" offers the --auto-merge as an
optional behaviour (which tells, at least to me, that the default
behaviour is not to auto-merge and makes me assume that the default
must be chosen by some sound reasoning, hence some users would prefer
not to use this new behaviour with good reasons)?

I guess what I am trying to get at is, if --auto-merge is an optional
and non-default behaviour for "meld" users, perhaps it is not a good
idea to change the behaviour on them only because the version of meld
they run happens to support the --auto-merge as an optional behaviour.

IOW, wouldn't it make more sense, and certainly make it safer
without surprises to existing users, if we made the logic to

    * If mergetool.meld.useAutoMerge is not set, do not pass
      --auto-merge whether "meld" supports the option or not.

    * If mergetool.meld.useAutoMerge is 'true', always pass it
      without checking.

    * If mergetool.meld.useAutoMerge is 'when-able' (or come up with
      a better name if you want, perhaps 'auto'), check if "meld"
      accepts "--auto-merge" and decide whether to pass it or not.

perhaps?

> +# Check whether we should use 'meld --auto-merge ...'
> +check_meld_for_auto_merge_version () {
> +	meld_path="$(git config mergetool.meld.path)"
> +	meld_path="${meld_path:-meld}"
> +
> +	if meld_has_auto_merge_option=$(git config --bool mergetool.meld.hasAutoMerge)
> +	then
> +		: use configured value
> +	elif "$meld_path" --help 2>&1 |
> +		grep -e '--auto-merge' -e '\[OPTION\.\.\.\]' >/dev/null
> +	then
> +		: old ones mention --auto-merge and new ones just say OPTION...
> +		meld_has_auto_merge_option=true
> +	else
> +		meld_has_auto_merge_option=false
> +	fi
> +}

When not configured, we end up running "meld --help" twice for two
options, which is not great, don't you think?  I actually think the
part that runs "meld --help" and parses its output should be split
out of the helper function "check_meld_for_output_version" and
called "check_meld_supported_options" or something, so that the
logic to see if the --output and --auto-merge options should be
passed can be made with at most one invocation of "meld --help".
Which may involve *NOT* having two separate helper functions
check_meld_for_*_version for the tested features.

Oh, also, check_meld_for_*_version is nonsensical as a name for
these helper functions (it is not the fault of this patch---it is
mimicking the existing practice, but that does not make the function
name not nonsensical).  The helpers do not actually want to check a
"version", they only want to see if a feature is supported.  So
having "feature" in the name would be good, but "version" is not.




^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v3] Enable auto-merge for meld to follow the vim-diff beharior
  2020-06-30  0:06     ` Junio C Hamano
@ 2020-06-30  7:42       ` David Aguilar
  2020-06-30 11:25         ` lin.sun
                           ` (2 more replies)
  0 siblings, 3 replies; 74+ messages in thread
From: David Aguilar @ 2020-06-30  7:42 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: sunlin via GitGitGadget, git, sunlin, lin.sun

On Mon, Jun 29, 2020 at 05:06:13PM -0700, Junio C Hamano wrote:
> "sunlin via GitGitGadget" <gitgitgadget@gmail.com> writes:
> >  mergetools/meld | 32 ++++++++++++++++++++++++++++++--
> >  1 file changed, 30 insertions(+), 2 deletions(-)
> >
> > diff --git a/mergetools/meld b/mergetools/meld
> > index 7a08470f88..91b65ff22c 100644
> > --- a/mergetools/meld
> > +++ b/mergetools/meld
> > @@ -7,13 +7,23 @@ merge_cmd () {
> >  	then
> >  		check_meld_for_output_version
> >  	fi
> > +	if test -z "${meld_has_auto_merge_option:+set}"
> > +	then
> > +		check_meld_for_auto_merge_version
> > +	fi
> 
> The detection part looks clumsy and inefficient.  More about it later.


Sorry for not noticing your reply here earlier.  I agree with everything
you wrote here, and rescind my earlier sign-off.  Combining as you
suggested below is best IMO as well.

> 
> > +	option_auto_merge=
> > +	if test "$meld_has_auto_merge_option" = true
> > +	then
> > +		option_auto_merge="--auto-merge"
> > +	fi
> >  
> >  	if test "$meld_has_output_option" = true
> >  	then
> > -		"$merge_tool_path" --output="$MERGED" \
> > +		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
> >  			"$LOCAL" "$BASE" "$REMOTE"
> >  	else
> > -		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
> > +		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
> >  	fi
> >  }
> 
> The part that chooses whether to pass --auto-merge or not and
> adjusts the command line options does look sensible.
> 
> I wonder if the same "hasAutoMerge" option can be used by those who
> do *not* want the new --auto-merge behaviour to opt out of this
> change.  Is there a reason why "meld" offers the --auto-merge as an
> optional behaviour (which tells, at least to me, that the default
> behaviour is not to auto-merge and makes me assume that the default
> must be chosen by some sound reasoning, hence some users would prefer
> not to use this new behaviour with good reasons)?
> 
> I guess what I am trying to get at is, if --auto-merge is an optional
> and non-default behaviour for "meld" users, perhaps it is not a good
> idea to change the behaviour on them only because the version of meld
> they run happens to support the --auto-merge as an optional behaviour.
> 
> IOW, wouldn't it make more sense, and certainly make it safer
> without surprises to existing users, if we made the logic to
> 
>     * If mergetool.meld.useAutoMerge is not set, do not pass
>       --auto-merge whether "meld" supports the option or not.
> 
>     * If mergetool.meld.useAutoMerge is 'true', always pass it
>       without checking.
> 
>     * If mergetool.meld.useAutoMerge is 'when-able' (or come up with
>       a better name if you want, perhaps 'auto'), check if "meld"
>       accepts "--auto-merge" and decide whether to pass it or not.
> 
> perhaps?


I like the idea of having it be auto/true/false, and perhaps "auto"
would be a sensible default if more users benefit from it than not.

Sunlin, do you have an opinion on what the default should be?



> > +# Check whether we should use 'meld --auto-merge ...'
> > +check_meld_for_auto_merge_version () {
> > +	meld_path="$(git config mergetool.meld.path)"

Small sug -- this command substitution doesn't need the enclosing
quotes.

	meld_path=$(git config mergetool.meld.path || echo meld)

should be sufficient.  Are we okay with `|| echo meld`?
If so, it would let us drop this line below.

> > +	meld_path="${meld_path:-meld}"


> > +
> > +	if meld_has_auto_merge_option=$(git config --bool mergetool.meld.hasAutoMerge)
> > +	then
> > +		: use configured value
> > +	elif "$meld_path" --help 2>&1 |
> > +		grep -e '--auto-merge' -e '\[OPTION\.\.\.\]' >/dev/null
> > +	then
> > +		: old ones mention --auto-merge and new ones just say OPTION...
> > +		meld_has_auto_merge_option=true
> > +	else
> > +		meld_has_auto_merge_option=false
> > +	fi
> > +}
> 
> When not configured, we end up running "meld --help" twice for two
> options, which is not great, don't you think?  I actually think the
> part that runs "meld --help" and parses its output should be split
> out of the helper function "check_meld_for_output_version" and
> called "check_meld_supported_options" or something, so that the
> logic to see if the --output and --auto-merge options should be
> passed can be made with at most one invocation of "meld --help".
> Which may involve *NOT* having two separate helper functions
> check_meld_for_*_version for the tested features.


I'm 100% on board with this suggestion.

> 
> Oh, also, check_meld_for_*_version is nonsensical as a name for
> these helper functions (it is not the fault of this patch---it is
> mimicking the existing practice, but that does not make the function
> name not nonsensical).  The helpers do not actually want to check a
> "version", they only want to see if a feature is supported.  So
> having "feature" in the name would be good, but "version" is not.


Ditto.
-- 
David

^ permalink raw reply	[flat|nested] 74+ messages in thread

* RE: [PATCH v3] Enable auto-merge for meld to follow the vim-diff beharior
  2020-06-30  7:42       ` David Aguilar
@ 2020-06-30 11:25         ` lin.sun
  2020-06-30 11:37         ` lin.sun
  2020-06-30 15:51         ` Junio C Hamano
  2 siblings, 0 replies; 74+ messages in thread
From: lin.sun @ 2020-06-30 11:25 UTC (permalink / raw)
  To: 'David Aguilar', 'Junio C Hamano'
  Cc: 'sunlin via GitGitGadget', git, 'sunlin'

[-- Attachment #1: Type: text/plain, Size: 358 bytes --]

Hi David, Junio,

Appreciate for your comments, I rewrite the "mergetool/meld" to follow your comments and suggestions.
It will respect the git config first, then detect the options if no configuration for them, and also reduce the subprocess calling.
Both the modified-file and patch-file are appended.
Please review again. Thanks

Regards
Lin Sun

[-- Attachment #2: 0001-Enable-auto-merge-for-meld-to-follow-the-vim-diff-be.patch --]
[-- Type: application/octet-stream, Size: 3503 bytes --]

From 93ae3ec011e7b55cc9971f91345cb4aab5189cb4 Mon Sep 17 00:00:00 2001
From: "lin.sun" <lin.sun@zoom.us>
Date: Thu, 7 May 2020 07:31:14 +0800
Subject: [PATCH] Enable auto-merge for meld to follow the vim-diff beharior

Make the mergetool used with "meld" backend behave similarly to
how "vimdiff" beheaves by telling it to auto-merge parts without
conflicts and highlight the parts with conflicts.

Signed-off-by: lin.sun <lin.sun@zoom.us>
---
 mergetools/meld | 73 ++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 57 insertions(+), 16 deletions(-)

diff --git a/mergetools/meld b/mergetools/meld
index 7a08470..1b92771 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,75 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_has_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+get_meld_help_msg () {
+	meld_path="$(git config mergetool.meld.path || echo meld)"
+  $meld_path --help 2>&1
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "${meld_has_output_option:+set}"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		if test "$meld_has_output_option" = true -o \
+						"$meld_has_output_option" = false
+		then
+			: use configured value
+		else												# treat meld_has_output_option as "auto"
+			if test -z "$meld_help_msg"
+			then
+				meld_help_msg="$(get_meld_help_msg)"
+			fi
+
+			if echo "$meld_help_msg" |
+							grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+			then
+				: old ones mention --output and new ones just say OPTION...
+				meld_has_output_option=true
+			else
+				meld_has_output_option=false
+			fi
+		fi
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "${meld_has_auto_merge_option:+set}"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_has_auto_merge_option=$(git config --bool mergetool.meld.hasAutoMerge)
+		if test "$meld_has_auto_merge_option" = true -o \
+						"$meld_has_auto_merge_option" = false
+		then
+			: use configured value
+		else												# treat meld_has_auto_merge_option as "auto"
+			if test -z "$meld_help_msg"
+			then
+					meld_help_msg="$(get_meld_help_msg)"
+			fi
+
+			if echo "$meld_help_msg" | grep -e '--auto-merge' >/dev/null
+			then
+					meld_has_auto_merge_option=true
+			else
+				meld_has_auto_merge_option=false
+			fi
+		fi
 	fi
 }
-- 
2.2.0


[-- Attachment #3: meld --]
[-- Type: application/octet-stream, Size: 2038 bytes --]

diff_cmd () {
	"$merge_tool_path" "$LOCAL" "$REMOTE"
}

merge_cmd () {
	check_meld_for_features

	option_auto_merge=
	if test "$meld_has_auto_merge_option" = true
	then
		option_auto_merge="--auto-merge"
	fi

	if test "$meld_has_output_option" = true
	then
		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
			"$LOCAL" "$BASE" "$REMOTE"
	else
		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
	fi
}

# Get meld help message
get_meld_help_msg () {
	meld_path="$(git config mergetool.meld.path || echo meld)"
  $meld_path --help 2>&1
}

# Check the features and set flags
check_meld_for_features () {
	# Check whether we should use 'meld --output <file>'
	if test -z "${meld_has_output_option:+set}"
	then
		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
		if test "$meld_has_output_option" = true -o \
						"$meld_has_output_option" = false
		then
			: use configured value
		else												# treat meld_has_output_option as "auto"
			if test -z "$meld_help_msg"
			then
				meld_help_msg="$(get_meld_help_msg)"
			fi

			if echo "$meld_help_msg" |
							grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
			then
				: old ones mention --output and new ones just say OPTION...
				meld_has_output_option=true
			else
				meld_has_output_option=false
			fi
		fi
	fi
	# Check whether we should use 'meld --auto-merge ...'
	if test -z "${meld_has_auto_merge_option:+set}"
	then
		meld_has_auto_merge_option=$(git config --bool mergetool.meld.hasAutoMerge)
		if test "$meld_has_auto_merge_option" = true -o \
						"$meld_has_auto_merge_option" = false
		then
			: use configured value
		else												# treat meld_has_auto_merge_option as "auto"
			if test -z "$meld_help_msg"
			then
					meld_help_msg="$(get_meld_help_msg)"
			fi

			if echo "$meld_help_msg" | grep -e '--auto-merge' >/dev/null
			then
					meld_has_auto_merge_option=true
			else
				meld_has_auto_merge_option=false
			fi
		fi
	fi
}

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* [PATCH v4] Enable auto-merge for meld to follow the vim-diff beharior
  2020-06-29  7:07   ` [PATCH v3] " sunlin via GitGitGadget
  2020-06-29 12:32     ` Fwd: " Git Gadget
  2020-06-30  0:06     ` Junio C Hamano
@ 2020-06-30 11:26     ` sunlin via GitGitGadget
  2020-06-30 16:23       ` Đoàn Trần Công Danh
  2020-07-01  7:06       ` [PATCH v5] " sunlin via GitGitGadget
  2 siblings, 2 replies; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-06-30 11:26 UTC (permalink / raw)
  To: git; +Cc: sunlin, lin.sun

From: "lin.sun" <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to
how "vimdiff" beheaves by telling it to auto-merge parts without
conflicts and highlight the parts with conflicts.

Signed-off-by: lin.sun <lin.sun@zoom.us>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v4
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v3:

 1:  3b70fd0bfc ! 1:  93ae3ec011 Enable auto-merge for meld to follow the vim-diff beharior
     @@ Metadata
       ## Commit message ##
          Enable auto-merge for meld to follow the vim-diff beharior
      
     -    The mergetool "meld" does NOT merge the no-conflict changes, while the
     -    mergetool "vimdiff" will merge the no-conflict parts and highlight the
     -    conflict parts.
     -    This patch will make the mergetool "meld" similar to "vimdiff",
     -    auto-merge the no-conflict parts, highlight conflict parts.
     +    Make the mergetool used with "meld" backend behave similarly to
     +    how "vimdiff" beheaves by telling it to auto-merge parts without
     +    conflicts and highlight the parts with conflicts.
      
     -    Signed-off-by: Lin Sun <lin.sun@zoom.us>
     +    Signed-off-by: lin.sun <lin.sun@zoom.us>
      
       ## mergetools/meld ##
     -@@ mergetools/meld: merge_cmd () {
     - 	then
     - 		check_meld_for_output_version
     - 	fi
     -+	if test -z "${meld_has_auto_merge_option:+set}"
     -+	then
     -+		check_meld_for_auto_merge_version
     -+	fi
     +@@ mergetools/meld: diff_cmd () {
     + }
     + 
     + merge_cmd () {
     +-	if test -z "${meld_has_output_option:+set}"
     ++	check_meld_for_features
      +
      +	option_auto_merge=
      +	if test "$meld_has_auto_merge_option" = true
     -+	then
     + 	then
     +-		check_meld_for_output_version
      +		option_auto_merge="--auto-merge"
     -+	fi
     + 	fi
       
       	if test "$meld_has_output_option" = true
       	then
     @@ mergetools/meld: merge_cmd () {
       	fi
       }
       
     -@@ mergetools/meld: check_meld_for_output_version () {
     - 		meld_has_output_option=false
     - 	fi
     - }
     -+
     -+# Check whether we should use 'meld --auto-merge ...'
     -+check_meld_for_auto_merge_version () {
     -+	meld_path="$(git config mergetool.meld.path)"
     -+	meld_path="${meld_path:-meld}"
     +-# Check whether we should use 'meld --output <file>'
     +-check_meld_for_output_version () {
     +-	meld_path="$(git config mergetool.meld.path)"
     +-	meld_path="${meld_path:-meld}"
     ++# Get meld help message
     ++get_meld_help_msg () {
     ++	meld_path="$(git config mergetool.meld.path || echo meld)"
     ++  $meld_path --help 2>&1
     ++}
     + 
     +-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
     ++# Check the features and set flags
     ++check_meld_for_features () {
     ++	# Check whether we should use 'meld --output <file>'
     ++	if test -z "${meld_has_output_option:+set}"
     + 	then
     +-		: use configured value
     +-	elif "$meld_path" --help 2>&1 |
     +-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
     ++		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
     ++		if test "$meld_has_output_option" = true -o \
     ++						"$meld_has_output_option" = false
     ++		then
     ++			: use configured value
     ++		else												# treat meld_has_output_option as "auto"
     ++			if test -z "$meld_help_msg"
     ++			then
     ++				meld_help_msg="$(get_meld_help_msg)"
     ++			fi
      +
     -+	if meld_has_auto_merge_option=$(git config --bool mergetool.meld.hasAutoMerge)
     -+	then
     -+		: use configured value
     -+	elif "$meld_path" --help 2>&1 |
     -+		grep -e '--auto-merge' -e '\[OPTION\.\.\.\]' >/dev/null
     -+	then
     -+		: old ones mention --auto-merge and new ones just say OPTION...
     -+		meld_has_auto_merge_option=true
     -+	else
     -+		meld_has_auto_merge_option=false
     ++			if echo "$meld_help_msg" |
     ++							grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
     ++			then
     ++				: old ones mention --output and new ones just say OPTION...
     ++				meld_has_output_option=true
     ++			else
     ++				meld_has_output_option=false
     ++			fi
     ++		fi
      +	fi
     -+}
     ++	# Check whether we should use 'meld --auto-merge ...'
     ++	if test -z "${meld_has_auto_merge_option:+set}"
     + 	then
     +-		: old ones mention --output and new ones just say OPTION...
     +-		meld_has_output_option=true
     +-	else
     +-		meld_has_output_option=false
     ++		meld_has_auto_merge_option=$(git config --bool mergetool.meld.hasAutoMerge)
     ++		if test "$meld_has_auto_merge_option" = true -o \
     ++						"$meld_has_auto_merge_option" = false
     ++		then
     ++			: use configured value
     ++		else												# treat meld_has_auto_merge_option as "auto"
     ++			if test -z "$meld_help_msg"
     ++			then
     ++					meld_help_msg="$(get_meld_help_msg)"
     ++			fi
     ++
     ++			if echo "$meld_help_msg" | grep -e '--auto-merge' >/dev/null
     ++			then
     ++					meld_has_auto_merge_option=true
     ++			else
     ++				meld_has_auto_merge_option=false
     ++			fi
     ++		fi
     + 	fi
     + }


 mergetools/meld | 73 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 57 insertions(+), 16 deletions(-)

diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..1b92771228 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,75 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_has_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+get_meld_help_msg () {
+	meld_path="$(git config mergetool.meld.path || echo meld)"
+  $meld_path --help 2>&1
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "${meld_has_output_option:+set}"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		if test "$meld_has_output_option" = true -o \
+						"$meld_has_output_option" = false
+		then
+			: use configured value
+		else												# treat meld_has_output_option as "auto"
+			if test -z "$meld_help_msg"
+			then
+				meld_help_msg="$(get_meld_help_msg)"
+			fi
+
+			if echo "$meld_help_msg" |
+							grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+			then
+				: old ones mention --output and new ones just say OPTION...
+				meld_has_output_option=true
+			else
+				meld_has_output_option=false
+			fi
+		fi
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "${meld_has_auto_merge_option:+set}"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_has_auto_merge_option=$(git config --bool mergetool.meld.hasAutoMerge)
+		if test "$meld_has_auto_merge_option" = true -o \
+						"$meld_has_auto_merge_option" = false
+		then
+			: use configured value
+		else												# treat meld_has_auto_merge_option as "auto"
+			if test -z "$meld_help_msg"
+			then
+					meld_help_msg="$(get_meld_help_msg)"
+			fi
+
+			if echo "$meld_help_msg" | grep -e '--auto-merge' >/dev/null
+			then
+					meld_has_auto_merge_option=true
+			else
+				meld_has_auto_merge_option=false
+			fi
+		fi
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* [PATCH v3] Enable auto-merge for meld to follow the vim-diff beharior
  2020-06-30  7:42       ` David Aguilar
  2020-06-30 11:25         ` lin.sun
@ 2020-06-30 11:37         ` lin.sun
  2020-06-30 15:51         ` Junio C Hamano
  2 siblings, 0 replies; 74+ messages in thread
From: lin.sun @ 2020-06-30 11:37 UTC (permalink / raw)
  To: 'David Aguilar', 'Junio C Hamano'
  Cc: 'sunlin via GitGitGadget', git, 'sunlin'

The last change also available in https://github.com/git/git/pull/781/files.


^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v3] Enable auto-merge for meld to follow the vim-diff beharior
  2020-06-30  7:42       ` David Aguilar
  2020-06-30 11:25         ` lin.sun
  2020-06-30 11:37         ` lin.sun
@ 2020-06-30 15:51         ` Junio C Hamano
  2 siblings, 0 replies; 74+ messages in thread
From: Junio C Hamano @ 2020-06-30 15:51 UTC (permalink / raw)
  To: David Aguilar; +Cc: sunlin via GitGitGadget, git, sunlin, lin.sun

David Aguilar <davvid@gmail.com> writes:

> On Mon, Jun 29, 2020 at 05:06:13PM -0700, Junio C Hamano wrote:
> ...
>> I guess what I am trying to get at is, if --auto-merge is an optional
>> and non-default behaviour for "meld" users, perhaps it is not a good
>> idea to change the behaviour on them only because the version of meld
>> they run happens to support the --auto-merge as an optional behaviour.
>> 
>> IOW, wouldn't it make more sense, and certainly make it safer
>> without surprises to existing users, if we made the logic to
>> 
>>     * If mergetool.meld.useAutoMerge is not set, do not pass
>>       --auto-merge whether "meld" supports the option or not.
>> 
>>     * If mergetool.meld.useAutoMerge is 'true', always pass it
>>       without checking.
>> 
>>     * If mergetool.meld.useAutoMerge is 'when-able' (or come up with
>>       a better name if you want, perhaps 'auto'), check if "meld"
>>       accepts "--auto-merge" and decide whether to pass it or not.
>> 
>> perhaps?
>
> I like the idea of having it be auto/true/false, and perhaps "auto"
> would be a sensible default if more users benefit from it than not.

The principle I've stuck to running this project for the past years
is to avoid hurting 1 user more than trying to please 10 others.  As
I do not use meld regularly myself, I do not know if there are use
cases that are helped by the fact that "--auto-merge" is not the
default behaviour among "meld" users (not limited to "users of
mergetool with meld backend").  And if there are, suddenly changing
the behaviour to those who have happily been using mergetool with
meld backend that does not "--auto-merge" can be disservice to our
users.  Until I hear something along the lines of "Even though meld
requires --auto-merge from users merely due to historical reasons,
these days everybody hates the fact that it is not the default", I'd
recommend against making 'auto' the default on our side, just to be
safe, even if our intuition is that majority of users may want the
"--auto-merge" behaviour.

But I am not a user of mergetool with meld backend, so...

Thanks.

^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v4] Enable auto-merge for meld to follow the vim-diff beharior
  2020-06-30 11:26     ` [PATCH v4] " sunlin via GitGitGadget
@ 2020-06-30 16:23       ` Đoàn Trần Công Danh
  2020-06-30 23:01         ` Đoàn Trần Công Danh
  2020-07-01  7:06       ` [PATCH v5] " sunlin via GitGitGadget
  1 sibling, 1 reply; 74+ messages in thread
From: Đoàn Trần Công Danh @ 2020-06-30 16:23 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, lin.sun

On 2020-06-30 11:26:37+0000, sunlin via GitGitGadget <gitgitgadget@gmail.com> wrote:
> From: "lin.sun" <lin.sun@zoom.us>

This part needs to be fixed, aka, use your real name here :).

> 
> Make the mergetool used with "meld" backend behave similarly to
> how "vimdiff" beheaves by telling it to auto-merge parts without
> conflicts and highlight the parts with conflicts.
> 
> Signed-off-by: lin.sun <lin.sun@zoom.us>
> ---
>     Enable auto-merge for meld to follow the vimdiff beharior
>     
>     Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
>     the mergetool "vimdiff" will merge the no-conflict changes and highlight
>     the conflict parts. This patch will make the mergetool "meld" similar to
>     "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.
> 
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v4
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v4
> Pull-Request: https://github.com/git/git/pull/781
> 
> Range-diff vs v3:
> 
>  1:  3b70fd0bfc ! 1:  93ae3ec011 Enable auto-merge for meld to follow the vim-diff beharior
>      @@ Metadata
>        ## Commit message ##
>           Enable auto-merge for meld to follow the vim-diff beharior
>       
>      -    The mergetool "meld" does NOT merge the no-conflict changes, while the
>      -    mergetool "vimdiff" will merge the no-conflict parts and highlight the
>      -    conflict parts.
>      -    This patch will make the mergetool "meld" similar to "vimdiff",
>      -    auto-merge the no-conflict parts, highlight conflict parts.
>      +    Make the mergetool used with "meld" backend behave similarly to
>      +    how "vimdiff" beheaves by telling it to auto-merge parts without
>      +    conflicts and highlight the parts with conflicts.
>       
>      -    Signed-off-by: Lin Sun <lin.sun@zoom.us>
>      +    Signed-off-by: lin.sun <lin.sun@zoom.us>
>       
>        ## mergetools/meld ##
>      -@@ mergetools/meld: merge_cmd () {
>      - 	then
>      - 		check_meld_for_output_version
>      - 	fi
>      -+	if test -z "${meld_has_auto_merge_option:+set}"
>      -+	then
>      -+		check_meld_for_auto_merge_version
>      -+	fi
>      +@@ mergetools/meld: diff_cmd () {
>      + }
>      + 
>      + merge_cmd () {
>      +-	if test -z "${meld_has_output_option:+set}"
>      ++	check_meld_for_features
>       +
>       +	option_auto_merge=
>       +	if test "$meld_has_auto_merge_option" = true
>      -+	then
>      + 	then
>      +-		check_meld_for_output_version
>       +		option_auto_merge="--auto-merge"
>      -+	fi
>      + 	fi
>        
>        	if test "$meld_has_output_option" = true
>        	then
>      @@ mergetools/meld: merge_cmd () {
>        	fi
>        }
>        
>      -@@ mergetools/meld: check_meld_for_output_version () {
>      - 		meld_has_output_option=false
>      - 	fi
>      - }
>      -+
>      -+# Check whether we should use 'meld --auto-merge ...'
>      -+check_meld_for_auto_merge_version () {
>      -+	meld_path="$(git config mergetool.meld.path)"
>      -+	meld_path="${meld_path:-meld}"
>      +-# Check whether we should use 'meld --output <file>'
>      +-check_meld_for_output_version () {
>      +-	meld_path="$(git config mergetool.meld.path)"
>      +-	meld_path="${meld_path:-meld}"
>      ++# Get meld help message
>      ++get_meld_help_msg () {
>      ++	meld_path="$(git config mergetool.meld.path || echo meld)"
>      ++  $meld_path --help 2>&1
>      ++}
>      + 
>      +-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
>      ++# Check the features and set flags
>      ++check_meld_for_features () {
>      ++	# Check whether we should use 'meld --output <file>'
>      ++	if test -z "${meld_has_output_option:+set}"
>      + 	then
>      +-		: use configured value
>      +-	elif "$meld_path" --help 2>&1 |
>      +-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
>      ++		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
>      ++		if test "$meld_has_output_option" = true -o \
>      ++						"$meld_has_output_option" = false
>      ++		then
>      ++			: use configured value
>      ++		else												# treat meld_has_output_option as "auto"
>      ++			if test -z "$meld_help_msg"
>      ++			then
>      ++				meld_help_msg="$(get_meld_help_msg)"
>      ++			fi
>       +
>      -+	if meld_has_auto_merge_option=$(git config --bool mergetool.meld.hasAutoMerge)
>      -+	then
>      -+		: use configured value
>      -+	elif "$meld_path" --help 2>&1 |
>      -+		grep -e '--auto-merge' -e '\[OPTION\.\.\.\]' >/dev/null
>      -+	then
>      -+		: old ones mention --auto-merge and new ones just say OPTION...
>      -+		meld_has_auto_merge_option=true
>      -+	else
>      -+		meld_has_auto_merge_option=false
>      ++			if echo "$meld_help_msg" |
>      ++							grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
>      ++			then
>      ++				: old ones mention --output and new ones just say OPTION...
>      ++				meld_has_output_option=true
>      ++			else
>      ++				meld_has_output_option=false
>      ++			fi
>      ++		fi
>       +	fi
>      -+}
>      ++	# Check whether we should use 'meld --auto-merge ...'
>      ++	if test -z "${meld_has_auto_merge_option:+set}"
>      + 	then
>      +-		: old ones mention --output and new ones just say OPTION...
>      +-		meld_has_output_option=true
>      +-	else
>      +-		meld_has_output_option=false
>      ++		meld_has_auto_merge_option=$(git config --bool mergetool.meld.hasAutoMerge)
>      ++		if test "$meld_has_auto_merge_option" = true -o \
>      ++						"$meld_has_auto_merge_option" = false
>      ++		then
>      ++			: use configured value
>      ++		else												# treat meld_has_auto_merge_option as "auto"
>      ++			if test -z "$meld_help_msg"
>      ++			then
>      ++					meld_help_msg="$(get_meld_help_msg)"
>      ++			fi
>      ++
>      ++			if echo "$meld_help_msg" | grep -e '--auto-merge' >/dev/null
>      ++			then
>      ++					meld_has_auto_merge_option=true
>      ++			else
>      ++				meld_has_auto_merge_option=false
>      ++			fi
>      ++		fi
>      + 	fi
>      + }
> 
> 
>  mergetools/meld | 73 ++++++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 57 insertions(+), 16 deletions(-)
> 
> diff --git a/mergetools/meld b/mergetools/meld
> index 7a08470f88..1b92771228 100644
> --- a/mergetools/meld
> +++ b/mergetools/meld
> @@ -3,34 +3,75 @@ diff_cmd () {
>  }
>  
>  merge_cmd () {
> -	if test -z "${meld_has_output_option:+set}"
> +	check_meld_for_features
> +
> +	option_auto_merge=
> +	if test "$meld_has_auto_merge_option" = true

We probably want "meld_want_auto_merge"?
Someone may use meld that has --auto-merge but don't want to use it.

>  	then
> -		check_meld_for_output_version
> +		option_auto_merge="--auto-merge"
>  	fi
>  
>  	if test "$meld_has_output_option" = true
>  	then
> -		"$merge_tool_path" --output="$MERGED" \
> +		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
>  			"$LOCAL" "$BASE" "$REMOTE"
>  	else
> -		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
> +		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
>  	fi
>  }
>  
> -# Check whether we should use 'meld --output <file>'
> -check_meld_for_output_version () {
> -	meld_path="$(git config mergetool.meld.path)"
> -	meld_path="${meld_path:-meld}"
> +# Get meld help message
> +get_meld_help_msg () {
> +	meld_path="$(git config mergetool.meld.path || echo meld)"
> +  $meld_path --help 2>&1

We always use TAB for indentation.

> +}
>  
> -	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
> +# Check the features and set flags
> +check_meld_for_features () {
> +	# Check whether we should use 'meld --output <file>'
> +	if test -z "${meld_has_output_option:+set}"
>  	then
> -		: use configured value
> -	elif "$meld_path" --help 2>&1 |
> -		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
> +		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
> +		if test "$meld_has_output_option" = true -o \
> +						"$meld_has_output_option" = false
> +		then
> +			: use configured value
> +		else												# treat meld_has_output_option as "auto"

Please don't put your comment like this,
it's too far away from code,
reader may miss that.

> +			if test -z "$meld_help_msg"
> +			then
> +				meld_help_msg="$(get_meld_help_msg)"
> +			fi
> +
> +			if echo "$meld_help_msg" |
> +							grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null

I probably write like this to save a pipe, a fork and an exec:

	case "$meld_help_msg" in
	*"[OPTION"???"]"*)
		meld_has_output_option=true ;;
	*)
		meld_has_output_option=false ;;
	esac

If you don't like the case ... esac,
I prefer "grep -q" in this case,
I didn't check how much portable it's.
Don't forget to hide the error with 2>/dev/null (or in you case 2>&1)

> +			then
> +				: old ones mention --output and new ones just say OPTION...
> +				meld_has_output_option=true
> +			else
> +				meld_has_output_option=false
> +			fi
> +		fi
> +	fi
> +	# Check whether we should use 'meld --auto-merge ...'
> +	if test -z "${meld_has_auto_merge_option:+set}"
>  	then
> -		: old ones mention --output and new ones just say OPTION...
> -		meld_has_output_option=true

I think something was forgotten here?

> -	else
> -		meld_has_output_option=false
> +		meld_has_auto_merge_option=$(git config --bool mergetool.meld.hasAutoMerge)
> +		if test "$meld_has_auto_merge_option" = true -o \
> +						"$meld_has_auto_merge_option" = false
> +		then
> +			: use configured value
> +		else												# treat meld_has_auto_merge_option as "auto"
> +			if test -z "$meld_help_msg"
> +			then
> +					meld_help_msg="$(get_meld_help_msg)"
> +			fi
> +
> +			if echo "$meld_help_msg" | grep -e '--auto-merge' >/dev/null

And I'll use the same "case ... esac" above for this one :)

> +			then
> +					meld_has_auto_merge_option=true
> +			else
> +				meld_has_auto_merge_option=false
> +			fi
> +		fi
>  	fi
>  }
> 
> base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
> -- 
> gitgitgadget

-- 
Danh

^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v4] Enable auto-merge for meld to follow the vim-diff beharior
  2020-06-30 16:23       ` Đoàn Trần Công Danh
@ 2020-06-30 23:01         ` Đoàn Trần Công Danh
  0 siblings, 0 replies; 74+ messages in thread
From: Đoàn Trần Công Danh @ 2020-06-30 23:01 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, lin.sun

On 2020-06-30 23:23:33+0700, Đoàn Trần Công Danh <congdanhqx@gmail.com> wrote:
> > +			then
> > +				: old ones mention --output and new ones just say OPTION...
> > +				meld_has_output_option=true
> > +			else
> > +				meld_has_output_option=false
> > +			fi
> > +		fi
> > +	fi
> > +	# Check whether we should use 'meld --auto-merge ...'
> > +	if test -z "${meld_has_auto_merge_option:+set}"
> >  	then
> > -		: old ones mention --output and new ones just say OPTION...
> > -		meld_has_output_option=true
> 
> I think something was forgotten here?

Please read this line as:
Is this a copy-paste and forget to edit-afterward.
Somehow that line was lost.


Sorry for the extra noise

Thanks,
Danh

^ permalink raw reply	[flat|nested] 74+ messages in thread

* [PATCH v5] Enable auto-merge for meld to follow the vim-diff beharior
  2020-06-30 11:26     ` [PATCH v4] " sunlin via GitGitGadget
  2020-06-30 16:23       ` Đoàn Trần Công Danh
@ 2020-07-01  7:06       ` sunlin via GitGitGadget
  2020-07-01  7:23         ` lin.sun
                           ` (2 more replies)
  1 sibling, 3 replies; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-07-01  7:06 UTC (permalink / raw)
  To: git; +Cc: sunlin, Lin Sun

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to
how "vimdiff" behavior by telling it to auto-merge parts without
conflicts and highlight the parts with conflicts when configuring
`mergetool.meld.hasAutoMerge` with `true`, or `auto` for
automatically detecting the option.

Signed-off-by: Lin Sun <lin.sun@zoom.us>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v5
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v5
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v4:

 1:  93ae3ec011 ! 1:  344817d579 Enable auto-merge for meld to follow the vim-diff beharior
     @@
       ## Metadata ##
     -Author: lin.sun <lin.sun@zoom.us>
     +Author: Lin Sun <lin.sun@zoom.us>
      
       ## Commit message ##
          Enable auto-merge for meld to follow the vim-diff beharior
      
          Make the mergetool used with "meld" backend behave similarly to
     -    how "vimdiff" beheaves by telling it to auto-merge parts without
     -    conflicts and highlight the parts with conflicts.
     +    how "vimdiff" behavior by telling it to auto-merge parts without
     +    conflicts and highlight the parts with conflicts when configuring
     +    `mergetool.meld.hasAutoMerge` with `true`, or `auto` for
     +    automatically detecting the option.
      
     -    Signed-off-by: lin.sun <lin.sun@zoom.us>
     +    Signed-off-by: Lin Sun <lin.sun@zoom.us>
     +
     + ## Documentation/config/mergetool.txt ##
     +@@ Documentation/config/mergetool.txt: mergetool.meld.hasOutput::
     + 	to `true` tells Git to unconditionally use the `--output` option,
     + 	and `false` avoids using `--output`.
     + 
     ++mergetool.meld.hasAutoMerge::
     ++	Older versions of `meld` do not support the `--auto-merge` option.
     ++	Setting `mergetool.meld.hasOutput` to `true` tells Git to
     ++	unconditionally use the `--auto-merge` option, and `false` avoids using
     ++	`--auto-merge`, and `auto` detect whether `meld` supports `--auto-merge`
     ++	by inspecting the output of `meld --help`, otherwise, follow meld's
     ++	default behavior.
     ++
     + mergetool.keepBackup::
     + 	After performing a merge, the original file with conflict markers
     + 	can be saved as a file with a `.orig` extension.  If this variable
      
       ## mergetools/meld ##
      @@ mergetools/meld: diff_cmd () {
     @@ mergetools/meld: diff_cmd () {
      +# Get meld help message
      +get_meld_help_msg () {
      +	meld_path="$(git config mergetool.meld.path || echo meld)"
     -+  $meld_path --help 2>&1
     ++	$meld_path --help 2>&1
      +}
       
      -	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
     @@ mergetools/meld: diff_cmd () {
      -		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
      +		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
      +		if test "$meld_has_output_option" = true -o \
     -+						"$meld_has_output_option" = false
     ++			"$meld_has_output_option" = false
      +		then
      +			: use configured value
     -+		else												# treat meld_has_output_option as "auto"
     ++		else
     ++			# treat meld_has_output_option as "auto"
      +			if test -z "$meld_help_msg"
      +			then
      +				meld_help_msg="$(get_meld_help_msg)"
      +			fi
      +
     -+			if echo "$meld_help_msg" |
     -+							grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
     -+			then
     -+				: old ones mention --output and new ones just say OPTION...
     -+				meld_has_output_option=true
     -+			else
     -+				meld_has_output_option=false
     -+			fi
     ++			case "$meld_help_msg" in
     ++				*"--output="* | *"[OPTION"???"]"*)
     ++					# old ones mention --output and new ones just say OPTION...
     ++					meld_has_output_option=true ;;
     ++				*)
     ++					meld_has_output_option=false ;;
     ++			esac
      +		fi
      +	fi
      +	# Check whether we should use 'meld --auto-merge ...'
     @@ mergetools/meld: diff_cmd () {
      -		meld_has_output_option=true
      -	else
      -		meld_has_output_option=false
     -+		meld_has_auto_merge_option=$(git config --bool mergetool.meld.hasAutoMerge)
     -+		if test "$meld_has_auto_merge_option" = true -o \
     -+						"$meld_has_auto_merge_option" = false
     ++		meld_has_auto_merge_option=$(git config mergetool.meld.hasAutoMerge)
     ++		if test "$meld_has_auto_merge_option" = auto
      +		then
     -+			: use configured value
     -+		else												# treat meld_has_auto_merge_option as "auto"
     ++			# testing the "--auto-merge" option only if config is "auto"
      +			if test -z "$meld_help_msg"
      +			then
      +					meld_help_msg="$(get_meld_help_msg)"
      +			fi
      +
     -+			if echo "$meld_help_msg" | grep -e '--auto-merge' >/dev/null
     -+			then
     -+					meld_has_auto_merge_option=true
     -+			else
     -+				meld_has_auto_merge_option=false
     -+			fi
     ++			case "$meld_help_msg" in
     ++				*"--auto-merge"*)
     ++					: old ones mention --output and new ones just say OPTION...
     ++					meld_has_auto_merge_option=true ;;
     ++				*)
     ++					meld_has_auto_merge_option=false ;;
     ++			esac
      +		fi
       	fi
       }


 Documentation/config/mergetool.txt |  8 ++++
 mergetools/meld                    | 72 +++++++++++++++++++++++-------
 2 files changed, 64 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..9a74bd98dc 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,14 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.hasAutoMerge::
+	Older versions of `meld` do not support the `--auto-merge` option.
+	Setting `mergetool.meld.hasOutput` to `true` tells Git to
+	unconditionally use the `--auto-merge` option, and `false` avoids using
+	`--auto-merge`, and `auto` detect whether `meld` supports `--auto-merge`
+	by inspecting the output of `meld --help`, otherwise, follow meld's
+	default behavior.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..9ee835b1e5 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,74 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_has_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+get_meld_help_msg () {
+	meld_path="$(git config mergetool.meld.path || echo meld)"
+	$meld_path --help 2>&1
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "${meld_has_output_option:+set}"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		if test "$meld_has_output_option" = true -o \
+			"$meld_has_output_option" = false
+		then
+			: use configured value
+		else
+			# treat meld_has_output_option as "auto"
+			if test -z "$meld_help_msg"
+			then
+				meld_help_msg="$(get_meld_help_msg)"
+			fi
+
+			case "$meld_help_msg" in
+				*"--output="* | *"[OPTION"???"]"*)
+					# old ones mention --output and new ones just say OPTION...
+					meld_has_output_option=true ;;
+				*)
+					meld_has_output_option=false ;;
+			esac
+		fi
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "${meld_has_auto_merge_option:+set}"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_has_auto_merge_option=$(git config mergetool.meld.hasAutoMerge)
+		if test "$meld_has_auto_merge_option" = auto
+		then
+			# testing the "--auto-merge" option only if config is "auto"
+			if test -z "$meld_help_msg"
+			then
+					meld_help_msg="$(get_meld_help_msg)"
+			fi
+
+			case "$meld_help_msg" in
+				*"--auto-merge"*)
+					: old ones mention --output and new ones just say OPTION...
+					meld_has_auto_merge_option=true ;;
+				*)
+					meld_has_auto_merge_option=false ;;
+			esac
+		fi
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* RE: [PATCH v5] Enable auto-merge for meld to follow the vim-diff beharior
  2020-07-01  7:06       ` [PATCH v5] " sunlin via GitGitGadget
@ 2020-07-01  7:23         ` lin.sun
  2020-07-01 18:19           ` David Aguilar
  2020-07-01 14:17         ` Đoàn Trần Công Danh
  2020-07-02  0:44         ` [PATCH v6] Support auto-merge for meld to follow the vim-diff behavior sunlin via GitGitGadget
  2 siblings, 1 reply; 74+ messages in thread
From: lin.sun @ 2020-07-01  7:23 UTC (permalink / raw)
  To: 'sunlin via GitGitGadget',
	git, 'Đoàn Trần Công Danh'
  Cc: 'Junio C Hamano', 'David Aguilar'

Hi Danh,

The [PATH v5] is changed to following the comments from you, Junio, David. 
Please review this newer version. Thank you.
The raw files is https://github.com/git/git/blob/344817d57970e3ac0910cdd8ad47bf97334ab2a6/mergetools/meld

Regards
Lin
-----Original Message-----
From: sunlin via GitGitGadget <gitgitgadget@gmail.com> 
Sent: Wednesday, July 1, 2020 15:07
To: git@vger.kernel.org
Cc: sunlin <sunlin7@yahoo.com>; Lin Sun <lin.sun@zoom.us>
Subject: [PATCH v5] Enable auto-merge for meld to follow the vim-diff beharior

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to how "vimdiff" behavior by telling it to auto-merge parts without conflicts and highlight the parts with conflicts when configuring `mergetool.meld.hasAutoMerge` with `true`, or `auto` for automatically detecting the option.

Signed-off-by: Lin Sun <lin.sun@zoom.us>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v5
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v5
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v4:

 1:  93ae3ec011 ! 1:  344817d579 Enable auto-merge for meld to follow the vim-diff beharior
     @@
       ## Metadata ##
     -Author: lin.sun <lin.sun@zoom.us>
     +Author: Lin Sun <lin.sun@zoom.us>
      
       ## Commit message ##
          Enable auto-merge for meld to follow the vim-diff beharior
      
          Make the mergetool used with "meld" backend behave similarly to
     -    how "vimdiff" beheaves by telling it to auto-merge parts without
     -    conflicts and highlight the parts with conflicts.
     +    how "vimdiff" behavior by telling it to auto-merge parts without
     +    conflicts and highlight the parts with conflicts when configuring
     +    `mergetool.meld.hasAutoMerge` with `true`, or `auto` for
     +    automatically detecting the option.
      
     -    Signed-off-by: lin.sun <lin.sun@zoom.us>
     +    Signed-off-by: Lin Sun <lin.sun@zoom.us>
     +
     + ## Documentation/config/mergetool.txt ##
     +@@ Documentation/config/mergetool.txt: mergetool.meld.hasOutput::
     + 	to `true` tells Git to unconditionally use the `--output` option,
     + 	and `false` avoids using `--output`.
     + 
     ++mergetool.meld.hasAutoMerge::
     ++	Older versions of `meld` do not support the `--auto-merge` option.
     ++	Setting `mergetool.meld.hasOutput` to `true` tells Git to
     ++	unconditionally use the `--auto-merge` option, and `false` avoids using
     ++	`--auto-merge`, and `auto` detect whether `meld` supports `--auto-merge`
     ++	by inspecting the output of `meld --help`, otherwise, follow meld's
     ++	default behavior.
     ++
     + mergetool.keepBackup::
     + 	After performing a merge, the original file with conflict markers
     + 	can be saved as a file with a `.orig` extension.  If this variable
      
       ## mergetools/meld ##
      @@ mergetools/meld: diff_cmd () {
     @@ mergetools/meld: diff_cmd () {
      +# Get meld help message
      +get_meld_help_msg () {
      +	meld_path="$(git config mergetool.meld.path || echo meld)"
     -+  $meld_path --help 2>&1
     ++	$meld_path --help 2>&1
      +}
       
      -	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
     @@ mergetools/meld: diff_cmd () {
      -		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
      +		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
      +		if test "$meld_has_output_option" = true -o \
     -+						"$meld_has_output_option" = false
     ++			"$meld_has_output_option" = false
      +		then
      +			: use configured value
     -+		else												# treat meld_has_output_option as "auto"
     ++		else
     ++			# treat meld_has_output_option as "auto"
      +			if test -z "$meld_help_msg"
      +			then
      +				meld_help_msg="$(get_meld_help_msg)"
      +			fi
      +
     -+			if echo "$meld_help_msg" |
     -+							grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
     -+			then
     -+				: old ones mention --output and new ones just say OPTION...
     -+				meld_has_output_option=true
     -+			else
     -+				meld_has_output_option=false
     -+			fi
     ++			case "$meld_help_msg" in
     ++				*"--output="* | *"[OPTION"???"]"*)
     ++					# old ones mention --output and new ones just say OPTION...
     ++					meld_has_output_option=true ;;
     ++				*)
     ++					meld_has_output_option=false ;;
     ++			esac
      +		fi
      +	fi
      +	# Check whether we should use 'meld --auto-merge ...'
     @@ mergetools/meld: diff_cmd () {
      -		meld_has_output_option=true
      -	else
      -		meld_has_output_option=false
     -+		meld_has_auto_merge_option=$(git config --bool mergetool.meld.hasAutoMerge)
     -+		if test "$meld_has_auto_merge_option" = true -o \
     -+						"$meld_has_auto_merge_option" = false
     ++		meld_has_auto_merge_option=$(git config mergetool.meld.hasAutoMerge)
     ++		if test "$meld_has_auto_merge_option" = auto
      +		then
     -+			: use configured value
     -+		else												# treat meld_has_auto_merge_option as "auto"
     ++			# testing the "--auto-merge" option only if config is "auto"
      +			if test -z "$meld_help_msg"
      +			then
      +					meld_help_msg="$(get_meld_help_msg)"
      +			fi
      +
     -+			if echo "$meld_help_msg" | grep -e '--auto-merge' >/dev/null
     -+			then
     -+					meld_has_auto_merge_option=true
     -+			else
     -+				meld_has_auto_merge_option=false
     -+			fi
     ++			case "$meld_help_msg" in
     ++				*"--auto-merge"*)
     ++					: old ones mention --output and new ones just say OPTION...
     ++					meld_has_auto_merge_option=true ;;
     ++				*)
     ++					meld_has_auto_merge_option=false ;;
     ++			esac
      +		fi
       	fi
       }


 Documentation/config/mergetool.txt |  8 ++++
 mergetools/meld                    | 72 +++++++++++++++++++++++-------
 2 files changed, 64 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..9a74bd98dc 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,14 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.hasAutoMerge::
+	Older versions of `meld` do not support the `--auto-merge` option.
+	Setting `mergetool.meld.hasOutput` to `true` tells Git to
+	unconditionally use the `--auto-merge` option, and `false` avoids using
+	`--auto-merge`, and `auto` detect whether `meld` supports `--auto-merge`
+	by inspecting the output of `meld --help`, otherwise, follow meld's
+	default behavior.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable diff --git a/mergetools/meld b/mergetools/meld index 7a08470f88..9ee835b1e5 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,74 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_has_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+get_meld_help_msg () {
+	meld_path="$(git config mergetool.meld.path || echo meld)"
+	$meld_path --help 2>&1
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "${meld_has_output_option:+set}"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		if test "$meld_has_output_option" = true -o \
+			"$meld_has_output_option" = false
+		then
+			: use configured value
+		else
+			# treat meld_has_output_option as "auto"
+			if test -z "$meld_help_msg"
+			then
+				meld_help_msg="$(get_meld_help_msg)"
+			fi
+
+			case "$meld_help_msg" in
+				*"--output="* | *"[OPTION"???"]"*)
+					# old ones mention --output and new ones just say OPTION...
+					meld_has_output_option=true ;;
+				*)
+					meld_has_output_option=false ;;
+			esac
+		fi
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "${meld_has_auto_merge_option:+set}"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_has_auto_merge_option=$(git config mergetool.meld.hasAutoMerge)
+		if test "$meld_has_auto_merge_option" = auto
+		then
+			# testing the "--auto-merge" option only if config is "auto"
+			if test -z "$meld_help_msg"
+			then
+					meld_help_msg="$(get_meld_help_msg)"
+			fi
+
+			case "$meld_help_msg" in
+				*"--auto-merge"*)
+					: old ones mention --output and new ones just say OPTION...
+					meld_has_auto_merge_option=true ;;
+				*)
+					meld_has_auto_merge_option=false ;;
+			esac
+		fi
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
--
gitgitgadget


^ permalink raw reply related	[flat|nested] 74+ messages in thread

* Re: [PATCH v5] Enable auto-merge for meld to follow the vim-diff beharior
  2020-07-01  7:06       ` [PATCH v5] " sunlin via GitGitGadget
  2020-07-01  7:23         ` lin.sun
@ 2020-07-01 14:17         ` Đoàn Trần Công Danh
  2020-07-01 15:32           ` lin.sun
  2020-07-01 19:51           ` Junio C Hamano
  2020-07-02  0:44         ` [PATCH v6] Support auto-merge for meld to follow the vim-diff behavior sunlin via GitGitGadget
  2 siblings, 2 replies; 74+ messages in thread
From: Đoàn Trần Công Danh @ 2020-07-01 14:17 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, Lin Sun

On 2020-07-01 07:06:46+0000, sunlin via GitGitGadget <gitgitgadget@gmail.com> wrote:
> From: Lin Sun <lin.sun@zoom.us>
> 
> Make the mergetool used with "meld" backend behave similarly to
> how "vimdiff" behavior by telling it to auto-merge parts without
> conflicts and highlight the parts with conflicts when configuring
> `mergetool.meld.hasAutoMerge` with `true`, or `auto` for
> automatically detecting the option.
> 
> Signed-off-by: Lin Sun <lin.sun@zoom.us>
> ---
> diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
> index 09ed31dbfa..9a74bd98dc 100644
> --- a/Documentation/config/mergetool.txt
> +++ b/Documentation/config/mergetool.txt
> @@ -30,6 +30,14 @@ mergetool.meld.hasOutput::
>  	to `true` tells Git to unconditionally use the `--output` option,
>  	and `false` avoids using `--output`.
>  
> +mergetool.meld.hasAutoMerge::
> +	Older versions of `meld` do not support the `--auto-merge` option.
> +	Setting `mergetool.meld.hasOutput` to `true` tells Git to

s/hasOutput/hasAutoMerge/

Bikeshed opinion: I don't know if hasAutoMerge is a good name :)

> +	unconditionally use the `--auto-merge` option, and `false` avoids using
> +	`--auto-merge`, and `auto` detect whether `meld` supports `--auto-merge`
> +	by inspecting the output of `meld --help`, otherwise, follow meld's
> +	default behavior.
> +
>  mergetool.keepBackup::
>  	After performing a merge, the original file with conflict markers
>  	can be saved as a file with a `.orig` extension.  If this variable
> diff --git a/mergetools/meld b/mergetools/meld
> index 7a08470f88..9ee835b1e5 100644
> --- a/mergetools/meld
> +++ b/mergetools/meld
> @@ -3,34 +3,74 @@ diff_cmd () {
>  }
>  
>  merge_cmd () {
> -	if test -z "${meld_has_output_option:+set}"
> +	check_meld_for_features
> +
> +	option_auto_merge=
> +	if test "$meld_has_auto_merge_option" = true
>  	then
> -		check_meld_for_output_version
> +		option_auto_merge="--auto-merge"
>  	fi
>  
>  	if test "$meld_has_output_option" = true
>  	then
> -		"$merge_tool_path" --output="$MERGED" \
> +		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
>  			"$LOCAL" "$BASE" "$REMOTE"
>  	else
> -		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
> +		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
>  	fi
>  }
>  
> -# Check whether we should use 'meld --output <file>'
> -check_meld_for_output_version () {
> -	meld_path="$(git config mergetool.meld.path)"
> -	meld_path="${meld_path:-meld}"
> +# Get meld help message
> +get_meld_help_msg () {
> +	meld_path="$(git config mergetool.meld.path || echo meld)"
> +	$meld_path --help 2>&1
> +}

I'm actually prefer this change in 2 separated patches to reduce noise.
But given that mergetool/meld doesn't attract much attention, I don't know.

>  
> -	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
> +# Check the features and set flags
> +check_meld_for_features () {
> +	# Check whether we should use 'meld --output <file>'
> +	if test -z "${meld_has_output_option:+set}"
>  	then
> -		: use configured value
> -	elif "$meld_path" --help 2>&1 |
> -		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
> +		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
> +		if test "$meld_has_output_option" = true -o \
> +			"$meld_has_output_option" = false

The coding guideline seems to not like "test -o".
I think it's acceptable in this case since we control its input.
The output is comming out of "git config --bool" anyway,
so meld_has_output_option must be either "", "true", or "false"

I think we're better to do this instead:

	if test -n "$meld_has_output_option"
	then
		: use configured output
	else
		: messing with help
	fi

> +		then
> +			: use configured value
> +		else
> +			# treat meld_has_output_option as "auto"
> +			if test -z "$meld_help_msg"
> +			then
> +				meld_help_msg="$(get_meld_help_msg)"
> +			fi

If I were writing this patch, I probably changed get_meld_help_msg to

	init_meld_help_msg () {
		if test -z "$meld_help_msg"
		then
			meld_path="$(git config mergetool.meld.path || echo meld)"
			meld_help_msg=$($meld_path --help 2>&1)
		fi
	}

And call init_meld_help_msg unconditionally here,
(and in --auto-merge arm below, maybe other arms in the future).

I'm writing without much thought into this,
please take my word with a grain of salt :)

> +}


> +
> +			case "$meld_help_msg" in
> +				*"--output="* | *"[OPTION"???"]"*)

I think Git project prefer aligning case arm with case,
IOW, move left 1 TAB.

> +					# old ones mention --output and new ones just say OPTION...
> +					meld_has_output_option=true ;;

It's nice to see this update, good.
The comment is no longer correct, though.
The version 3.20.2 has --output but not OPTIONS.

It's not introduced by your change, but I think it's better to say:

	# All versions that has [OPTIONS???] supports --output

> +				*)
> +					meld_has_output_option=false ;;
> +			esac
> +		fi
> +	fi
> +	# Check whether we should use 'meld --auto-merge ...'
> +	if test -z "${meld_has_auto_merge_option:+set}"
>  	then
> -		: old ones mention --output and new ones just say OPTION...
> -		meld_has_output_option=true
> -	else
> -		meld_has_output_option=false
> +		meld_has_auto_merge_option=$(git config mergetool.meld.hasAutoMerge)
> +		if test "$meld_has_auto_merge_option" = auto

Since we don't canonicallise to bool output of
mergetool.meld.hasAutoMerge, I think we would need:

	case "$meld_has_auto_merge_option" in
	[Tt]rue|[Yy]es|[Oo]n)
		meld_has_auto_merge_option=true ;;
	auto)
		: this shenanigan ;;
	esac

But, that's a bit messy. Let's see other's opinions.

> +		then
> +			# testing the "--auto-merge" option only if config is "auto"
> +			if test -z "$meld_help_msg"
> +			then
> +					meld_help_msg="$(get_meld_help_msg)"
> +			fi
> +
> +			case "$meld_help_msg" in
> +				*"--auto-merge"*)
> +					: old ones mention --output and new ones just say OPTION...

This comment doesn't apply here.

> +					meld_has_auto_merge_option=true ;;
> +				*)
> +					meld_has_auto_merge_option=false ;;
> +			esac
> +		fi
>  	fi
>  }
> 
> base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
> -- 
> gitgitgadget

-- 
Danh

^ permalink raw reply	[flat|nested] 74+ messages in thread

* RE: [PATCH v5] Enable auto-merge for meld to follow the vim-diff beharior
  2020-07-01 14:17         ` Đoàn Trần Công Danh
@ 2020-07-01 15:32           ` lin.sun
  2020-07-01 22:02             ` lin.sun
  2020-07-01 19:51           ` Junio C Hamano
  1 sibling, 1 reply; 74+ messages in thread
From: lin.sun @ 2020-07-01 15:32 UTC (permalink / raw)
  To: 'Đoàn Trần Công Danh',
	'sunlin via GitGitGadget'
  Cc: git, 'Lin Sun'

[-- Attachment #1: Type: text/plain, Size: 6927 bytes --]

Hi Danh,

Thank you for your comments, and changes apply to the last patch with your suggestions. Please refer the attachment for [PATH v6].
Thank you.

Regards
Lin 

-----Original Message-----
From: Đoàn Trần Công Danh <congdanhqx@gmail.com> 
Sent: Wednesday, July 1, 2020 22:18
To: sunlin via GitGitGadget <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org; sunlin <sunlin7@yahoo.com>; Lin Sun <lin.sun@zoom.us>
Subject: Re: [PATCH v5] Enable auto-merge for meld to follow the vim-diff beharior

On 2020-07-01 07:06:46+0000, sunlin via GitGitGadget <gitgitgadget@gmail.com> wrote:
> From: Lin Sun <lin.sun@zoom.us>
> 
> Make the mergetool used with "meld" backend behave similarly to how 
> "vimdiff" behavior by telling it to auto-merge parts without conflicts 
> and highlight the parts with conflicts when configuring 
> `mergetool.meld.hasAutoMerge` with `true`, or `auto` for automatically 
> detecting the option.
> 
> Signed-off-by: Lin Sun <lin.sun@zoom.us>
> ---
> diff --git a/Documentation/config/mergetool.txt 
> b/Documentation/config/mergetool.txt
> index 09ed31dbfa..9a74bd98dc 100644
> --- a/Documentation/config/mergetool.txt
> +++ b/Documentation/config/mergetool.txt
> @@ -30,6 +30,14 @@ mergetool.meld.hasOutput::
>  	to `true` tells Git to unconditionally use the `--output` option,
>  	and `false` avoids using `--output`.
>  
> +mergetool.meld.hasAutoMerge::
> +	Older versions of `meld` do not support the `--auto-merge` option.
> +	Setting `mergetool.meld.hasOutput` to `true` tells Git to

s/hasOutput/hasAutoMerge/

Bikeshed opinion: I don't know if hasAutoMerge is a good name :)

> +	unconditionally use the `--auto-merge` option, and `false` avoids using
> +	`--auto-merge`, and `auto` detect whether `meld` supports `--auto-merge`
> +	by inspecting the output of `meld --help`, otherwise, follow meld's
> +	default behavior.
> +
>  mergetool.keepBackup::
>  	After performing a merge, the original file with conflict markers
>  	can be saved as a file with a `.orig` extension.  If this variable 
> diff --git a/mergetools/meld b/mergetools/meld index 
> 7a08470f88..9ee835b1e5 100644
> --- a/mergetools/meld
> +++ b/mergetools/meld
> @@ -3,34 +3,74 @@ diff_cmd () {
>  }
>  
>  merge_cmd () {
> -	if test -z "${meld_has_output_option:+set}"
> +	check_meld_for_features
> +
> +	option_auto_merge=
> +	if test "$meld_has_auto_merge_option" = true
>  	then
> -		check_meld_for_output_version
> +		option_auto_merge="--auto-merge"
>  	fi
>  
>  	if test "$meld_has_output_option" = true
>  	then
> -		"$merge_tool_path" --output="$MERGED" \
> +		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
>  			"$LOCAL" "$BASE" "$REMOTE"
>  	else
> -		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
> +		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
>  	fi
>  }
>  
> -# Check whether we should use 'meld --output <file>'
> -check_meld_for_output_version () {
> -	meld_path="$(git config mergetool.meld.path)"
> -	meld_path="${meld_path:-meld}"
> +# Get meld help message
> +get_meld_help_msg () {
> +	meld_path="$(git config mergetool.meld.path || echo meld)"
> +	$meld_path --help 2>&1
> +}

I'm actually prefer this change in 2 separated patches to reduce noise.
But given that mergetool/meld doesn't attract much attention, I don't know.

>  
> -	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
> +# Check the features and set flags
> +check_meld_for_features () {
> +	# Check whether we should use 'meld --output <file>'
> +	if test -z "${meld_has_output_option:+set}"
>  	then
> -		: use configured value
> -	elif "$meld_path" --help 2>&1 |
> -		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
> +		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
> +		if test "$meld_has_output_option" = true -o \
> +			"$meld_has_output_option" = false

The coding guideline seems to not like "test -o".
I think it's acceptable in this case since we control its input.
The output is comming out of "git config --bool" anyway, so meld_has_output_option must be either "", "true", or "false"

I think we're better to do this instead:

	if test -n "$meld_has_output_option"
	then
		: use configured output
	else
		: messing with help
	fi

> +		then
> +			: use configured value
> +		else
> +			# treat meld_has_output_option as "auto"
> +			if test -z "$meld_help_msg"
> +			then
> +				meld_help_msg="$(get_meld_help_msg)"
> +			fi

If I were writing this patch, I probably changed get_meld_help_msg to

	init_meld_help_msg () {
		if test -z "$meld_help_msg"
		then
			meld_path="$(git config mergetool.meld.path || echo meld)"
			meld_help_msg=$($meld_path --help 2>&1)
		fi
	}

And call init_meld_help_msg unconditionally here, (and in --auto-merge arm below, maybe other arms in the future).

I'm writing without much thought into this, please take my word with a grain of salt :)

> +}


> +
> +			case "$meld_help_msg" in
> +				*"--output="* | *"[OPTION"???"]"*)

I think Git project prefer aligning case arm with case, IOW, move left 1 TAB.

> +					# old ones mention --output and new ones just say OPTION...
> +					meld_has_output_option=true ;;

It's nice to see this update, good.
The comment is no longer correct, though.
The version 3.20.2 has --output but not OPTIONS.

It's not introduced by your change, but I think it's better to say:

	# All versions that has [OPTIONS???] supports --output

> +				*)
> +					meld_has_output_option=false ;;
> +			esac
> +		fi
> +	fi
> +	# Check whether we should use 'meld --auto-merge ...'
> +	if test -z "${meld_has_auto_merge_option:+set}"
>  	then
> -		: old ones mention --output and new ones just say OPTION...
> -		meld_has_output_option=true
> -	else
> -		meld_has_output_option=false
> +		meld_has_auto_merge_option=$(git config mergetool.meld.hasAutoMerge)
> +		if test "$meld_has_auto_merge_option" = auto

Since we don't canonicallise to bool output of mergetool.meld.hasAutoMerge, I think we would need:

	case "$meld_has_auto_merge_option" in
	[Tt]rue|[Yy]es|[Oo]n)
		meld_has_auto_merge_option=true ;;
	auto)
		: this shenanigan ;;
	esac

But, that's a bit messy. Let's see other's opinions.

> +		then
> +			# testing the "--auto-merge" option only if config is "auto"
> +			if test -z "$meld_help_msg"
> +			then
> +					meld_help_msg="$(get_meld_help_msg)"
> +			fi
> +
> +			case "$meld_help_msg" in
> +				*"--auto-merge"*)
> +					: old ones mention --output and new ones just say OPTION...

This comment doesn't apply here.

> +					meld_has_auto_merge_option=true ;;
> +				*)
> +					meld_has_auto_merge_option=false ;;
> +			esac
> +		fi
>  	fi
>  }
> 
> base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
> --
> gitgitgadget

--
Danh

[-- Attachment #2: 0001-Enable-auto-merge-for-meld-to-follow-the-vim-diff-be.patch --]
[-- Type: application/octet-stream, Size: 4658 bytes --]

From 33968fb9e52a6ead7b9fc64943d4c82c3f893865 Mon Sep 17 00:00:00 2001
From: Lin Sun <lin.sun@zoom.us>
Date: Thu, 7 May 2020 07:31:14 +0800
Subject: [PATCH] Enable auto-merge for meld to follow the vim-diff beharior
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Make the mergetool used with "meld" backend behave similarly to
how "vimdiff" behavior by telling it to auto-merge parts without
conflicts and highlight the parts with conflicts when configuring
`mergetool.meld.hasAutoMerge` with `true`, or `auto` for
automatically detecting the option.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
---
 Documentation/config/mergetool.txt |  8 ++++
 mergetools/meld                    | 80 ++++++++++++++++++++++++++++++--------
 2 files changed, 72 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31d..d2af88c 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,14 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.hasAutoMerge::
+	Older versions of `meld` do not support the `--auto-merge` option.
+	Setting `mergetool.meld.hasAutoMerge` to `true` tells Git to
+	unconditionally use the `--auto-merge` option, and `false` avoids using
+	`--auto-merge`, and `auto` detect whether `meld` supports `--auto-merge`
+	by inspecting the output of `meld --help`, otherwise, follow meld's
+	default behavior.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470..c6f499d 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,82 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_has_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "${meld_help_msg:+set}"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$($meld_path --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "${meld_has_output_option:+set}"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true|false)
+			: use configured value
+			;;
+		*)
+			: treat meld_has_output_option as "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="* | *"[OPTION"???"]"*)
+				# All version that has [OPTION???] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "${meld_has_auto_merge_option:+set}"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_has_auto_merge_option=$(git config mergetool.meld.hasAutoMerge)
+		case "$meld_has_auto_merge_option" in
+		[Tt]rue|[Yy]es|[Oo]n|1)
+			meld_has_auto_merge_option=true
+			;;
+		auto)
+			# testing the "--auto-merge" option only if config is "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--auto-merge"*)
+				meld_has_auto_merge_option=true
+				;;
+			*)
+				meld_has_auto_merge_option=false
+				;;
+			esac
+			;;
+		*)
+			meld_has_auto_merge_option=false
+			;;
+		esac
 	fi
 }
-- 
2.2.0


^ permalink raw reply related	[flat|nested] 74+ messages in thread

* Re: [PATCH v5] Enable auto-merge for meld to follow the vim-diff beharior
  2020-07-01  7:23         ` lin.sun
@ 2020-07-01 18:19           ` David Aguilar
  0 siblings, 0 replies; 74+ messages in thread
From: David Aguilar @ 2020-07-01 18:19 UTC (permalink / raw)
  To: lin.sun
  Cc: 'sunlin via GitGitGadget',
	git, 'Đoàn Trần Công Danh',
	'Junio C Hamano'

On Wed, Jul 01, 2020 at 03:23:56PM +0800, lin.sun@zoom.us wrote:
> Hi Danh,
> 
> The [PATH v5] is changed to following the comments from you, Junio, David. 
> Please review this newer version. Thank you.
> The raw files is https://github.com/git/git/blob/344817d57970e3ac0910cdd8ad47bf97334ab2a6/mergetools/meld
> 
> Regards
> Lin
> -----Original Message-----
> From: sunlin via GitGitGadget <gitgitgadget@gmail.com> 
> Sent: Wednesday, July 1, 2020 15:07
> To: git@vger.kernel.org
> Cc: sunlin <sunlin7@yahoo.com>; Lin Sun <lin.sun@zoom.us>
> Subject: [PATCH v5] Enable auto-merge for meld to follow the vim-diff beharior
> 
> From: Lin Sun <lin.sun@zoom.us>
> 
> Make the mergetool used with "meld" backend behave similarly to how "vimdiff" behavior by telling it to auto-merge parts without conflicts and highlight the parts with conflicts when configuring `mergetool.meld.hasAutoMerge` with `true`, or `auto` for automatically detecting the option.

Please word-wrap commit messages to 72 chars or less.


> 
> Signed-off-by: Lin Sun <lin.sun@zoom.us>
> ---
>  Documentation/config/mergetool.txt |  8 ++++
>  mergetools/meld                    | 72 +++++++++++++++++++++++-------
>  2 files changed, 64 insertions(+), 16 deletions(-)
> 
> diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
> index 09ed31dbfa..9a74bd98dc 100644
> --- a/Documentation/config/mergetool.txt
> +++ b/Documentation/config/mergetool.txt
> @@ -30,6 +30,14 @@ mergetool.meld.hasOutput::
>  	to `true` tells Git to unconditionally use the `--output` option,
>  	and `false` avoids using `--output`.
>  
> +mergetool.meld.hasAutoMerge::
> +	Older versions of `meld` do not support the `--auto-merge` option.
> +	Setting `mergetool.meld.hasOutput` to `true` tells Git to
> +	unconditionally use the `--auto-merge` option, and `false` avoids using
> +	`--auto-merge`, and `auto` detect whether `meld` supports `--auto-merge`
> +	by inspecting the output of `meld --help`, otherwise, follow meld's
> +	default behavior.
> +

Now that we've decided that "false" should be the default behavior, the
naming of this option don't make sense.  "hasAutoMerge" doesn't
really convey what this option does anymore.  I would suggest calling it
"mergetool.meld.automerge".

Perhaps something like this?

mergetool.meld.automerge::
	Older versions of `meld` do not support the `--auto-merge`
	option.  Setting `mergetool.meld.automerge` to `true` tells Git
	to unconditionally use the `--auto-merge` option with `meld`.
	Setting this value to `auto` makes git detect whether
	`--auto-merge` is supported and will only use `--auto-merge`
	when available.  A value of `false` avoids using `--auto-merge`
	altogether, and is the default value.

> @@ -3,34 +3,74 @@ diff_cmd () {
>  }
>  
>  merge_cmd () {
> -	if test -z "${meld_has_output_option:+set}"
> +	check_meld_for_features
> +
> +	option_auto_merge=
> +	if test "$meld_has_auto_merge_option" = true
>  	then
> -		check_meld_for_output_version
> +		option_auto_merge="--auto-merge"
>  	fi
>  
>  	if test "$meld_has_output_option" = true
>  	then
> -		"$merge_tool_path" --output="$MERGED" \
> +		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
>  			"$LOCAL" "$BASE" "$REMOTE"
>  	else
> -		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
> +		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
>  	fi
>  }
>  
> -# Check whether we should use 'meld --output <file>'
> -check_meld_for_output_version () {
> -	meld_path="$(git config mergetool.meld.path)"
> -	meld_path="${meld_path:-meld}"
> +# Get meld help message
> +get_meld_help_msg () {

This comment seems redundant when the function is called
get_meld_help_msg().


> +	meld_path="$(git config mergetool.meld.path || echo meld)"
> +	$meld_path --help 2>&1
> +}
>  
> -	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
> +# Check the features and set flags
> +check_meld_for_features () {

Ditto for this comment.


> +	# Check whether we should use 'meld --output <file>'
> +	if test -z "${meld_has_output_option:+set}"
>  	then
> -		: use configured value
> -	elif "$meld_path" --help 2>&1 |
> -		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
> +		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
> +		if test "$meld_has_output_option" = true -o \
> +			"$meld_has_output_option" = false

Documentation/CodingGuidelines mentions:

 - We do not write our "test" command with "-a" and "-o" and use "&&"
   or "||" to concatenate multiple "test" commands instead, because
   the use of "-a/-o" is often error-prone.  E.g.

This would be written as:

	if test "$meld_has_output_option" = true ||
		test "$meld_has_output_option" = false
	then
		...
	fi

Instead of two checks, would it be better to instead just check:
	if test -n "$meld_has_output_option"
?
git config --bool will only ever produce true/false, so we really only
need to check that it's a non-empty value, perhaps?


> +			case "$meld_help_msg" in
> +				*"--output="* | *"[OPTION"???"]"*)
> +					# old ones mention --output and new ones just say OPTION...
> +					meld_has_output_option=true ;;
> +				*)
> +					meld_has_output_option=false ;;
> +			esac

We typically avoid the extra indentation level for the case labels.
eg. this would be written like this (with ";;" on its own line):

	case "$meld_help_msg" in
	*--output=*|*"[OPTION"???"]"*)
		# old ones mention --output and new ones just say OPTION...
		meld_has_output_option=true
		;;
	*)
		meld_has_output_option=false
		;;
	esac


Also, if you're matching [OPTION ...] would it work to just use
a single-quoted value in the case label?  eg: *'[OPTION...]'* ?


> +	if test -z "${meld_has_auto_merge_option:+set}"
>  	then
> -		: old ones mention --output and new ones just say OPTION...
> -		meld_has_output_option=true
> -	else
> -		meld_has_output_option=false
> +		meld_has_auto_merge_option=$(git config mergetool.meld.hasAutoMerge)
> +		if test "$meld_has_auto_merge_option" = auto
> +		then
> +			# testing the "--auto-merge" option only if config is "auto"
> +			if test -z "$meld_help_msg"
> +			then
> +					meld_help_msg="$(get_meld_help_msg)"

This can just be:

	meld_help_msg=$(get_meld_help_msg)

and can do without the surrounding " " double quotes.



> +			case "$meld_help_msg" in
> +				*"--auto-merge"*)
> +					: old ones mention --output and new ones just say OPTION...
> +					meld_has_auto_merge_option=true ;;
> +				*)
> +					meld_has_auto_merge_option=false ;;
> +			esac

As above -- unindent the case statements, and put the ";;" case
statement terminators on their own line.

cheers,
-- 
David

^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v5] Enable auto-merge for meld to follow the vim-diff beharior
  2020-07-01 14:17         ` Đoàn Trần Công Danh
  2020-07-01 15:32           ` lin.sun
@ 2020-07-01 19:51           ` Junio C Hamano
  2020-07-02  0:20             ` lin.sun
  1 sibling, 1 reply; 74+ messages in thread
From: Junio C Hamano @ 2020-07-01 19:51 UTC (permalink / raw)
  To: Đoàn Trần Công Danh
  Cc: sunlin via GitGitGadget, git, sunlin, Lin Sun

Đoàn Trần Công Danh  <congdanhqx@gmail.com> writes:

>> +mergetool.meld.hasAutoMerge::
>> +	Older versions of `meld` do not support the `--auto-merge` option.
>> +	Setting `mergetool.meld.hasOutput` to `true` tells Git to
>
> s/hasOutput/hasAutoMerge/
>
> Bikeshed opinion: I don't know if hasAutoMerge is a good name :)

I do not think "has" is a good choice for this one, even though
hasOutput may very well be a good one for "output".  As the
paragraph describes (below), this lets the user "avoid" using
"--auto-merge", even if the version of "meld" the user has does have
the automerge capability.

So perhaps say "mergetool.meld.useAutoMerge"; that will let the users
express exactly their wish---don't use it (false), do forcibly try
to use it (true), or use it when able (auto).


^ permalink raw reply	[flat|nested] 74+ messages in thread

* RE: [PATCH v5] Enable auto-merge for meld to follow the vim-diff beharior
  2020-07-01 15:32           ` lin.sun
@ 2020-07-01 22:02             ` lin.sun
  2020-07-01 23:06               ` Đoàn Trần Công Danh
  0 siblings, 1 reply; 74+ messages in thread
From: lin.sun @ 2020-07-01 22:02 UTC (permalink / raw)
  To: 'Đoàn Trần Công Danh',
	'sunlin via GitGitGadget'
  Cc: git

Hi Danh,

I'll push the patch to GitGitGadget so that it's will sending from the system mail. Sorry for this noise.

Regards
Lin

-----Original Message-----
From: lin.sun@zoom.us <lin.sun@zoom.us> 
Sent: Wednesday, July 1, 2020 23:32
To: 'Đoàn Trần Công Danh' <congdanhqx@gmail.com>; 'sunlin via GitGitGadget' <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org; 'Lin Sun' <lin.sun@zoom.us>
Subject: RE: [PATCH v5] Enable auto-merge for meld to follow the vim-diff beharior

Hi Danh,

Thank you for your comments, and changes apply to the last patch with your suggestions. Please refer the attachment for [PATH v6].
Thank you.

Regards
Lin 

-----Original Message-----
From: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Sent: Wednesday, July 1, 2020 22:18
To: sunlin via GitGitGadget <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org; sunlin <sunlin7@yahoo.com>; Lin Sun <lin.sun@zoom.us>
Subject: Re: [PATCH v5] Enable auto-merge for meld to follow the vim-diff beharior

On 2020-07-01 07:06:46+0000, sunlin via GitGitGadget <gitgitgadget@gmail.com> wrote:
> From: Lin Sun <lin.sun@zoom.us>
> 
> Make the mergetool used with "meld" backend behave similarly to how 
> "vimdiff" behavior by telling it to auto-merge parts without conflicts 
> and highlight the parts with conflicts when configuring 
> `mergetool.meld.hasAutoMerge` with `true`, or `auto` for automatically 
> detecting the option.
> 
> Signed-off-by: Lin Sun <lin.sun@zoom.us>
> ---
> diff --git a/Documentation/config/mergetool.txt
> b/Documentation/config/mergetool.txt
> index 09ed31dbfa..9a74bd98dc 100644
> --- a/Documentation/config/mergetool.txt
> +++ b/Documentation/config/mergetool.txt
> @@ -30,6 +30,14 @@ mergetool.meld.hasOutput::
>  	to `true` tells Git to unconditionally use the `--output` option,
>  	and `false` avoids using `--output`.
>  
> +mergetool.meld.hasAutoMerge::
> +	Older versions of `meld` do not support the `--auto-merge` option.
> +	Setting `mergetool.meld.hasOutput` to `true` tells Git to

s/hasOutput/hasAutoMerge/

Bikeshed opinion: I don't know if hasAutoMerge is a good name :)

> +	unconditionally use the `--auto-merge` option, and `false` avoids using
> +	`--auto-merge`, and `auto` detect whether `meld` supports `--auto-merge`
> +	by inspecting the output of `meld --help`, otherwise, follow meld's
> +	default behavior.
> +
>  mergetool.keepBackup::
>  	After performing a merge, the original file with conflict markers
>  	can be saved as a file with a `.orig` extension.  If this variable 
> diff --git a/mergetools/meld b/mergetools/meld index
> 7a08470f88..9ee835b1e5 100644
> --- a/mergetools/meld
> +++ b/mergetools/meld
> @@ -3,34 +3,74 @@ diff_cmd () {
>  }
>  
>  merge_cmd () {
> -	if test -z "${meld_has_output_option:+set}"
> +	check_meld_for_features
> +
> +	option_auto_merge=
> +	if test "$meld_has_auto_merge_option" = true
>  	then
> -		check_meld_for_output_version
> +		option_auto_merge="--auto-merge"
>  	fi
>  
>  	if test "$meld_has_output_option" = true
>  	then
> -		"$merge_tool_path" --output="$MERGED" \
> +		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
>  			"$LOCAL" "$BASE" "$REMOTE"
>  	else
> -		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
> +		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
>  	fi
>  }
>  
> -# Check whether we should use 'meld --output <file>'
> -check_meld_for_output_version () {
> -	meld_path="$(git config mergetool.meld.path)"
> -	meld_path="${meld_path:-meld}"
> +# Get meld help message
> +get_meld_help_msg () {
> +	meld_path="$(git config mergetool.meld.path || echo meld)"
> +	$meld_path --help 2>&1
> +}

I'm actually prefer this change in 2 separated patches to reduce noise.
But given that mergetool/meld doesn't attract much attention, I don't know.

>  
> -	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
> +# Check the features and set flags
> +check_meld_for_features () {
> +	# Check whether we should use 'meld --output <file>'
> +	if test -z "${meld_has_output_option:+set}"
>  	then
> -		: use configured value
> -	elif "$meld_path" --help 2>&1 |
> -		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
> +		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
> +		if test "$meld_has_output_option" = true -o \
> +			"$meld_has_output_option" = false

The coding guideline seems to not like "test -o".
I think it's acceptable in this case since we control its input.
The output is comming out of "git config --bool" anyway, so meld_has_output_option must be either "", "true", or "false"

I think we're better to do this instead:

	if test -n "$meld_has_output_option"
	then
		: use configured output
	else
		: messing with help
	fi

> +		then
> +			: use configured value
> +		else
> +			# treat meld_has_output_option as "auto"
> +			if test -z "$meld_help_msg"
> +			then
> +				meld_help_msg="$(get_meld_help_msg)"
> +			fi

If I were writing this patch, I probably changed get_meld_help_msg to

	init_meld_help_msg () {
		if test -z "$meld_help_msg"
		then
			meld_path="$(git config mergetool.meld.path || echo meld)"
			meld_help_msg=$($meld_path --help 2>&1)
		fi
	}

And call init_meld_help_msg unconditionally here, (and in --auto-merge arm below, maybe other arms in the future).

I'm writing without much thought into this, please take my word with a grain of salt :)

> +}


> +
> +			case "$meld_help_msg" in
> +				*"--output="* | *"[OPTION"???"]"*)

I think Git project prefer aligning case arm with case, IOW, move left 1 TAB.

> +					# old ones mention --output and new ones just say OPTION...
> +					meld_has_output_option=true ;;

It's nice to see this update, good.
The comment is no longer correct, though.
The version 3.20.2 has --output but not OPTIONS.

It's not introduced by your change, but I think it's better to say:

	# All versions that has [OPTIONS???] supports --output

> +				*)
> +					meld_has_output_option=false ;;
> +			esac
> +		fi
> +	fi
> +	# Check whether we should use 'meld --auto-merge ...'
> +	if test -z "${meld_has_auto_merge_option:+set}"
>  	then
> -		: old ones mention --output and new ones just say OPTION...
> -		meld_has_output_option=true
> -	else
> -		meld_has_output_option=false
> +		meld_has_auto_merge_option=$(git config mergetool.meld.hasAutoMerge)
> +		if test "$meld_has_auto_merge_option" = auto

Since we don't canonicallise to bool output of mergetool.meld.hasAutoMerge, I think we would need:

	case "$meld_has_auto_merge_option" in
	[Tt]rue|[Yy]es|[Oo]n)
		meld_has_auto_merge_option=true ;;
	auto)
		: this shenanigan ;;
	esac

But, that's a bit messy. Let's see other's opinions.

> +		then
> +			# testing the "--auto-merge" option only if config is "auto"
> +			if test -z "$meld_help_msg"
> +			then
> +					meld_help_msg="$(get_meld_help_msg)"
> +			fi
> +
> +			case "$meld_help_msg" in
> +				*"--auto-merge"*)
> +					: old ones mention --output and new ones just say OPTION...

This comment doesn't apply here.

> +					meld_has_auto_merge_option=true ;;
> +				*)
> +					meld_has_auto_merge_option=false ;;
> +			esac
> +		fi
>  	fi
>  }
> 
> base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
> --
> gitgitgadget

--
Danh


^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v5] Enable auto-merge for meld to follow the vim-diff beharior
  2020-07-01 22:02             ` lin.sun
@ 2020-07-01 23:06               ` Đoàn Trần Công Danh
  0 siblings, 0 replies; 74+ messages in thread
From: Đoàn Trần Công Danh @ 2020-07-01 23:06 UTC (permalink / raw)
  To: lin.sun; +Cc: 'sunlin via GitGitGadget', git

On 2020-07-02 06:02:27+0800, lin.sun@zoom.us wrote:
> Hi Danh,

Hi Lin,

> 
> I'll push the patch to GitGitGadget so that it's will sending from
> the system mail. Sorry for this noise.

While you're doing it,
do you mind changing hasAutoMerge to useAutoMerge?
I think that name is better :)

c.f: https://lore.kernel.org/git/xmqq7dvndnf0.fsf@gitster.c.googlers.com/

Thanks,

-- 
Danh

^ permalink raw reply	[flat|nested] 74+ messages in thread

* RE: [PATCH v5] Enable auto-merge for meld to follow the vim-diff beharior
  2020-07-01 19:51           ` Junio C Hamano
@ 2020-07-02  0:20             ` lin.sun
  0 siblings, 0 replies; 74+ messages in thread
From: lin.sun @ 2020-07-02  0:20 UTC (permalink / raw)
  To: 'Đoàn Trần Công Danh'
  Cc: 'sunlin via GitGitGadget', git, 'sunlin',
	'Junio C Hamano'

Hi Danh,

> While you're doing it,
> do you mind changing hasAutoMerge to useAutoMerge?
> I think that name is better :)
Okay, no problem, it will be ` useAutoMerge`.

Regards
Lin


^ permalink raw reply	[flat|nested] 74+ messages in thread

* [PATCH v6] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-01  7:06       ` [PATCH v5] " sunlin via GitGitGadget
  2020-07-01  7:23         ` lin.sun
  2020-07-01 14:17         ` Đoàn Trần Công Danh
@ 2020-07-02  0:44         ` sunlin via GitGitGadget
  2020-07-02  2:35           ` lin.sun
                             ` (2 more replies)
  2 siblings, 3 replies; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-07-02  0:44 UTC (permalink / raw)
  To: git; +Cc: sunlin, Lin Sun

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to how
"vimdiff" behavior by telling it to auto-merge parts without conflicts
and highlight the parts with conflicts when configuring
`mergetool.meld.useAutoMerge` with `true`, or `auto` for automatically
detecting the option.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v6
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v6
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v5:

 1:  344817d579 ! 1:  63ee3406d2 Enable auto-merge for meld to follow the vim-diff beharior
     @@ Metadata
      Author: Lin Sun <lin.sun@zoom.us>
      
       ## Commit message ##
     -    Enable auto-merge for meld to follow the vim-diff beharior
     +    Support auto-merge for meld to follow the vim-diff behavior
      
     -    Make the mergetool used with "meld" backend behave similarly to
     -    how "vimdiff" behavior by telling it to auto-merge parts without
     -    conflicts and highlight the parts with conflicts when configuring
     -    `mergetool.meld.hasAutoMerge` with `true`, or `auto` for
     -    automatically detecting the option.
     +    Make the mergetool used with "meld" backend behave similarly to how
     +    "vimdiff" behavior by telling it to auto-merge parts without conflicts
     +    and highlight the parts with conflicts when configuring
     +    `mergetool.meld.useAutoMerge` with `true`, or `auto` for automatically
     +    detecting the option.
      
     +    Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
     +    Helped-by: Junio C Hamano <gitster@pobox.com>
     +    Helped-by: David Aguilar <davvid@gmail.com>
          Signed-off-by: Lin Sun <lin.sun@zoom.us>
      
       ## Documentation/config/mergetool.txt ##
     @@ Documentation/config/mergetool.txt: mergetool.meld.hasOutput::
       	to `true` tells Git to unconditionally use the `--output` option,
       	and `false` avoids using `--output`.
       
     -+mergetool.meld.hasAutoMerge::
     ++mergetool.meld.useAutoMerge::
      +	Older versions of `meld` do not support the `--auto-merge` option.
     -+	Setting `mergetool.meld.hasOutput` to `true` tells Git to
     -+	unconditionally use the `--auto-merge` option, and `false` avoids using
     -+	`--auto-merge`, and `auto` detect whether `meld` supports `--auto-merge`
     -+	by inspecting the output of `meld --help`, otherwise, follow meld's
     -+	default behavior.
     ++	Setting `mergetool.meld.useAutoMerge` to `true` tells Git to
     ++	unconditionally use the `--auto-merge` option with `meld`.  Setting
     ++	this value to `auto` makes git detect whether `--auto-merge` is
     ++	supported and will only use `--auto-merge` when available.  A value
     ++	of `false` avoids using `--auto-merge` altogether, and is the default
     ++	value.
      +
       mergetool.keepBackup::
       	After performing a merge, the original file with conflict markers
     @@ mergetools/meld: diff_cmd () {
      +	check_meld_for_features
      +
      +	option_auto_merge=
     -+	if test "$meld_has_auto_merge_option" = true
     ++	if test "$meld_use_auto_merge_option" = true
       	then
      -		check_meld_for_output_version
      +		option_auto_merge="--auto-merge"
     @@ mergetools/meld: diff_cmd () {
      -	meld_path="$(git config mergetool.meld.path)"
      -	meld_path="${meld_path:-meld}"
      +# Get meld help message
     -+get_meld_help_msg () {
     -+	meld_path="$(git config mergetool.meld.path || echo meld)"
     -+	$meld_path --help 2>&1
     ++init_meld_help_msg () {
     ++	if test -z "${meld_help_msg:+set}"
     ++	then
     ++		meld_path="$(git config mergetool.meld.path || echo meld)"
     ++		meld_help_msg=$($meld_path --help 2>&1)
     ++	fi
      +}
       
      -	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
     @@ mergetools/meld: diff_cmd () {
      -	elif "$meld_path" --help 2>&1 |
      -		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
      +		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
     -+		if test "$meld_has_output_option" = true -o \
     -+			"$meld_has_output_option" = false
     -+		then
     ++		case "$meld_has_output_option" in
     ++		true|false)
      +			: use configured value
     -+		else
     -+			# treat meld_has_output_option as "auto"
     -+			if test -z "$meld_help_msg"
     -+			then
     -+				meld_help_msg="$(get_meld_help_msg)"
     -+			fi
     ++			;;
     ++		*)
     ++			: treat meld_has_output_option as "auto"
     ++			init_meld_help_msg
      +
      +			case "$meld_help_msg" in
     -+				*"--output="* | *"[OPTION"???"]"*)
     -+					# old ones mention --output and new ones just say OPTION...
     -+					meld_has_output_option=true ;;
     -+				*)
     -+					meld_has_output_option=false ;;
     ++			*"--output="* | *'[OPTION...]'*)
     ++				# All version that has [OPTION...] supports --output
     ++				meld_has_output_option=true
     ++				;;
     ++			*)
     ++				meld_has_output_option=false
     ++				;;
      +			esac
     -+		fi
     ++			;;
     ++		esac
      +	fi
      +	# Check whether we should use 'meld --auto-merge ...'
     -+	if test -z "${meld_has_auto_merge_option:+set}"
     ++	if test -z "${meld_use_auto_merge_option:+set}"
       	then
      -		: old ones mention --output and new ones just say OPTION...
      -		meld_has_output_option=true
      -	else
      -		meld_has_output_option=false
     -+		meld_has_auto_merge_option=$(git config mergetool.meld.hasAutoMerge)
     -+		if test "$meld_has_auto_merge_option" = auto
     -+		then
     ++		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
     ++		case "$meld_use_auto_merge_option" in
     ++		[Tt]rue|[Yy]es|[Oo]n|1)
     ++			meld_use_auto_merge_option=true
     ++			;;
     ++		auto)
      +			# testing the "--auto-merge" option only if config is "auto"
     -+			if test -z "$meld_help_msg"
     -+			then
     -+					meld_help_msg="$(get_meld_help_msg)"
     -+			fi
     ++			init_meld_help_msg
      +
      +			case "$meld_help_msg" in
     -+				*"--auto-merge"*)
     -+					: old ones mention --output and new ones just say OPTION...
     -+					meld_has_auto_merge_option=true ;;
     -+				*)
     -+					meld_has_auto_merge_option=false ;;
     ++			*"--auto-merge"*)
     ++				meld_use_auto_merge_option=true
     ++				;;
     ++			*)
     ++				meld_use_auto_merge_option=false
     ++				;;
      +			esac
     -+		fi
     ++			;;
     ++		*)
     ++			meld_use_auto_merge_option=false
     ++			;;
     ++		esac
       	fi
       }


 Documentation/config/mergetool.txt |  9 ++++
 mergetools/meld                    | 80 ++++++++++++++++++++++++------
 2 files changed, 73 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..625ad34230 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,15 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	Older versions of `meld` do not support the `--auto-merge` option.
+	Setting `mergetool.meld.useAutoMerge` to `true` tells Git to
+	unconditionally use the `--auto-merge` option with `meld`.  Setting
+	this value to `auto` makes git detect whether `--auto-merge` is
+	supported and will only use `--auto-merge` when available.  A value
+	of `false` avoids using `--auto-merge` altogether, and is the default
+	value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..5bc03f564a 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,82 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "${meld_help_msg:+set}"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$($meld_path --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "${meld_has_output_option:+set}"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true|false)
+			: use configured value
+			;;
+		*)
+			: treat meld_has_output_option as "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="* | *'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "${meld_use_auto_merge_option:+set}"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
+		case "$meld_use_auto_merge_option" in
+		[Tt]rue|[Yy]es|[Oo]n|1)
+			meld_use_auto_merge_option=true
+			;;
+		auto)
+			# testing the "--auto-merge" option only if config is "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--auto-merge"*)
+				meld_use_auto_merge_option=true
+				;;
+			*)
+				meld_use_auto_merge_option=false
+				;;
+			esac
+			;;
+		*)
+			meld_use_auto_merge_option=false
+			;;
+		esac
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* RE: [PATCH v6] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-02  0:44         ` [PATCH v6] Support auto-merge for meld to follow the vim-diff behavior sunlin via GitGitGadget
@ 2020-07-02  2:35           ` lin.sun
  2020-07-03  1:50           ` Junio C Hamano
  2020-07-03  3:26           ` [PATCH v7] " sunlin via GitGitGadget
  2 siblings, 0 replies; 74+ messages in thread
From: lin.sun @ 2020-07-02  2:35 UTC (permalink / raw)
  To: 'Đoàn Trần Công Danh',
	'Junio C Hamano', 'David Aguilar',
	git, 'sunlin via GitGitGadget'

Hi,

The [PATCH v6] changes to follow comments from Danh, Junio, David. 
Please review again. Thank you all.

https://lore.kernel.org/git/pull.781.v6.git.git.1593650687697.gitgitgadget@gmail.com/

Regards
Lin




^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v6] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-02  0:44         ` [PATCH v6] Support auto-merge for meld to follow the vim-diff behavior sunlin via GitGitGadget
  2020-07-02  2:35           ` lin.sun
@ 2020-07-03  1:50           ` Junio C Hamano
  2020-07-03  3:53             ` lin.sun
  2020-07-03 15:58             ` Đoàn Trần Công Danh
  2020-07-03  3:26           ` [PATCH v7] " sunlin via GitGitGadget
  2 siblings, 2 replies; 74+ messages in thread
From: Junio C Hamano @ 2020-07-03  1:50 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, Lin Sun

"sunlin via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: Lin Sun <lin.sun@zoom.us>
>
> Make the mergetool used with "meld" backend behave similarly to how
> "vimdiff" behavior by telling it to auto-merge parts without conflicts
> and highlight the parts with conflicts when configuring
> `mergetool.meld.useAutoMerge` with `true`, or `auto` for automatically
> detecting the option.
>
> Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
> Helped-by: Junio C Hamano <gitster@pobox.com>
> Helped-by: David Aguilar <davvid@gmail.com>
> Signed-off-by: Lin Sun <lin.sun@zoom.us>
> ---

Thanks.

> +mergetool.meld.useAutoMerge::
> +	Older versions of `meld` do not support the `--auto-merge` option.

I do not mind the above text at all, but I do not think it is the
most important point about this configuration option.  Are the
readers of this manual page, at least the subset of them who are
interested in using the meld backend, expected to know what 'meld'
would do when given (and not given) the `--auto-merge` option?

At least, what meld does with and without `--auto-merge` briefly is
more important, especially if your belief is that it is plausible
that most users would prefer to use it.  Something like (I am not a
`meld` user, so everything I wrote after the first comma ',' in
these two paragraphs may be total rubbish---I am just writing these
as an illustration to show the level of details necessary to help
readers decide if the option is for them)...

    When meld is given `--auto-merge`, a part of the conflicted file
    that was modified only by one side is automatically resolved to
    take that change, and a part that was touched by both sides are
    highlighted for manual conflict resolution.

    Without `--auto-merge` option given, the automatic resolution
    does not happen---all changes in the conflicted file are
    highlighted for manual conflict resolution.

Only after that, telling them "(even though you may want to use the
option all the time) Older versions of `meld` do not support it"
becomes relevant---for users with ancient versions of `meld`, the
option, even if it is desirable, may not be available to them so it
is worth warning them that they should not set it to 'true' blindly
without checking with their version of `meld` first.

> diff --git a/mergetools/meld b/mergetools/meld
> index 7a08470f88..5bc03f564a 100644
> --- a/mergetools/meld
> +++ b/mergetools/meld
> @@ -3,34 +3,82 @@ diff_cmd () {
>  }
>  
>  merge_cmd () {
> +	check_meld_for_features
> +
> +	option_auto_merge=
> +	if test "$meld_use_auto_merge_option" = true
>  	then
> +		option_auto_merge="--auto-merge"
>  	fi
>  
>  	if test "$meld_has_output_option" = true
>  	then
> +		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
>  			"$LOCAL" "$BASE" "$REMOTE"
>  	else
> +		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
>  	fi
>  }

That's straight-forward to follow.  Good.

> +# Get meld help message
> +init_meld_help_msg () {
> +	if test -z "${meld_help_msg:+set}"

I suspect that you copied the pattern 

    if test -z "${var:+set}"

from the original, but it looks rather strange.  "${var:+set}" means
"if $var is set to a non-empty string, give me 'set'; otherwise give
me $var".  And checking if that result is an empty string with "-z"
would mean you can safely write

    if test -z "$var"

no?  If you are "set -u" proofing, you might write "${var-}" instead
of "$var" there, but that does not change the story all that much.

> +	then
> +		meld_path="$(git config mergetool.meld.path || echo meld)"
> +		meld_help_msg=$($meld_path --help 2>&1)
> +	fi
> +}

In any case, the if/then/fi makes sure we'll ask `meld` only once,
which is good.

> +# Check the features and set flags
> +check_meld_for_features () {
> +	# Check whether we should use 'meld --output <file>'
> +	if test -z "${meld_has_output_option:+set}"

Likewise about "test -z ${var:+set}".

So, if we do not know yet, then...

>  	then
> +		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)

We ask "config --bool" and are prepared to see two primary cases, i.e.

> +		case "$meld_has_output_option" in
> +		true|false)
> +			: use configured value

In this case, the user may have configured, so the variable already
has the right value.  Good.

> +			;;
> +		*)
> +			: treat meld_has_output_option as "auto"
> +			init_meld_help_msg

Otherwise, we ask `meld`.

> +			case "$meld_help_msg" in
> +			*"--output="* | *'[OPTION...]'*)
> +				# All version that has [OPTION...] supports --output

Very good comment.

> +				meld_has_output_option=true
> +				;;
> +			*)
> +				meld_has_output_option=false
> +				;;
> +			esac
> +			;;
> +		esac
> +	fi

Nicely done up to this point.

> +	# Check whether we should use 'meld --auto-merge ...'
> +	if test -z "${meld_use_auto_merge_option:+set}"

Likewise about "test -z ${var:+set}".

So, if we do not know yet, then...

>  	then
> +		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
> +		case "$meld_use_auto_merge_option" in
> +		[Tt]rue|[Yy]es|[Oo]n|1)
> +			meld_use_auto_merge_option=true

This is sloppy.  TRUE is also a valid way to spell 'yes'.

    if o=$(git config --bool 2>/dev/null mergetool.meld.useautomerge)
    then
    	meld_use_auto_merge_option=$o
    elif test auto = "$(git config mergetool.meld.useautomerge)"
    then
	... auto detect ...
    else
	meld_use_auto_merge_option=false
    fi

Maybe somebody else has a clever idea to reduce the two calls into
one without breaking correctness, but unfortunately I do not offhand
think of a way to do this with just a single "git config" call.

> +			;;
> +		auto)
> +			# testing the "--auto-merge" option only if config is "auto"
> +			init_meld_help_msg
> +
> +			case "$meld_help_msg" in
> +			*"--auto-merge"*)
> +				meld_use_auto_merge_option=true
> +				;;
> +			*)
> +				meld_use_auto_merge_option=false
> +				;;
> +			esac
> +			;;
> +		*)
> +			meld_use_auto_merge_option=false
> +			;;
> +		esac
>  	fi
>  }

Thanks.

^ permalink raw reply	[flat|nested] 74+ messages in thread

* [PATCH v7] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-02  0:44         ` [PATCH v6] Support auto-merge for meld to follow the vim-diff behavior sunlin via GitGitGadget
  2020-07-02  2:35           ` lin.sun
  2020-07-03  1:50           ` Junio C Hamano
@ 2020-07-03  3:26           ` sunlin via GitGitGadget
  2020-07-03  4:50             ` Junio C Hamano
  2020-07-04  1:16             ` [PATCH v8] " sunlin via GitGitGadget
  2 siblings, 2 replies; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-07-03  3:26 UTC (permalink / raw)
  To: git; +Cc: sunlin, Lin Sun

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to
"vimdiff" by telling it to auto-merge non-conflicting parts and
highlight the conflicting parts when `mergetool.meld.useAutoMerge` is
configured with `true`, or `auto` for detecting the `--auto-merge`
option automatically.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v7
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v7
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v6:

 1:  63ee3406d2 ! 1:  ec2b49b9b8 Support auto-merge for meld to follow the vim-diff behavior
     @@ Metadata
       ## Commit message ##
          Support auto-merge for meld to follow the vim-diff behavior
      
     -    Make the mergetool used with "meld" backend behave similarly to how
     -    "vimdiff" behavior by telling it to auto-merge parts without conflicts
     -    and highlight the parts with conflicts when configuring
     -    `mergetool.meld.useAutoMerge` with `true`, or `auto` for automatically
     -    detecting the option.
     +    Make the mergetool used with "meld" backend behave similarly to
     +    "vimdiff" by telling it to auto-merge non-conflicting parts and
     +    highlight the conflicting parts when `mergetool.meld.useAutoMerge` is
     +    configured with `true`, or `auto` for detecting the `--auto-merge`
     +    option automatically.
      
          Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
          Helped-by: Junio C Hamano <gitster@pobox.com>
     @@ Documentation/config/mergetool.txt: mergetool.meld.hasOutput::
       	and `false` avoids using `--output`.
       
      +mergetool.meld.useAutoMerge::
     -+	Older versions of `meld` do not support the `--auto-merge` option.
     -+	Setting `mergetool.meld.useAutoMerge` to `true` tells Git to
     -+	unconditionally use the `--auto-merge` option with `meld`.  Setting
     -+	this value to `auto` makes git detect whether `--auto-merge` is
     -+	supported and will only use `--auto-merge` when available.  A value
     -+	of `false` avoids using `--auto-merge` altogether, and is the default
     -+	value.
     ++	When the `--auto-merge` is given, meld will merges all non-conflicting
     ++	part automatically, highlight the conflicting part and waiting for user
     ++	decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells Git to
     ++	unconditionally use the `--auto-merge` option with `meld`.  Setting this
     ++	value to `auto` makes git detect whether `--auto-merge` is supported and
     ++	will only use `--auto-merge` when available.  A value of `false` avoids
     ++	using `--auto-merge` altogether, and is the default value.
      +
       mergetool.keepBackup::
       	After performing a merge, the original file with conflict markers
     @@ mergetools/meld: diff_cmd () {
      -	meld_path="${meld_path:-meld}"
      +# Get meld help message
      +init_meld_help_msg () {
     -+	if test -z "${meld_help_msg:+set}"
     ++	if test -z "${meld_help_msg}"
      +	then
      +		meld_path="$(git config mergetool.meld.path || echo meld)"
      +		meld_help_msg=$($meld_path --help 2>&1)
     @@ mergetools/meld: diff_cmd () {
      +# Check the features and set flags
      +check_meld_for_features () {
      +	# Check whether we should use 'meld --output <file>'
     -+	if test -z "${meld_has_output_option:+set}"
     ++	if test -z "${meld_has_output_option}"
       	then
      -		: use configured value
      -	elif "$meld_path" --help 2>&1 |
     @@ mergetools/meld: diff_cmd () {
      +			: use configured value
      +			;;
      +		*)
     -+			: treat meld_has_output_option as "auto"
     ++			: empty or invalid configured value, detecting "--output" automatically
      +			init_meld_help_msg
      +
      +			case "$meld_help_msg" in
     @@ mergetools/meld: diff_cmd () {
      +		esac
      +	fi
      +	# Check whether we should use 'meld --auto-merge ...'
     -+	if test -z "${meld_use_auto_merge_option:+set}"
     ++	if test -z "${meld_use_auto_merge_option}"
       	then
      -		: old ones mention --output and new ones just say OPTION...
      -		meld_has_output_option=true
      -	else
      -		meld_has_output_option=false
      +		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
     -+		case "$meld_use_auto_merge_option" in
     -+		[Tt]rue|[Yy]es|[Oo]n|1)
     ++		case "${meld_use_auto_merge_option,,*}" in
     ++		true|yes|on|1)
      +			meld_use_auto_merge_option=true
      +			;;
      +		auto)


 Documentation/config/mergetool.txt |  9 ++++
 mergetools/meld                    | 80 ++++++++++++++++++++++++------
 2 files changed, 73 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..b7657734a0 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,15 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	When the `--auto-merge` is given, meld will merges all non-conflicting
+	part automatically, highlight the conflicting part and waiting for user
+	decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells Git to
+	unconditionally use the `--auto-merge` option with `meld`.  Setting this
+	value to `auto` makes git detect whether `--auto-merge` is supported and
+	will only use `--auto-merge` when available.  A value of `false` avoids
+	using `--auto-merge` altogether, and is the default value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..5e6b50d480 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,82 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "${meld_help_msg}"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$($meld_path --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "${meld_has_output_option}"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true|false)
+			: use configured value
+			;;
+		*)
+			: empty or invalid configured value, detecting "--output" automatically
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="* | *'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "${meld_use_auto_merge_option}"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
+		case "${meld_use_auto_merge_option,,*}" in
+		true|yes|on|1)
+			meld_use_auto_merge_option=true
+			;;
+		auto)
+			# testing the "--auto-merge" option only if config is "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--auto-merge"*)
+				meld_use_auto_merge_option=true
+				;;
+			*)
+				meld_use_auto_merge_option=false
+				;;
+			esac
+			;;
+		*)
+			meld_use_auto_merge_option=false
+			;;
+		esac
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* RE: [PATCH v6] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-03  1:50           ` Junio C Hamano
@ 2020-07-03  3:53             ` lin.sun
  2020-07-03 15:58             ` Đoàn Trần Công Danh
  1 sibling, 0 replies; 74+ messages in thread
From: lin.sun @ 2020-07-03  3:53 UTC (permalink / raw)
  To: 'Junio C Hamano', 'sunlin via GitGitGadget'
  Cc: git, 'sunlin'

Hi Junio,

Thank you for your comments, and the changes are made to follow your suggestion. 
In the [PATCH v7], the ":+set" is removed, and the "${var,,*}" is used to convert 
configuration to lower-case, it won't call git config twice for getting `useAutoMerge`.

Please review again, thank you.
https://lore.kernel.org/git/pull.781.v7.git.git.1593746805771.gitgitgadget@gmail.com

Regards
Lin



^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v7] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-03  3:26           ` [PATCH v7] " sunlin via GitGitGadget
@ 2020-07-03  4:50             ` Junio C Hamano
  2020-07-04  1:18               ` lin.sun
  2020-07-04  1:16             ` [PATCH v8] " sunlin via GitGitGadget
  1 sibling, 1 reply; 74+ messages in thread
From: Junio C Hamano @ 2020-07-03  4:50 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, Lin Sun

"sunlin via GitGitGadget" <gitgitgadget@gmail.com> writes:

>      ++	When the `--auto-merge` is given, meld will merges all non-conflicting

Grammo: "will merges"???

>      ++	part automatically, highlight the conflicting part and waiting for user
>      ++	decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells Git to
>      ++	unconditionally use the `--auto-merge` option with `meld`.  Setting this
>      ++	value to `auto` makes git detect whether `--auto-merge` is supported and
>      ++	will only use `--auto-merge` when available.  A value of `false` avoids
>      ++	using `--auto-merge` altogether, and is the default value.
>       +
>        mergetool.keepBackup::
>        	After performing a merge, the original file with conflict markers
>      @@ mergetools/meld: diff_cmd () {
>       -	meld_path="${meld_path:-meld}"
>       +# Get meld help message
>       +init_meld_help_msg () {
>      -+	if test -z "${meld_help_msg:+set}"
>      ++	if test -z "${meld_help_msg}"

Now we do not use the :+ magic, there is no reason to use extra
{brace} around the variable name.  Just sticking to the normal
"$meld_help_msg" would help the readers to hint that there is no
strange thing going on.

>      ++		case "${meld_use_auto_merge_option,,*}" in

DON'T. 

The ${parameter,,pattern} expansion is one of the non-portable
bash-isms we do not use in our codebase.  Use of it won't fix the
correctness problem coming from not using --bool anyway, because ...

>      ++		true|yes|on|1)

... any numeric value that is not 0 is taken as true.  Writing 1
here does not help.



^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v6] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-03  1:50           ` Junio C Hamano
  2020-07-03  3:53             ` lin.sun
@ 2020-07-03 15:58             ` Đoàn Trần Công Danh
  2020-07-06  6:23               ` Junio C Hamano
  1 sibling, 1 reply; 74+ messages in thread
From: Đoàn Trần Công Danh @ 2020-07-03 15:58 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: sunlin via GitGitGadget, git, sunlin, Lin Sun

On 2020-07-02 18:50:15-0700, Junio C Hamano <gitster@pobox.com> wrote:
> So, if we do not know yet, then...
> 
> >  	then
> > +		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
> > +		case "$meld_use_auto_merge_option" in
> > +		[Tt]rue|[Yy]es|[Oo]n|1)
> > +			meld_use_auto_merge_option=true
> 
> This is sloppy.  TRUE is also a valid way to spell 'yes'.
> 
>     if o=$(git config --bool 2>/dev/null mergetool.meld.useautomerge)
>     then
>     	meld_use_auto_merge_option=$o
>     elif test auto = "$(git config mergetool.meld.useautomerge)"
>     then
> 	... auto detect ...
>     else
> 	meld_use_auto_merge_option=false
>     fi

Something like this should work if we don't write anything to stderr,
except the complain from git-config:

> fatal: bad numeric config value 'auto' for 'mergetool.meld.useautomerge': invalid unit

	if o=$(git config --bool mergetool.meld.useautomerge 2>&1)
	then
		meld_use_auto_merge_option=$o
	else
		case "$o" in
		*"'auto'"*) ... auto detect ... ;;
		esac
	fi

This code block is likely broken if git-config is chatty (trace).
I don't know if we have a reliable ways to tell Git to not chatty,
though.


-- 
Danh

^ permalink raw reply	[flat|nested] 74+ messages in thread

* [PATCH v8] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-03  3:26           ` [PATCH v7] " sunlin via GitGitGadget
  2020-07-03  4:50             ` Junio C Hamano
@ 2020-07-04  1:16             ` sunlin via GitGitGadget
  2020-07-06  2:27               ` [PATCH v9] " sunlin via GitGitGadget
  1 sibling, 1 reply; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-07-04  1:16 UTC (permalink / raw)
  To: git; +Cc: sunlin, Lin Sun

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
telling it to auto-merge non-conflicting parts and highlight the conflicting
parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
for detecting the `--auto-merge` option automatically.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v8
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v8
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v7:

 1:  ec2b49b9b8 ! 1:  f28a32c66e Support auto-merge for meld to follow the vim-diff behavior
     @@ Metadata
       ## Commit message ##
          Support auto-merge for meld to follow the vim-diff behavior
      
     -    Make the mergetool used with "meld" backend behave similarly to
     -    "vimdiff" by telling it to auto-merge non-conflicting parts and
     -    highlight the conflicting parts when `mergetool.meld.useAutoMerge` is
     -    configured with `true`, or `auto` for detecting the `--auto-merge`
     -    option automatically.
     +    Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
     +    telling it to auto-merge non-conflicting parts and highlight the conflicting
     +    parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
     +    for detecting the `--auto-merge` option automatically.
      
          Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
          Helped-by: Junio C Hamano <gitster@pobox.com>
     @@ Documentation/config/mergetool.txt: mergetool.meld.hasOutput::
       	and `false` avoids using `--output`.
       
      +mergetool.meld.useAutoMerge::
     -+	When the `--auto-merge` is given, meld will merges all non-conflicting
     -+	part automatically, highlight the conflicting part and waiting for user
     -+	decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells Git to
     -+	unconditionally use the `--auto-merge` option with `meld`.  Setting this
     -+	value to `auto` makes git detect whether `--auto-merge` is supported and
     -+	will only use `--auto-merge` when available.  A value of `false` avoids
     -+	using `--auto-merge` altogether, and is the default value.
     ++	When the `--auto-merge` is given, meld will merge all non-conflicting
     ++	parts automatically, highlight the conflicting parts and waiting for
     ++	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
     ++	Git to unconditionally use the `--auto-merge` option with `meld`.
     ++	Setting this value to `auto` makes git detect whether `--auto-merge`
     ++	is supported and will only use `--auto-merge` when available.  A
     ++	value of `false` avoids using `--auto-merge` altogether, and is the
     ++	default value.
      +
       mergetool.keepBackup::
       	After performing a merge, the original file with conflict markers
     @@ mergetools/meld: diff_cmd () {
      -	meld_path="${meld_path:-meld}"
      +# Get meld help message
      +init_meld_help_msg () {
     -+	if test -z "${meld_help_msg}"
     ++	if test -z "$meld_help_msg"
      +	then
      +		meld_path="$(git config mergetool.meld.path || echo meld)"
      +		meld_help_msg=$($meld_path --help 2>&1)
     @@ mergetools/meld: diff_cmd () {
      +# Check the features and set flags
      +check_meld_for_features () {
      +	# Check whether we should use 'meld --output <file>'
     -+	if test -z "${meld_has_output_option}"
     ++	if test -z "$meld_has_output_option"
       	then
      -		: use configured value
      -	elif "$meld_path" --help 2>&1 |
     @@ mergetools/meld: diff_cmd () {
      +		esac
      +	fi
      +	# Check whether we should use 'meld --auto-merge ...'
     -+	if test -z "${meld_use_auto_merge_option}"
     ++	if test -z "$meld_use_auto_merge_option"
       	then
      -		: old ones mention --output and new ones just say OPTION...
      -		meld_has_output_option=true
      -	else
      -		meld_has_output_option=false
      +		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
     -+		case "${meld_use_auto_merge_option,,*}" in
     -+		true|yes|on|1)
     -+			meld_use_auto_merge_option=true
     -+			;;
     -+		auto)
     -+			# testing the "--auto-merge" option only if config is "auto"
     -+			init_meld_help_msg
     ++		if test -z "$meld_use_auto_merge_option"
     ++		then
     ++			meld_use_auto_merge_option=false
     ++		else
     ++			bool_value=$(git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
     ++			if test -n "$bool_value"
     ++			then
     ++				meld_use_auto_merge_option="$bool_value"
     ++			elif test "$meld_use_auto_merge_option" = "auto" \
     ++				|| test "$meld_use_auto_merge_option" = "Auto"
     ++			then
     ++				# testing the "--auto-merge" option only if config is "[Aa]uto"
     ++				init_meld_help_msg
      +
     -+			case "$meld_help_msg" in
     -+			*"--auto-merge"*)
     -+				meld_use_auto_merge_option=true
     -+				;;
     -+			*)
     ++				case "$meld_help_msg" in
     ++				*"--auto-merge"*)
     ++					meld_use_auto_merge_option=true
     ++					;;
     ++				*)
     ++					meld_use_auto_merge_option=false
     ++					;;
     ++				esac
     ++			else
      +				meld_use_auto_merge_option=false
     -+				;;
     -+			esac
     -+			;;
     -+		*)
     -+			meld_use_auto_merge_option=false
     -+			;;
     -+		esac
     ++			fi
     ++		fi
       	fi
       }


 Documentation/config/mergetool.txt | 10 ++++
 mergetools/meld                    | 85 ++++++++++++++++++++++++------
 2 files changed, 79 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..031c78aa95 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	When the `--auto-merge` is given, meld will merge all non-conflicting
+	parts automatically, highlight the conflicting parts and waiting for
+	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
+	Git to unconditionally use the `--auto-merge` option with `meld`.
+	Setting this value to `auto` makes git detect whether `--auto-merge`
+	is supported and will only use `--auto-merge` when available.  A
+	value of `false` avoids using `--auto-merge` altogether, and is the
+	default value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..7b9d917f7a 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,87 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "$meld_help_msg"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$($meld_path --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "$meld_has_output_option"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true|false)
+			: use configured value
+			;;
+		*)
+			: empty or invalid configured value, detecting "--output" automatically
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="* | *'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "$meld_use_auto_merge_option"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
+		if test -z "$meld_use_auto_merge_option"
+		then
+			meld_use_auto_merge_option=false
+		else
+			bool_value=$(git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
+			if test -n "$bool_value"
+			then
+				meld_use_auto_merge_option="$bool_value"
+			elif test "$meld_use_auto_merge_option" = "auto" \
+				|| test "$meld_use_auto_merge_option" = "Auto"
+			then
+				# testing the "--auto-merge" option only if config is "[Aa]uto"
+				init_meld_help_msg
+
+				case "$meld_help_msg" in
+				*"--auto-merge"*)
+					meld_use_auto_merge_option=true
+					;;
+				*)
+					meld_use_auto_merge_option=false
+					;;
+				esac
+			else
+				meld_use_auto_merge_option=false
+			fi
+		fi
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* RE: [PATCH v7] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-03  4:50             ` Junio C Hamano
@ 2020-07-04  1:18               ` lin.sun
  2020-07-06  2:36                 ` lin.sun
  0 siblings, 1 reply; 74+ messages in thread
From: lin.sun @ 2020-07-04  1:18 UTC (permalink / raw)
  To: 'Junio C Hamano', 'sunlin via GitGitGadget'
  Cc: git, 'sunlin'

Hi Junio, Doah,

To follow your comments, the new [PATCH v8] is uploaded, try to reduce calling `git config --bool`.
Please review again. Thank you.
https://lore.kernel.org/git/pull.781.v8.git.git.1593825400699.gitgitgadget@gmail.com/

B.R.
Lin


^ permalink raw reply	[flat|nested] 74+ messages in thread

* [PATCH v9] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-04  1:16             ` [PATCH v8] " sunlin via GitGitGadget
@ 2020-07-06  2:27               ` sunlin via GitGitGadget
  2020-07-06 22:31                 ` Junio C Hamano
  2020-07-07  6:17                 ` [PATCH v10] " sunlin via GitGitGadget
  0 siblings, 2 replies; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-07-06  2:27 UTC (permalink / raw)
  To: git; +Cc: sunlin, Lin Sun

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
telling it to auto-merge non-conflicting parts and highlight the conflicting
parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
for detecting the `--auto-merge` option automatically.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v9
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v9
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v8:

 1:  f28a32c66e ! 1:  95586fb2c2 Support auto-merge for meld to follow the vim-diff behavior
     @@ mergetools/meld: diff_cmd () {
      -	else
      -		meld_has_output_option=false
      +		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
     -+		if test -z "$meld_use_auto_merge_option"
     -+		then
     ++		case "$meld_use_auto_merge_option" in
     ++		"")
      +			meld_use_auto_merge_option=false
     -+		else
     ++			;;
     ++		[Aa]uto)
     ++			# testing the "--auto-merge" option only if config is "[Aa]uto"
     ++			init_meld_help_msg
     ++
     ++			case "$meld_help_msg" in
     ++			*"--auto-merge"*)
     ++				meld_use_auto_merge_option=true
     ++				;;
     ++			*)
     ++				meld_use_auto_merge_option=false
     ++				;;
     ++			esac
     ++			;;
     ++		*)
      +			bool_value=$(git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
      +			if test -n "$bool_value"
      +			then
      +				meld_use_auto_merge_option="$bool_value"
     -+			elif test "$meld_use_auto_merge_option" = "auto" \
     -+				|| test "$meld_use_auto_merge_option" = "Auto"
     -+			then
     -+				# testing the "--auto-merge" option only if config is "[Aa]uto"
     -+				init_meld_help_msg
     -+
     -+				case "$meld_help_msg" in
     -+				*"--auto-merge"*)
     -+					meld_use_auto_merge_option=true
     -+					;;
     -+				*)
     -+					meld_use_auto_merge_option=false
     -+					;;
     -+				esac
      +			else
      +				meld_use_auto_merge_option=false
      +			fi
     -+		fi
     ++			;;
     ++		esac
       	fi
       }


 Documentation/config/mergetool.txt | 10 ++++
 mergetools/meld                    | 86 ++++++++++++++++++++++++------
 2 files changed, 80 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..031c78aa95 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	When the `--auto-merge` is given, meld will merge all non-conflicting
+	parts automatically, highlight the conflicting parts and waiting for
+	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
+	Git to unconditionally use the `--auto-merge` option with `meld`.
+	Setting this value to `auto` makes git detect whether `--auto-merge`
+	is supported and will only use `--auto-merge` when available.  A
+	value of `false` avoids using `--auto-merge` altogether, and is the
+	default value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..ba6607a088 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,88 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "$meld_help_msg"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$($meld_path --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "$meld_has_output_option"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true|false)
+			: use configured value
+			;;
+		*)
+			: empty or invalid configured value, detecting "--output" automatically
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="* | *'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "$meld_use_auto_merge_option"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
+		case "$meld_use_auto_merge_option" in
+		"")
+			meld_use_auto_merge_option=false
+			;;
+		[Aa]uto)
+			# testing the "--auto-merge" option only if config is "[Aa]uto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--auto-merge"*)
+				meld_use_auto_merge_option=true
+				;;
+			*)
+				meld_use_auto_merge_option=false
+				;;
+			esac
+			;;
+		*)
+			bool_value=$(git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
+			if test -n "$bool_value"
+			then
+				meld_use_auto_merge_option="$bool_value"
+			else
+				meld_use_auto_merge_option=false
+			fi
+			;;
+		esac
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* RE: [PATCH v7] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-04  1:18               ` lin.sun
@ 2020-07-06  2:36                 ` lin.sun
  0 siblings, 0 replies; 74+ messages in thread
From: lin.sun @ 2020-07-06  2:36 UTC (permalink / raw)
  To: 'Junio C Hamano',
	'Đoàn Trần Công Danh',
	'sunlin via GitGitGadget'
  Cc: git

Hi Junio, Doah,

>To follow your comments, the new [PATCH v8] is uploaded, try to reduce calling `git config --bool`.
>Please review again. Thank you.
>https://lore.kernel.org/git/pull.781.v8.git.git.1593825400699.gitgitgadget@gmail.com/

Please review the [PATCH v9] instead, it will calling the `git config --bool ...` until last moment.
https://lore.kernel.org/git/pull.781.v9.git.git.1594002423685.gitgitgadget@gmail.com/

B.R.
Lin



^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v6] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-03 15:58             ` Đoàn Trần Công Danh
@ 2020-07-06  6:23               ` Junio C Hamano
  0 siblings, 0 replies; 74+ messages in thread
From: Junio C Hamano @ 2020-07-06  6:23 UTC (permalink / raw)
  To: Đoàn Trần Công Danh
  Cc: sunlin via GitGitGadget, git, sunlin, Lin Sun

Đoàn Trần Công Danh  <congdanhqx@gmail.com> writes:

>>     if o=$(git config --bool 2>/dev/null mergetool.meld.useautomerge)
>>     then
>>     	meld_use_auto_merge_option=$o
>>     elif test auto = "$(git config mergetool.meld.useautomerge)"
>>     then
>> 	... auto detect ...
>>     else
>> 	meld_use_auto_merge_option=false
>>     fi
>
> Something like this should work if we don't write anything to stderr,
> except the complain from git-config:

I did say "Maybe somebody else has a clever idea to reduce the two
calls into one without breaking correctness" but the stress is on
the "without breaking correctness" part, not on "clever" part.  Two
"git config" call may be more expensive than one call, but at least
the resulting code is readable.

If we really wanted to, I think the way to go would actually be to
teach "git config" new options that allows us scripters to express
what we can already say internally like "maybe bool", "bool or int",
etc.  IOW, "git config --bool-or-string" that does something like

int git_config_bool_or_str(const char **dest,
			   const char *name, const char *value);
{
	int v = git_parse_maybe_bool_text(value);
	if (0 <= v)
        	*dest = v ? "true" : "false";
	else                
        	*dest = value;
	return 0;
}

may help normalizing various ways to spell boolean plus non-boolean
strings into canonical form, so that you can say

	if o=$(git config --bool-or-string mergetool.meld.useautomerge)"
	then
		case "$o" in
		true | false)
		        meld_use_auto_merge_option=$o # as specified
			;;
		auto)
			... auto detect ...
			;;
		esac
	else
		meld_use_auto_merge_option=false
	fi
	
But I think two calls to config is good enough and it certainly is
not worth making the script ugly with hackeries and/or manually
enumerating all the possible shapes of trues and falses.

Thanks.

^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v9] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-06  2:27               ` [PATCH v9] " sunlin via GitGitGadget
@ 2020-07-06 22:31                 ` Junio C Hamano
  2020-07-07  6:34                   ` lin.sun
  2020-07-07  6:17                 ` [PATCH v10] " sunlin via GitGitGadget
  1 sibling, 1 reply; 74+ messages in thread
From: Junio C Hamano @ 2020-07-06 22:31 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, Lin Sun

"sunlin via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: Lin Sun <lin.sun@zoom.us>
>
> Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
> telling it to auto-merge non-conflicting parts and highlight the conflicting
> parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
> for detecting the `--auto-merge` option automatically.

This reads well.

> +mergetool.meld.useAutoMerge::
> +	When the `--auto-merge` is given, meld will merge all non-conflicting
> +	parts automatically, highlight the conflicting parts and waiting for

s/waiting/wait/, I presume, i.e. "merge", "highlight" and "wait" all 
share the "meld will" that starts the sentence.

> +	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
> +	Git to unconditionally use the `--auto-merge` option with `meld`.
> +	Setting this value to `auto` makes git detect whether `--auto-merge`
> +	is supported and will only use `--auto-merge` when available.  A
> +	value of `false` avoids using `--auto-merge` altogether, and is the
> +	default value.

Other than that, this reads well, too.

> diff --git a/mergetools/meld b/mergetools/meld
> index 7a08470f88..ba6607a088 100644
> --- a/mergetools/meld
> +++ b/mergetools/meld
> @@ -3,34 +3,88 @@ diff_cmd () {
>  }
>  
>  merge_cmd () {
> +	check_meld_for_features
> +
> +	option_auto_merge=
> +	if test "$meld_use_auto_merge_option" = true
>  	then
> +		option_auto_merge="--auto-merge"
>  	fi
>  
>  	if test "$meld_has_output_option" = true
>  	then
> +		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
>  			"$LOCAL" "$BASE" "$REMOTE"
>  	else
> +		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
>  	fi
>  }

OK.

> +# Get meld help message
> +init_meld_help_msg () {
> +	if test -z "$meld_help_msg"
> +	then
> +		meld_path="$(git config mergetool.meld.path || echo meld)"
> +		meld_help_msg=$($meld_path --help 2>&1)
> +	fi
> +}

OK.

> +# Check the features and set flags
> +check_meld_for_features () {
> +	# Check whether we should use 'meld --output <file>'
> +	if test -z "$meld_has_output_option"
>  	then
> +		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
> +		case "$meld_has_output_option" in
> +		true|false)
> +			: use configured value
> +			;;

I think the assignment before "case" would have yielded a non-zero
exist status, so that would be another way to tell if we got a
proper boolean value, but this is also good.

> +		*)
> +			: empty or invalid configured value, detecting "--output" automatically
> +			init_meld_help_msg
> +
> +			case "$meld_help_msg" in
> +			*"--output="* | *'[OPTION...]'*)
> +				# All version that has [OPTION...] supports --output
> +				meld_has_output_option=true
> +				;;
> +			*)
> +				meld_has_output_option=false
> +				;;
> +			esac
> +			;;

OK.

> +		esac
> +	fi
> +	# Check whether we should use 'meld --auto-merge ...'
> +	if test -z "$meld_use_auto_merge_option"
>  	then
> +		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
> +		case "$meld_use_auto_merge_option" in
> +		"")
> +			meld_use_auto_merge_option=false

This is wrong, isn't it?  I have

	[rerere] enabled

in my .git/config and I'd certainly get an empty string if you ask
about it in a non-bool context:

    $ o=$(git config --bool rerere.enabled); echo $o
    true
    $ o=$(git config rerere.enabled); echo $o

    $    

In short, I think you can just drop this test for an empty string here.

> +			;;
> +		[Aa]uto)

Does any other configuration variable that takes "auto" take "Auto",
"AUTO", etc. as syonyms?  It's not like we said "you must create a
file whose name is auto to trigger this feature" and some people
live on a case insensitive filesystem that may make it impossible
for them to do so, so I do not see much point in doing this.

> +			# testing the "--auto-merge" option only if config is "[Aa]uto"
> +			init_meld_help_msg
> +
> +			case "$meld_help_msg" in
> +			*"--auto-merge"*)
> +				meld_use_auto_merge_option=true
> +				;;
> +			*)
> +				meld_use_auto_merge_option=false
> +				;;
> +			esac

I didn't notice this until now, but for "--auto-merge", the "if your
meld is new enough, the option name may not appear and you would
only see [OPTION...]" rule we had for the "--output" does not apply?

I am not a meld user, and "yes, my code is correct" is a perfectly
good answer (in other word, the above question is NOT a rhetorical
one that points out an error in the code being reviewed).

> +			;;
> +		*)
> +			bool_value=$(git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
> +			if test -n "$bool_value"
> +			then
> +				meld_use_auto_merge_option="$bool_value"
> +			else
> +				meld_use_auto_merge_option=false
> +			fi
> +			;;

Perhaps the whole thing is easier to read if it is structured more
like so:

	varname=mergetool.meld.useAutoMerge
	if meld_use_auto_merge_option=$(git config --bool "$varname" 2>/dev/null)
	then
        	: happy
	else
                # not a boolean.  Is it 'auto'?
		val=$(git config "$varname")
                case "$val" in
                auto)
                        ;;
                *)
                        die "unrecognized value '$val' for $varname"
                        ;;;
                esac
                ... here we auto detect ...
	fi

Thanks.

^ permalink raw reply	[flat|nested] 74+ messages in thread

* [PATCH v10] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-06  2:27               ` [PATCH v9] " sunlin via GitGitGadget
  2020-07-06 22:31                 ` Junio C Hamano
@ 2020-07-07  6:17                 ` sunlin via GitGitGadget
  2020-07-07  6:25                   ` Junio C Hamano
  2020-07-07  7:13                   ` [PATCH v11] " sunlin via GitGitGadget
  1 sibling, 2 replies; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-07-07  6:17 UTC (permalink / raw)
  To: git; +Cc: sunlin, Lin Sun

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
telling it to auto-merge non-conflicting parts and highlight the conflicting
parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
for detecting the `--auto-merge` option automatically.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v10
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v10
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v9:

 1:  95586fb2c2 ! 1:  a4f1b8c2fa Support auto-merge for meld to follow the vim-diff behavior
     @@ Commit message
          for detecting the `--auto-merge` option automatically.
      
          Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
     -    Helped-by: Junio C Hamano <gitster@pobox.com>
          Helped-by: David Aguilar <davvid@gmail.com>
          Signed-off-by: Lin Sun <lin.sun@zoom.us>
     +    Signed-off-by: Junio C Hamano <gitster@pobox.com>
      
       ## Documentation/config/mergetool.txt ##
      @@ Documentation/config/mergetool.txt: mergetool.meld.hasOutput::
     @@ Documentation/config/mergetool.txt: mergetool.meld.hasOutput::
       
      +mergetool.meld.useAutoMerge::
      +	When the `--auto-merge` is given, meld will merge all non-conflicting
     -+	parts automatically, highlight the conflicting parts and waiting for
     ++	parts automatically, highlight the conflicting parts and wait for
      +	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
      +	Git to unconditionally use the `--auto-merge` option with `meld`.
      +	Setting this value to `auto` makes git detect whether `--auto-merge`
     @@ mergetools/meld: diff_cmd () {
      +		"")
      +			meld_use_auto_merge_option=false
      +			;;
     -+		[Aa]uto)
     -+			# testing the "--auto-merge" option only if config is "[Aa]uto"
     ++		[Tt]ure|TRUE)
     ++			meld_use_auto_merge_option=true
     ++			;;
     ++		[Ff]alse|FALSE)
     ++			meld_use_auto_merge_option=false
     ++			;;
     ++		[Aa]uto|AUTO)
     ++			# testing the "--auto-merge" option only if config is "auto"
      +			init_meld_help_msg
      +
      +			case "$meld_help_msg" in
     @@ mergetools/meld: diff_cmd () {
      +			esac
      +			;;
      +		*)
     ++			# try detect boolean for 'on'||'yes'||numberic value
      +			bool_value=$(git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
      +			if test -n "$bool_value"
      +			then


 Documentation/config/mergetool.txt | 10 ++++
 mergetools/meld                    | 93 +++++++++++++++++++++++++-----
 2 files changed, 87 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..16a27443a3 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	When the `--auto-merge` is given, meld will merge all non-conflicting
+	parts automatically, highlight the conflicting parts and wait for
+	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
+	Git to unconditionally use the `--auto-merge` option with `meld`.
+	Setting this value to `auto` makes git detect whether `--auto-merge`
+	is supported and will only use `--auto-merge` when available.  A
+	value of `false` avoids using `--auto-merge` altogether, and is the
+	default value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..0250c1554a 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,95 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "$meld_help_msg"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$($meld_path --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "$meld_has_output_option"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true|false)
+			: use configured value
+			;;
+		*)
+			: empty or invalid configured value, detecting "--output" automatically
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="* | *'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "$meld_use_auto_merge_option"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
+		case "$meld_use_auto_merge_option" in
+		"")
+			meld_use_auto_merge_option=false
+			;;
+		[Tt]ure|TRUE)
+			meld_use_auto_merge_option=true
+			;;
+		[Ff]alse|FALSE)
+			meld_use_auto_merge_option=false
+			;;
+		[Aa]uto|AUTO)
+			# testing the "--auto-merge" option only if config is "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--auto-merge"*)
+				meld_use_auto_merge_option=true
+				;;
+			*)
+				meld_use_auto_merge_option=false
+				;;
+			esac
+			;;
+		*)
+			# try detect boolean for 'on'||'yes'||numberic value
+			bool_value=$(git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
+			if test -n "$bool_value"
+			then
+				meld_use_auto_merge_option="$bool_value"
+			else
+				meld_use_auto_merge_option=false
+			fi
+			;;
+		esac
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* Re: [PATCH v10] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-07  6:17                 ` [PATCH v10] " sunlin via GitGitGadget
@ 2020-07-07  6:25                   ` Junio C Hamano
  2020-07-07  6:38                     ` lin.sun
  2020-07-07  7:13                   ` [PATCH v11] " sunlin via GitGitGadget
  1 sibling, 1 reply; 74+ messages in thread
From: Junio C Hamano @ 2020-07-07  6:25 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, Lin Sun

"sunlin via GitGitGadget" <gitgitgadget@gmail.com> writes:

> +		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
> +		case "$meld_use_auto_merge_option" in
> +		"")
> +			meld_use_auto_merge_option=false
> +			;;

I somehow thought that I already pointed out that this is wrong,
didn't I?  You cannot tell between a "[section] var" (which is
"true") and not having any "[section] var = val" (which I think you
are trying to treat as "not configured---do not use") from the
output of "git config section.var".

Perhaps our mails crossed?

> +		[Tt]ure|TRUE)
> +			meld_use_auto_merge_option=true
> +			;;
> +		[Ff]alse|FALSE)
> +			meld_use_auto_merge_option=false
> +			;;

These are probably premature optimizations.

> +		[Aa]uto|AUTO)

Sigh.  I somehow thought that I already said we shouldn't do this
"aCCEpt AnY CaSES" unless all other variables that take 'auto' take
it case insensitively.

> +			# testing the "--auto-merge" option only if config is "auto"
> +			init_meld_help_msg
> +
> +			case "$meld_help_msg" in
> +			*"--auto-merge"*)
> +				meld_use_auto_merge_option=true
> +				;;
> +			*)
> +				meld_use_auto_merge_option=false
> +				;;
> +			esac
> +			;;
> +		*)
> +			# try detect boolean for 'on'||'yes'||numberic value
> +			bool_value=$(git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
> +			if test -n "$bool_value"
> +			then
> +				meld_use_auto_merge_option="$bool_value"
> +			else
> +				meld_use_auto_merge_option=false

I think this case (i.e. set to a non-bool value, and we do not
recognise because it is not 'auto') should be flagged as an error,
instead of treated as a silent "do not use", as it would leave the
user scratching his or her head without realizing that there is a
typo in the configuration file.

> +			fi
> +			;;
> +		esac
>  	fi
>  }
>
> base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17

^ permalink raw reply	[flat|nested] 74+ messages in thread

* RE: [PATCH v9] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-06 22:31                 ` Junio C Hamano
@ 2020-07-07  6:34                   ` lin.sun
  2020-07-07 16:43                     ` Junio C Hamano
  0 siblings, 1 reply; 74+ messages in thread
From: lin.sun @ 2020-07-07  6:34 UTC (permalink / raw)
  To: 'Junio C Hamano', 'sunlin via GitGitGadget'
  Cc: git, 'sunlin'

Hi Junio,

Thank you for your comments, and I made the changes in [PATH v10].
For `git config --bool ...`, with a `=` appending to the rerere.enabled will get reverse result, here are the commands.
$ echo [rerere] enabled >> .git/config
$ git config --bool rerere.enabled
true
$ echo [rerere] enabled = >> .git/config
$ git config --bool rerere.enabled
false

So in [PATH v10], it still try get the string value first, then detecting the ""(empty)/true/false/auto. 
That will cover most cases with one `git config...` calling for useAutoMerge is not configured or is configured properly.
Otherwise, it will try call `git config --bool ...` for checking more boolean configuration values.

Please review the [PATH v10], thank you.
https://lore.kernel.org/git/pull.781.v10.git.git.1594102679750.gitgitgadget@gmail.com/

Regards
Lin


^ permalink raw reply	[flat|nested] 74+ messages in thread

* RE: [PATCH v10] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-07  6:25                   ` Junio C Hamano
@ 2020-07-07  6:38                     ` lin.sun
  2020-07-07  6:44                       ` lin.sun
  0 siblings, 1 reply; 74+ messages in thread
From: lin.sun @ 2020-07-07  6:38 UTC (permalink / raw)
  To: 'Junio C Hamano', 'sunlin via GitGitGadget'
  Cc: git, 'sunlin'

Hi Junio,

It seems our mails crossed. I'll read your comments in this mail and reply you later.

Lin

-----Original Message-----
From: Junio C Hamano <gitster@pobox.com> 
Sent: Tuesday, July 7, 2020 14:26
To: sunlin via GitGitGadget <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org; sunlin <sunlin7@yahoo.com>; Lin Sun <lin.sun@zoom.us>
Subject: Re: [PATCH v10] Support auto-merge for meld to follow the vim-diff behavior

"sunlin via GitGitGadget" <gitgitgadget@gmail.com> writes:

> +		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
> +		case "$meld_use_auto_merge_option" in
> +		"")
> +			meld_use_auto_merge_option=false
> +			;;

I somehow thought that I already pointed out that this is wrong, didn't I?  You cannot tell between a "[section] var" (which is
"true") and not having any "[section] var = val" (which I think you are trying to treat as "not configured---do not use") from the output of "git config section.var".

Perhaps our mails crossed?

> +		[Tt]ure|TRUE)
> +			meld_use_auto_merge_option=true
> +			;;
> +		[Ff]alse|FALSE)
> +			meld_use_auto_merge_option=false
> +			;;

These are probably premature optimizations.

> +		[Aa]uto|AUTO)

Sigh.  I somehow thought that I already said we shouldn't do this "aCCEpt AnY CaSES" unless all other variables that take 'auto' take it case insensitively.

> +			# testing the "--auto-merge" option only if config is "auto"
> +			init_meld_help_msg
> +
> +			case "$meld_help_msg" in
> +			*"--auto-merge"*)
> +				meld_use_auto_merge_option=true
> +				;;
> +			*)
> +				meld_use_auto_merge_option=false
> +				;;
> +			esac
> +			;;
> +		*)
> +			# try detect boolean for 'on'||'yes'||numberic value
> +			bool_value=$(git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
> +			if test -n "$bool_value"
> +			then
> +				meld_use_auto_merge_option="$bool_value"
> +			else
> +				meld_use_auto_merge_option=false

I think this case (i.e. set to a non-bool value, and we do not recognise because it is not 'auto') should be flagged as an error, instead of treated as a silent "do not use", as it would leave the user scratching his or her head without realizing that there is a typo in the configuration file.

> +			fi
> +			;;
> +		esac
>  	fi
>  }
>
> base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17


^ permalink raw reply	[flat|nested] 74+ messages in thread

* RE: [PATCH v10] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-07  6:38                     ` lin.sun
@ 2020-07-07  6:44                       ` lin.sun
  0 siblings, 0 replies; 74+ messages in thread
From: lin.sun @ 2020-07-07  6:44 UTC (permalink / raw)
  To: 'Junio C Hamano', 'sunlin via GitGitGadget'
  Cc: git, 'sunlin'

Hi Junio,

I got your points now, I will upload another patch soon.
Thank you.

Regards
Lin

-----Original Message-----
From: lin.sun@zoom.us <lin.sun@zoom.us> 
Sent: Tuesday, July 7, 2020 14:39
To: 'Junio C Hamano' <gitster@pobox.com>; 'sunlin via GitGitGadget' <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org; 'sunlin' <sunlin7@yahoo.com>
Subject: RE: [PATCH v10] Support auto-merge for meld to follow the vim-diff behavior

Hi Junio,

It seems our mails crossed. I'll read your comments in this mail and reply you later.

Lin

-----Original Message-----
From: Junio C Hamano <gitster@pobox.com> 
Sent: Tuesday, July 7, 2020 14:26
To: sunlin via GitGitGadget <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org; sunlin <sunlin7@yahoo.com>; Lin Sun <lin.sun@zoom.us>
Subject: Re: [PATCH v10] Support auto-merge for meld to follow the vim-diff behavior

"sunlin via GitGitGadget" <gitgitgadget@gmail.com> writes:

> +		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
> +		case "$meld_use_auto_merge_option" in
> +		"")
> +			meld_use_auto_merge_option=false
> +			;;

I somehow thought that I already pointed out that this is wrong, didn't I?  You cannot tell between a "[section] var" (which is
"true") and not having any "[section] var = val" (which I think you are trying to treat as "not configured---do not use") from the output of "git config section.var".

Perhaps our mails crossed?

> +		[Tt]ure|TRUE)
> +			meld_use_auto_merge_option=true
> +			;;
> +		[Ff]alse|FALSE)
> +			meld_use_auto_merge_option=false
> +			;;

These are probably premature optimizations.

> +		[Aa]uto|AUTO)

Sigh.  I somehow thought that I already said we shouldn't do this "aCCEpt AnY CaSES" unless all other variables that take 'auto' take it case insensitively.

> +			# testing the "--auto-merge" option only if config is "auto"
> +			init_meld_help_msg
> +
> +			case "$meld_help_msg" in
> +			*"--auto-merge"*)
> +				meld_use_auto_merge_option=true
> +				;;
> +			*)
> +				meld_use_auto_merge_option=false
> +				;;
> +			esac
> +			;;
> +		*)
> +			# try detect boolean for 'on'||'yes'||numberic value
> +			bool_value=$(git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
> +			if test -n "$bool_value"
> +			then
> +				meld_use_auto_merge_option="$bool_value"
> +			else
> +				meld_use_auto_merge_option=false

I think this case (i.e. set to a non-bool value, and we do not recognise because it is not 'auto') should be flagged as an error, instead of treated as a silent "do not use", as it would leave the user scratching his or her head without realizing that there is a typo in the configuration file.

> +			fi
> +			;;
> +		esac
>  	fi
>  }
>
> base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17



^ permalink raw reply	[flat|nested] 74+ messages in thread

* [PATCH v11] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-07  6:17                 ` [PATCH v10] " sunlin via GitGitGadget
  2020-07-07  6:25                   ` Junio C Hamano
@ 2020-07-07  7:13                   ` sunlin via GitGitGadget
  2020-07-07 15:31                     ` Đoàn Trần Công Danh
  2020-07-08  3:25                     ` [PATCH v12] " sunlin via GitGitGadget
  1 sibling, 2 replies; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-07-07  7:13 UTC (permalink / raw)
  To: git; +Cc: sunlin, Lin Sun

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
telling it to auto-merge non-conflicting parts and highlight the conflicting
parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
for detecting the `--auto-merge` option automatically.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v11
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v11
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v10:

 1:  a4f1b8c2fa ! 1:  8015c4c98e Support auto-merge for meld to follow the vim-diff behavior
     @@ mergetools/meld: diff_cmd () {
      -		meld_has_output_option=true
      -	else
      -		meld_has_output_option=false
     -+		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
     -+		case "$meld_use_auto_merge_option" in
     -+		"")
     -+			meld_use_auto_merge_option=false
     -+			;;
     -+		[Tt]ure|TRUE)
     -+			meld_use_auto_merge_option=true
     -+			;;
     -+		[Ff]alse|FALSE)
     -+			meld_use_auto_merge_option=false
     -+			;;
     -+		[Aa]uto|AUTO)
     -+			# testing the "--auto-merge" option only if config is "auto"
     -+			init_meld_help_msg
     -+
     -+			case "$meld_help_msg" in
     -+			*"--auto-merge"*)
     -+				meld_use_auto_merge_option=true
     -+				;;
     -+			*)
     -+				meld_use_auto_merge_option=false
     -+				;;
     -+			esac
     -+			;;
     -+		*)
     -+			# try detect boolean for 'on'||'yes'||numberic value
     -+			bool_value=$(git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
     -+			if test -n "$bool_value"
     ++		if meld_use_auto_merge_option=$( \
     ++			git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
     ++		then
     ++			: use configured value
     ++		else
     ++			meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
     ++			if test "$meld_use_auto_merge_option" = "auto"
      +			then
     -+				meld_use_auto_merge_option="$bool_value"
     ++				# testing the "--auto-merge" option only if config is "auto"
     ++				init_meld_help_msg
     ++
     ++				case "$meld_help_msg" in
     ++				*"--auto-merge"* | *'[OPTION...]'*)
     ++					meld_use_auto_merge_option=true
     ++					;;
     ++				*)
     ++					meld_use_auto_merge_option=false
     ++					;;
     ++				esac
      +			else
      +				meld_use_auto_merge_option=false
      +			fi
     -+			;;
     -+		esac
     ++		fi
       	fi
       }


 Documentation/config/mergetool.txt | 10 ++++
 mergetools/meld                    | 81 ++++++++++++++++++++++++------
 2 files changed, 75 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..16a27443a3 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	When the `--auto-merge` is given, meld will merge all non-conflicting
+	parts automatically, highlight the conflicting parts and wait for
+	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
+	Git to unconditionally use the `--auto-merge` option with `meld`.
+	Setting this value to `auto` makes git detect whether `--auto-merge`
+	is supported and will only use `--auto-merge` when available.  A
+	value of `false` avoids using `--auto-merge` altogether, and is the
+	default value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..3463aee87e 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,83 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "$meld_help_msg"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$($meld_path --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "$meld_has_output_option"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true|false)
+			: use configured value
+			;;
+		*)
+			: empty or invalid configured value, detecting "--output" automatically
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="* | *'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "$meld_use_auto_merge_option"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		if meld_use_auto_merge_option=$( \
+			git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
+		then
+			: use configured value
+		else
+			meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
+			if test "$meld_use_auto_merge_option" = "auto"
+			then
+				# testing the "--auto-merge" option only if config is "auto"
+				init_meld_help_msg
+
+				case "$meld_help_msg" in
+				*"--auto-merge"* | *'[OPTION...]'*)
+					meld_use_auto_merge_option=true
+					;;
+				*)
+					meld_use_auto_merge_option=false
+					;;
+				esac
+			else
+				meld_use_auto_merge_option=false
+			fi
+		fi
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* Re: [PATCH v11] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-07  7:13                   ` [PATCH v11] " sunlin via GitGitGadget
@ 2020-07-07 15:31                     ` Đoàn Trần Công Danh
  2020-07-08  0:57                       ` lin.sun
  2020-07-08  3:25                     ` [PATCH v12] " sunlin via GitGitGadget
  1 sibling, 1 reply; 74+ messages in thread
From: Đoàn Trần Công Danh @ 2020-07-07 15:31 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, Lin Sun

On 2020-07-07 07:13:43+0000, sunlin via GitGitGadget <gitgitgadget@gmail.com> wrote:
> -# Check whether we should use 'meld --output <file>'
> -check_meld_for_output_version () {
> -	meld_path="$(git config mergetool.meld.path)"
> -	meld_path="${meld_path:-meld}"
> +# Get meld help message
> +init_meld_help_msg () {
> +	if test -z "$meld_help_msg"
> +	then
> +		meld_path="$(git config mergetool.meld.path || echo meld)"
> +		meld_help_msg=$($meld_path --help 2>&1)

I haven't thought about this until now.
`$meld_path` should be quoted.

	meld_help_msg="$("$meld_path" --help 2>&1)"

Either that or our Windows friends will complain soon:

	C:/Program Files/Meld/meld --help

(I don't know where meld will be installed by default in Window exactly,
above command is just a guess)

> +	fi
> +}
>  
> -	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
> +# Check the features and set flags
> +check_meld_for_features () {
> +	# Check whether we should use 'meld --output <file>'
> +	if test -z "$meld_has_output_option"
>  	then
> -		: use configured value
> -	elif "$meld_path" --help 2>&1 |
> -		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
> +		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
> +		case "$meld_has_output_option" in
> +		true|false)
> +			: use configured value
> +			;;
> +		*)
> +			: empty or invalid configured value, detecting "--output" automatically
> +			init_meld_help_msg
> +
> +			case "$meld_help_msg" in
> +			*"--output="* | *'[OPTION...]'*)
> +				# All version that has [OPTION...] supports --output

Good comments :)

> +				meld_has_output_option=true
> +				;;
> +			*)
> +				meld_has_output_option=false
> +				;;
> +			esac
> +			;;
> +		esac
> +	fi
> +	# Check whether we should use 'meld --auto-merge ...'
> +	if test -z "$meld_use_auto_merge_option"
>  	then
> -		: old ones mention --output and new ones just say OPTION...
> -		meld_has_output_option=true
> -	else
> -		meld_has_output_option=false
> +		if meld_use_auto_merge_option=$( \
> +			git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
> +		then
> +			: use configured value
> +		else
> +			meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
> +			if test "$meld_use_auto_merge_option" = "auto"
> +			then
> +				# testing the "--auto-merge" option only if config is "auto"
> +				init_meld_help_msg
> +
> +				case "$meld_help_msg" in
> +				*"--auto-merge"* | *'[OPTION...]'*)
> +					meld_use_auto_merge_option=true
> +					;;
> +				*)
> +					meld_use_auto_merge_option=false
> +					;;
> +				esac
> +			else
> +				meld_use_auto_merge_option=false

If I read other emails correctly (which I usually don't),
I think we would want to bail out in this case.

> +			fi
> +		fi
>  	fi
>  }
> 
> base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
> -- 
> gitgitgadget

-- 
Danh

^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v9] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-07  6:34                   ` lin.sun
@ 2020-07-07 16:43                     ` Junio C Hamano
  2020-07-08  1:20                       ` lin.sun
  0 siblings, 1 reply; 74+ messages in thread
From: Junio C Hamano @ 2020-07-07 16:43 UTC (permalink / raw)
  To: lin.sun; +Cc: 'sunlin via GitGitGadget', git, 'sunlin'

<lin.sun@zoom.us> writes:

> So in [PATH v10], it still try get the string value first, then detecting the ""(empty)/true/false/auto. 

You cannot interpret an empty output from "git config section.variable";
it could be "[section] variable" (which is true), or it could be a sign
that there is no "[section] variable = value" in the configuration (which
you treat as false).

Catching common spellings of 'true' and 'false' in the output of the
string version of "git config", while checking for 'auto' at the
same time, may not be too bad as an optimization to save an extra
call to "git config --bool 2>/dev/null" (and ignoring errors), so I
am OK with that as long as you leave the empty output alone.

^ permalink raw reply	[flat|nested] 74+ messages in thread

* RE: [PATCH v11] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-07 15:31                     ` Đoàn Trần Công Danh
@ 2020-07-08  0:57                       ` lin.sun
  0 siblings, 0 replies; 74+ messages in thread
From: lin.sun @ 2020-07-08  0:57 UTC (permalink / raw)
  To: 'Đoàn Trần Công Danh',
	'sunlin via GitGitGadget'
  Cc: git, 'sunlin'

Hi Doah,

>`$meld_path` should be quoted.
>...
Yes, you're totally right, I'll fix the `$meld_path` and more changes will upload with the [PATCH v12].
I'll update to you when the patch is ready. 

Regards
Lin


^ permalink raw reply	[flat|nested] 74+ messages in thread

* RE: [PATCH v9] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-07 16:43                     ` Junio C Hamano
@ 2020-07-08  1:20                       ` lin.sun
  2020-07-08  1:51                         ` Junio C Hamano
  0 siblings, 1 reply; 74+ messages in thread
From: lin.sun @ 2020-07-08  1:20 UTC (permalink / raw)
  To: 'Junio C Hamano'
  Cc: 'sunlin via GitGitGadget', git, 'sunlin'

Hi Junio,

> You cannot interpret an empty output from "git config section.variable"; it could be "[section] variable" (which is true), or it could be a sign that there is no "[section] variable = value" in the configuration (which you treat as false)

Yes, I notice that both "[section] variable " and "[section] variable = " output empty string but have reverse Boolean value.

> Catching common spellings of 'true' and 'false' in the output of the string version of "git config", while checking for 'auto' at the same time, may not be too bad as an optimization to save an extra call to "git config --bool 2>/dev/null" (and ignoring errors)...

With preview point, ` git config --bool ...` would better than "not be too bad"  : )

With the return code and return string from ` git config --bool ...`, 
follow pseudo-code maybe good for current situation.
if meld_use_auto_merge_option =` git config --bool ...`
then
	# success, maybe "(empty)"/true/false
	if test -z "$ meld_use_auto_merge_option"
	then
		meld_use_auto_merge_option=false
	fi
else
	# failed, the option is not empty or Boolean
	if test "auto" = ` git config `
	then
		# detect the "--auto-merge" option
	else
		meld_use_auto_merge_option=false
	fi
fi

Changes will upload with the [PATCH v12].
I'll update to you when the patch is ready. 

Regards
Lin


^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v9] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-08  1:20                       ` lin.sun
@ 2020-07-08  1:51                         ` Junio C Hamano
  0 siblings, 0 replies; 74+ messages in thread
From: Junio C Hamano @ 2020-07-08  1:51 UTC (permalink / raw)
  To: lin.sun; +Cc: 'sunlin via GitGitGadget', git, 'sunlin'

<lin.sun@zoom.us> writes:

> if meld_use_auto_merge_option =` git config --bool ...`
> then
> 	# success, maybe "(empty)"/true/false
> 	if test -z "$ meld_use_auto_merge_option"
> 	then
> 		meld_use_auto_merge_option=false
> 	fi

The inner test does not make any sense to me; I doubt that you can
get an empty output from a "git config --bool" that succeeds.

     $ cat >config <<\EOF
     [x] a
         b=true
         c=1
         d=false
         e=no
	 f=bogus
     EOF
     $ for i in a b c d e f
       do
         if v=$(git config --file=config --bool x.$i 2>/dev/null)
         then
           echo "succeeds (x.$i) => '$v'"
         else
           echo "fails (x.$i) => '$v'"
         fi
       done

You should see

succeeds (x.a) => 'true'
succeeds (x.b) => 'true'
succeeds (x.c) => 'true'
succeeds (x.d) => 'false'
succeeds (x.e) => 'false'
fails (x.f) => ''

if you run the above.  The most interesting is how all boolean
values are normalized to true and false regardless of how they are
originally spelled.

> else
> 	# failed, the option is not empty or Boolean
> 	if test "auto" = ` git config `
> 	then
> 		# detect the "--auto-merge" option
> 	else
> 		meld_use_auto_merge_option=false

I think review by Đoàn pointed out that we would want to warn/fail
loudly in this "else" case, as it is likely a misspelt configuration
value?

To recap, I think something along the following lines would be the
most readable and acceptably efficient with a short-cut for the
common cases.

    var=mergetool.meld.whatever
    val=$(git config $var)
    case "$val" in
    true | false)
	# we can take a short-cut without asking config --bool
        ... use $val ...
	;;
    auto)
	... auto detect ...
	;;
    *)
	if val=$(git config --bool $var 2>/dev/null)
	then
		# succeeded, so val must be a normalized boolean
		... use $val ...
	else
		die cannot parse $var
	fi
    easc

Thanks.

^ permalink raw reply	[flat|nested] 74+ messages in thread

* [PATCH v12] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-07  7:13                   ` [PATCH v11] " sunlin via GitGitGadget
  2020-07-07 15:31                     ` Đoàn Trần Công Danh
@ 2020-07-08  3:25                     ` sunlin via GitGitGadget
  2020-07-08  3:31                       ` lin.sun
                                         ` (2 more replies)
  1 sibling, 3 replies; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-07-08  3:25 UTC (permalink / raw)
  To: git; +Cc: sunlin, Lin Sun

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
telling it to auto-merge non-conflicting parts and highlight the conflicting
parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
for detecting the `--auto-merge` option automatically.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v12
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v12
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v11:

 1:  8015c4c98e ! 1:  b130cf38b5 Support auto-merge for meld to follow the vim-diff behavior
     @@ mergetools/meld: diff_cmd () {
      +	if test -z "$meld_help_msg"
      +	then
      +		meld_path="$(git config mergetool.meld.path || echo meld)"
     -+		meld_help_msg=$($meld_path --help 2>&1)
     ++		meld_help_msg=$("$meld_path" --help 2>&1)
      +	fi
      +}
       
     @@ mergetools/meld: diff_cmd () {
      +			init_meld_help_msg
      +
      +			case "$meld_help_msg" in
     -+			*"--output="* | *'[OPTION...]'*)
     ++			*"--output="*|*'[OPTION...]'*)
      +				# All version that has [OPTION...] supports --output
      +				meld_has_output_option=true
      +				;;
     @@ mergetools/meld: diff_cmd () {
      -		meld_has_output_option=true
      -	else
      -		meld_has_output_option=false
     -+		if meld_use_auto_merge_option=$( \
     -+			git config --bool mergetool.meld.useAutoMerge 2>/dev/null)
     -+		then
     -+			: use configured value
     -+		else
     -+			meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
     -+			if test "$meld_use_auto_merge_option" = "auto"
     -+			then
     -+				# testing the "--auto-merge" option only if config is "auto"
     -+				init_meld_help_msg
     ++		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
     ++		case "$meld_use_auto_merge_option" in
     ++		true|false)
     ++			: use well formatted boolean value
     ++			;;
     ++		auto)
     ++			# testing the "--auto-merge" option only if config is "auto"
     ++			init_meld_help_msg
      +
     -+				case "$meld_help_msg" in
     -+				*"--auto-merge"* | *'[OPTION...]'*)
     -+					meld_use_auto_merge_option=true
     -+					;;
     -+				*)
     -+					meld_use_auto_merge_option=false
     -+					;;
     -+				esac
     ++			case "$meld_help_msg" in
     ++			*"--auto-merge"*|*'[OPTION...]')
     ++				meld_use_auto_merge_option=true
     ++				;;
     ++			*)
     ++				meld_use_auto_merge_option=false
     ++				;;
     ++			esac
     ++			;;
     ++		*)
     ++			if meld_use_auto_merge_option=$(\
     ++				 git config --bool mergetool.meld.useAutoMerge)
     ++			then
     ++				: use normalized boolean value
      +			else
      +				meld_use_auto_merge_option=false
      +			fi
     -+		fi
     ++			;;
     ++		esac
       	fi
       }


 Documentation/config/mergetool.txt | 10 ++++
 mergetools/meld                    | 86 ++++++++++++++++++++++++------
 2 files changed, 80 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..16a27443a3 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	When the `--auto-merge` is given, meld will merge all non-conflicting
+	parts automatically, highlight the conflicting parts and wait for
+	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
+	Git to unconditionally use the `--auto-merge` option with `meld`.
+	Setting this value to `auto` makes git detect whether `--auto-merge`
+	is supported and will only use `--auto-merge` when available.  A
+	value of `false` avoids using `--auto-merge` altogether, and is the
+	default value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..d71c22196d 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,88 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "$meld_help_msg"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$("$meld_path" --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "$meld_has_output_option"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true|false)
+			: use configured value
+			;;
+		*)
+			: empty or invalid configured value, detecting "--output" automatically
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="*|*'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "$meld_use_auto_merge_option"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
+		case "$meld_use_auto_merge_option" in
+		true|false)
+			: use well formatted boolean value
+			;;
+		auto)
+			# testing the "--auto-merge" option only if config is "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--auto-merge"*|*'[OPTION...]')
+				meld_use_auto_merge_option=true
+				;;
+			*)
+				meld_use_auto_merge_option=false
+				;;
+			esac
+			;;
+		*)
+			if meld_use_auto_merge_option=$(\
+				 git config --bool mergetool.meld.useAutoMerge)
+			then
+				: use normalized boolean value
+			else
+				meld_use_auto_merge_option=false
+			fi
+			;;
+		esac
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* RE: [PATCH v12] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-08  3:25                     ` [PATCH v12] " sunlin via GitGitGadget
@ 2020-07-08  3:31                       ` lin.sun
  2020-07-08 15:42                       ` Đoàn Trần Công Danh
  2020-07-09  0:35                       ` [PATCH v13] " sunlin via GitGitGadget
  2 siblings, 0 replies; 74+ messages in thread
From: lin.sun @ 2020-07-08  3:31 UTC (permalink / raw)
  To: 'sunlin via GitGitGadget', git, 'Junio C Hamano',
	'Đoàn Trần Công Danh'

Hi Junio, Doah,

The [PATCH v12] Is uploaded, in which,
1. "$meld_path" is quoted.
2. the logical for deal true/false/auto is flow Junio's comment
3. error message will emit for invalid configuration value
$ git config mergetool.meld.useAutoMerge invalid_boolean_value
$ git mergetool --tool=meld
...
fatal: bad numeric config value 'hello' for 'mergetool.meld.useautomerge' in .git/config: invalid unit

Please review again, thank you.
https://lore.kernel.org/git/pull.781.v12.git.git.1594178716840.gitgitgadget@gmail.com/

Regards
Lin


^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v12] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-08  3:25                     ` [PATCH v12] " sunlin via GitGitGadget
  2020-07-08  3:31                       ` lin.sun
@ 2020-07-08 15:42                       ` Đoàn Trần Công Danh
  2020-07-08 15:47                         ` lin.sun
  2020-07-09  0:35                       ` [PATCH v13] " sunlin via GitGitGadget
  2 siblings, 1 reply; 74+ messages in thread
From: Đoàn Trần Công Danh @ 2020-07-08 15:42 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, Lin Sun

On 2020-07-08 03:25:16+0000, sunlin via GitGitGadget <gitgitgadget@gmail.com> wrote:
> +	# Check whether we should use 'meld --auto-merge ...'
> +	if test -z "$meld_use_auto_merge_option"
>  	then
> -		: old ones mention --output and new ones just say OPTION...
> -		meld_has_output_option=true
> -	else
> -		meld_has_output_option=false
> +		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
> +		case "$meld_use_auto_merge_option" in
> +		true|false)
> +			: use well formatted boolean value
> +			;;
> +		auto)
> +			# testing the "--auto-merge" option only if config is "auto"
> +			init_meld_help_msg
> +
> +			case "$meld_help_msg" in
> +			*"--auto-merge"*|*'[OPTION...]')

The "*'[OPTION...]'*" part sneaks into here in v11,
And this version drops the last "*",
which makes it:

- less correct if all versions that has "[OPTION...]" supports
  --auto-merge, which is unlikely; and
- less incorrect (still not correct enough) if some versions
  that has "[OPTION...]" doesn't support --auto-merge,
  which is more likely.

If we could trace all versions of meld and confirms the former
condition, I think it's better to add back the missing "*"

Otherwise, it's safer choice to remove "|*'[OPTION...]" here.

I'm not using meld, so, if someone asked me, I would go with the latter.


-- 
Danh

^ permalink raw reply	[flat|nested] 74+ messages in thread

* RE: [PATCH v12] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-08 15:42                       ` Đoàn Trần Công Danh
@ 2020-07-08 15:47                         ` lin.sun
  0 siblings, 0 replies; 74+ messages in thread
From: lin.sun @ 2020-07-08 15:47 UTC (permalink / raw)
  To: 'Đoàn Trần Công Danh',
	'sunlin via GitGitGadget'
  Cc: git, 'sunlin'

Hi Danh,

Thank you for your comment, it's actually my failed that loss the "*" after *"[OPTIONS...]".
I'll add back the missing '*' in next uploading.

Regards
Lin


^ permalink raw reply	[flat|nested] 74+ messages in thread

* [PATCH v13] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-08  3:25                     ` [PATCH v12] " sunlin via GitGitGadget
  2020-07-08  3:31                       ` lin.sun
  2020-07-08 15:42                       ` Đoàn Trần Công Danh
@ 2020-07-09  0:35                       ` sunlin via GitGitGadget
  2020-07-09  0:39                         ` lin.sun
                                           ` (3 more replies)
  2 siblings, 4 replies; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-07-09  0:35 UTC (permalink / raw)
  To: git; +Cc: sunlin, Lin Sun

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
telling it to auto-merge non-conflicting parts and highlight the conflicting
parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
for detecting the `--auto-merge` option automatically.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v13
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v13
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v12:

 1:  b130cf38b5 ! 1:  b949e5721a Support auto-merge for meld to follow the vim-diff behavior
     @@ mergetools/meld: diff_cmd () {
      +			init_meld_help_msg
      +
      +			case "$meld_help_msg" in
     -+			*"--auto-merge"*|*'[OPTION...]')
     ++			*"--auto-merge"*|*'[OPTION...]'*)
      +				meld_use_auto_merge_option=true
      +				;;
      +			*)


 Documentation/config/mergetool.txt | 10 ++++
 mergetools/meld                    | 86 ++++++++++++++++++++++++------
 2 files changed, 80 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..16a27443a3 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	When the `--auto-merge` is given, meld will merge all non-conflicting
+	parts automatically, highlight the conflicting parts and wait for
+	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
+	Git to unconditionally use the `--auto-merge` option with `meld`.
+	Setting this value to `auto` makes git detect whether `--auto-merge`
+	is supported and will only use `--auto-merge` when available.  A
+	value of `false` avoids using `--auto-merge` altogether, and is the
+	default value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..5e5872e1c3 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,88 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "$meld_help_msg"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$("$meld_path" --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "$meld_has_output_option"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true|false)
+			: use configured value
+			;;
+		*)
+			: empty or invalid configured value, detecting "--output" automatically
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="*|*'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "$meld_use_auto_merge_option"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
+		case "$meld_use_auto_merge_option" in
+		true|false)
+			: use well formatted boolean value
+			;;
+		auto)
+			# testing the "--auto-merge" option only if config is "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--auto-merge"*|*'[OPTION...]'*)
+				meld_use_auto_merge_option=true
+				;;
+			*)
+				meld_use_auto_merge_option=false
+				;;
+			esac
+			;;
+		*)
+			if meld_use_auto_merge_option=$(\
+				 git config --bool mergetool.meld.useAutoMerge)
+			then
+				: use normalized boolean value
+			else
+				meld_use_auto_merge_option=false
+			fi
+			;;
+		esac
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* [PATCH v13] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-09  0:35                       ` [PATCH v13] " sunlin via GitGitGadget
@ 2020-07-09  0:39                         ` lin.sun
  2020-07-09  2:42                         ` Junio C Hamano
                                           ` (2 subsequent siblings)
  3 siblings, 0 replies; 74+ messages in thread
From: lin.sun @ 2020-07-09  0:39 UTC (permalink / raw)
  To: 'sunlin via GitGitGadget',
	git, 'Đoàn Trần Công Danh'
  Cc: 'sunlin', 'Junio C Hamano'

Hi Danh,

The [PATCH v13] add the missing "*" back at the back of *'[OPTION...]'.
     -+			*"--auto-merge"*|*'[OPTION...]')
     ++			*"--auto-merge"*|*'[OPTION...]'*)

https://lore.kernel.org/git/pull.781.v13.git.git.1594254906647.gitgitgadget@gmail.com
Thanks

Regards
Lin


^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v13] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-09  0:35                       ` [PATCH v13] " sunlin via GitGitGadget
  2020-07-09  0:39                         ` lin.sun
@ 2020-07-09  2:42                         ` Junio C Hamano
  2020-07-09  2:56                         ` Junio C Hamano
  2020-07-09  4:28                         ` [PATCH v14] " sunlin via GitGitGadget
  3 siblings, 0 replies; 74+ messages in thread
From: Junio C Hamano @ 2020-07-09  2:42 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, Lin Sun

"sunlin via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: Lin Sun <lin.sun@zoom.us>
> Subject: Re: [PATCH v13] Support auto-merge for meld to follow the vim-diff behavior

I'd retitle to match the recommended structure, e.g.

    Subject: [PATCH] mergetool: update meld backend to allow using '--auto-merge'

while queuing.

Thanks.  I might have more comments later.

^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v13] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-09  0:35                       ` [PATCH v13] " sunlin via GitGitGadget
  2020-07-09  0:39                         ` lin.sun
  2020-07-09  2:42                         ` Junio C Hamano
@ 2020-07-09  2:56                         ` Junio C Hamano
  2020-07-09  3:24                           ` lin.sun
  2020-07-09  4:28                         ` [PATCH v14] " sunlin via GitGitGadget
  3 siblings, 1 reply; 74+ messages in thread
From: Junio C Hamano @ 2020-07-09  2:56 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, Lin Sun

"sunlin via GitGitGadget" <gitgitgadget@gmail.com> writes:

> +			case "$meld_help_msg" in
> +			*"--output="*|*'[OPTION...]'*)

This may be personal preference, but I think the way you spelled
this line with SP on both sides of '|' was much easier to read.

> +	# Check whether we should use 'meld --auto-merge ...'
> +	if test -z "$meld_use_auto_merge_option"
>  	then
> +		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
> +		case "$meld_use_auto_merge_option" in
> +		true|false)
> +			: use well formatted boolean value
> +			;;

OK.

> +		auto)
> +			# testing the "--auto-merge" option only if config is "auto"
> +			init_meld_help_msg
> +
> +			case "$meld_help_msg" in
> +			*"--auto-merge"*|*'[OPTION...]'*)
> +				meld_use_auto_merge_option=true
> +				;;
> +			*)
> +				meld_use_auto_merge_option=false
> +				;;
> +			esac
> +			;;

OK.

> +		*)

This is the case where we saw "", "True", "treu", etc. from the
string "git config --get".

> +			if meld_use_auto_merge_option=$(\
> +				 git config --bool mergetool.meld.useAutoMerge)

You do not need that backslash, do you?

Perhaps

			if meld_use_auto_merge_option=$(
				 git config --bool mergetool.meld.useAutoMerge
			)	
			then

if you really want to spread them into multiple lines.

> +			then
> +				: use normalized boolean value

Sure, we got a valid boolean.

> +			else
> +				meld_use_auto_merge_option=false

Why? Shoudln't we loudly complain to let the user know of a misspelt
value in the configuration?

> +			fi
> +			;;
> +		esac
>  	fi
>  }
>
> base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17

^ permalink raw reply	[flat|nested] 74+ messages in thread

* RE: [PATCH v13] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-09  2:56                         ` Junio C Hamano
@ 2020-07-09  3:24                           ` lin.sun
  2020-07-09  4:49                             ` Junio C Hamano
  2020-07-12 14:07                             ` lin.sun
  0 siblings, 2 replies; 74+ messages in thread
From: lin.sun @ 2020-07-09  3:24 UTC (permalink / raw)
  To: 'Junio C Hamano', 'sunlin via GitGitGadget'
  Cc: git, 'sunlin'

Hi Junio,

I'll add SP on both side of  '|', and remove the backslash, thank you.

This line assign value with `git config --bool...` is over 80 characters, so there is a break. 

>> +			else
>> +				meld_use_auto_merge_option=false
>Why? Shoudln't we loudly complain to let the user know of a misspelt value in the configuration?

The command line `git config --bool ...` without "2>&/dev/null" will print error message, just passthrough to user.
$ git config mergetool.meld.useAutoMerge hello 
$ git mergetool --tool=meld 
fatal: bad numeric config value 'hello' for 'mergetool.meld.useautomerge' in .git/config: invalid unit

I'll upload the changes soon.

Regards
Lin


^ permalink raw reply	[flat|nested] 74+ messages in thread

* [PATCH v14] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-09  0:35                       ` [PATCH v13] " sunlin via GitGitGadget
                                           ` (2 preceding siblings ...)
  2020-07-09  2:56                         ` Junio C Hamano
@ 2020-07-09  4:28                         ` sunlin via GitGitGadget
  2020-07-12  8:39                           ` [PATCH v15] " sunlin via GitGitGadget
  3 siblings, 1 reply; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-07-09  4:28 UTC (permalink / raw)
  To: git; +Cc: sunlin, Lin Sun

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
telling it to auto-merge non-conflicting parts and highlight the conflicting
parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
for detecting the `--auto-merge` option automatically.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v14
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v14
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v13:

 1:  b949e5721a ! 1:  ce4e4cbfc0 Support auto-merge for meld to follow the vim-diff behavior
     @@ mergetools/meld: diff_cmd () {
      +			esac
      +			;;
      +		*)
     -+			if meld_use_auto_merge_option=$(\
     ++			# try other boolean value with git
     ++			if meld_use_auto_merge_option=$(
      +				 git config --bool mergetool.meld.useAutoMerge)
      +			then
      +				: use normalized boolean value


 Documentation/config/mergetool.txt | 10 ++++
 mergetools/meld                    | 87 ++++++++++++++++++++++++------
 2 files changed, 81 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..16a27443a3 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	When the `--auto-merge` is given, meld will merge all non-conflicting
+	parts automatically, highlight the conflicting parts and wait for
+	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
+	Git to unconditionally use the `--auto-merge` option with `meld`.
+	Setting this value to `auto` makes git detect whether `--auto-merge`
+	is supported and will only use `--auto-merge` when available.  A
+	value of `false` avoids using `--auto-merge` altogether, and is the
+	default value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..d95b4ee630 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,89 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "$meld_help_msg"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$("$meld_path" --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "$meld_has_output_option"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true|false)
+			: use configured value
+			;;
+		*)
+			: empty or invalid configured value, detecting "--output" automatically
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="*|*'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "$meld_use_auto_merge_option"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
+		case "$meld_use_auto_merge_option" in
+		true|false)
+			: use well formatted boolean value
+			;;
+		auto)
+			# testing the "--auto-merge" option only if config is "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--auto-merge"*|*'[OPTION...]'*)
+				meld_use_auto_merge_option=true
+				;;
+			*)
+				meld_use_auto_merge_option=false
+				;;
+			esac
+			;;
+		*)
+			# try other boolean value with git
+			if meld_use_auto_merge_option=$(
+				 git config --bool mergetool.meld.useAutoMerge)
+			then
+				: use normalized boolean value
+			else
+				meld_use_auto_merge_option=false
+			fi
+			;;
+		esac
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* Re: [PATCH v13] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-09  3:24                           ` lin.sun
@ 2020-07-09  4:49                             ` Junio C Hamano
  2020-07-09  5:31                               ` Junio C Hamano
  2020-07-12 14:07                             ` lin.sun
  1 sibling, 1 reply; 74+ messages in thread
From: Junio C Hamano @ 2020-07-09  4:49 UTC (permalink / raw)
  To: lin.sun; +Cc: 'sunlin via GitGitGadget', git, 'sunlin'

<lin.sun@zoom.us> writes:

> Hi Junio,
>
> I'll add SP on both side of  '|', and remove the backslash, thank you.
>
> This line assign value with `git config --bool...` is over 80 characters, so there is a break. 
>
>>> +			else
>>> +				meld_use_auto_merge_option=false
>>Why? Shoudln't we loudly complain to let the user know of a misspelt value in the configuration?
>
> The command line `git config --bool ...` without "2>&/dev/null" will print error message, just passthrough to user.
> $ git config mergetool.meld.useAutoMerge hello 
> $ git mergetool --tool=meld 
> fatal: bad numeric config value 'hello' for 'mergetool.meld.useautomerge' in .git/config: invalid unit

Yes, but you do not exit(1) here, so the user will keep going
without having a chance to stop, think and correct the misspelt
value in the configuration file, no?

>
> I'll upload the changes soon.
>
> Regards
> Lin

^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v13] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-09  4:49                             ` Junio C Hamano
@ 2020-07-09  5:31                               ` Junio C Hamano
  0 siblings, 0 replies; 74+ messages in thread
From: Junio C Hamano @ 2020-07-09  5:31 UTC (permalink / raw)
  To: lin.sun; +Cc: 'sunlin via GitGitGadget', git, 'sunlin'

Junio C Hamano <gitster@pobox.com> writes:

>>>> +			else
>>>> +				meld_use_auto_merge_option=false
>>>Why? Shoudln't we loudly complain to let the user know of a misspelt value in the configuration?
>>
>> The command line `git config --bool ...` without "2>&/dev/null" will print error message, just passthrough to user.
>> $ git config mergetool.meld.useAutoMerge hello 
>> $ git mergetool --tool=meld 
>> fatal: bad numeric config value 'hello' for 'mergetool.meld.useautomerge' in .git/config: invalid unit
>
> Yes, but you do not exit(1) here, so the user will keep going
> without having a chance to stop, think and correct the misspelt
> value in the configuration file, no?

Hmph, I've been forgetting an important case you are handling well,
which is that the user does not have the variable defined anywhere
in the configuration.  "git config --bool var.ia.ble" fails silently
in such a case, and you do want to declare that the user does not
want to use the "--auto-merge" in that case, which is what this
silent else clause does very well.

So, let's leave this part as-is.

Thanks, I'll push out a new iteration of today's integration before
going to bed.

>
>>
>> I'll upload the changes soon.
>>
>> Regards
>> Lin

^ permalink raw reply	[flat|nested] 74+ messages in thread

* [PATCH v15] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-09  4:28                         ` [PATCH v14] " sunlin via GitGitGadget
@ 2020-07-12  8:39                           ` sunlin via GitGitGadget
  2020-07-12  9:08                             ` [PATCH v16] " sunlin via GitGitGadget
  0 siblings, 1 reply; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-07-12  8:39 UTC (permalink / raw)
  To: git; +Cc: sunlin, Lin Sun

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
telling it to auto-merge non-conflicting parts and highlight the conflicting
parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
for detecting the `--auto-merge` option automatically.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v15
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v15
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v14:

 1:  ce4e4cbfc0 ! 1:  02d849784f Support auto-merge for meld to follow the vim-diff behavior
     @@ Documentation/config/mergetool.txt: mergetool.meld.hasOutput::
       	After performing a merge, the original file with conflict markers
       	can be saved as a file with a `.orig` extension.  If this variable
      
     + ## builtin/config.c ##
     +@@ builtin/config.c: static int show_scope;
     + #define TYPE_PATH		4
     + #define TYPE_EXPIRY_DATE	5
     + #define TYPE_COLOR		6
     ++#define TYPE_BOOL_OR_STR        7
     + 
     + #define OPT_CALLBACK_VALUE(s, l, v, h, i) \
     + 	{ OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
     +@@ builtin/config.c: static int option_parse_type(const struct option *opt, const char *arg,
     + 			new_type = TYPE_INT;
     + 		else if (!strcmp(arg, "bool-or-int"))
     + 			new_type = TYPE_BOOL_OR_INT;
     ++		else if (!strcmp(arg, "bool-or-str"))
     ++			new_type = TYPE_BOOL_OR_STR;
     + 		else if (!strcmp(arg, "path"))
     + 			new_type = TYPE_PATH;
     + 		else if (!strcmp(arg, "expiry-date"))
     +@@ builtin/config.c: static struct option builtin_config_options[] = {
     + 	OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
     + 	OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT),
     + 	OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
     ++	OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR),
     + 	OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
     + 	OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
     + 	OPT_GROUP(N_("Other")),
     +@@ builtin/config.c: static int format_config(struct strbuf *buf, const char *key_, const char *value
     + 				strbuf_addstr(buf, v ? "true" : "false");
     + 			else
     + 				strbuf_addf(buf, "%d", v);
     ++		} else if (type == TYPE_BOOL_OR_STR) {
     ++			int is_bool, v;
     ++			v = git_config_bool_or_str(NULL, key_, value_, &is_bool);
     ++			if (is_bool)
     ++				strbuf_addstr(buf, v ? "true" : "false");
     ++			else
     ++				strbuf_addstr(buf, value_);
     + 		} else if (type == TYPE_PATH) {
     + 			const char *v;
     + 			if (git_config_pathname(&v, key_, value_) < 0)
     +@@ builtin/config.c: static char *normalize_value(const char *key, const char *value)
     + 		else
     + 			return xstrdup(v ? "true" : "false");
     + 	}
     ++	if (type == TYPE_BOOL_OR_STR) {
     ++		int is_bool, v;
     ++		v = git_config_bool_or_str(NULL, key, value, &is_bool);
     ++		if (!is_bool)
     ++			return xstrdup(value);
     ++		else
     ++			return xstrdup(v ? "true" : "false");
     ++	}
     + 	if (type == TYPE_COLOR) {
     + 		char v[COLOR_MAXLEN];
     + 		if (git_config_color(v, key, value))
     +
     + ## config.c ##
     +@@ config.c: int git_config_bool_or_int(const char *name, const char *value, int *is_bool)
     + 	return git_config_int(name, value);
     + }
     + 
     ++int git_config_bool_or_str(const char **dest, const char *name, const char *value, int *is_bool)
     ++{
     ++	int v = git_parse_maybe_bool_text(value);
     ++	if (0 <= v) {
     ++		*is_bool = 1;
     ++		return v;
     ++	}
     ++	*is_bool = 0;
     ++	if (dest != NULL)
     ++	  return git_config_string(dest, name, value);
     ++	else
     ++	  return 0;
     ++}
     ++
     + int git_config_bool(const char *name, const char *value)
     + {
     + 	int discard;
     +
     + ## config.h ##
     +@@ config.h: ssize_t git_config_ssize_t(const char *, const char *);
     +  */
     + int git_config_bool_or_int(const char *, const char *, int *);
     + 
     ++/**
     ++ * Same as `git_config_bool`, except that `is_bool` flag is unset, then if
     ++ * `dest` parameter is non-NULL, it allocates and copies the value string
     ++ * into the `dest`, if `dest` is NULL and `is_bool` flag is unset it return 0.
     ++ */
     ++int git_config_bool_or_str(const char **, const char *, const char *, int *);
     ++
     + /**
     +  * Parse a string into a boolean value, respecting keywords like "true" and
     +  * "false". Integer values are converted into true/false values (when they
     +
       ## mergetools/meld ##
      @@ mergetools/meld: diff_cmd () {
       }
     @@ mergetools/meld: diff_cmd () {
      -		meld_has_output_option=true
      -	else
      -		meld_has_output_option=false
     -+		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
     ++		meld_use_auto_merge_option=$(
     ++			git --bool-or-str config mergetool.meld.useAutoMerge)
      +		case "$meld_use_auto_merge_option" in
      +		true|false)
      +			: use well formatted boolean value
     @@ mergetools/meld: diff_cmd () {
      +			esac
      +			;;
      +		*)
     -+			# try other boolean value with git
     -+			if meld_use_auto_merge_option=$(
     -+				 git config --bool mergetool.meld.useAutoMerge)
     -+			then
     -+				: use normalized boolean value
     -+			else
     -+				meld_use_auto_merge_option=false
     -+			fi
     ++			meld_use_auto_merge_option=false
      +			;;
      +		esac
       	fi


 Documentation/config/mergetool.txt | 10 ++++
 builtin/config.c                   | 19 +++++++
 config.c                           | 14 ++++++
 config.h                           |  7 +++
 mergetools/meld                    | 81 ++++++++++++++++++++++++------
 5 files changed, 115 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..16a27443a3 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	When the `--auto-merge` is given, meld will merge all non-conflicting
+	parts automatically, highlight the conflicting parts and wait for
+	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
+	Git to unconditionally use the `--auto-merge` option with `meld`.
+	Setting this value to `auto` makes git detect whether `--auto-merge`
+	is supported and will only use `--auto-merge` when available.  A
+	value of `false` avoids using `--auto-merge` altogether, and is the
+	default value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/builtin/config.c b/builtin/config.c
index ee4aef6a35..6f2ddadc80 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -65,6 +65,7 @@ static int show_scope;
 #define TYPE_PATH		4
 #define TYPE_EXPIRY_DATE	5
 #define TYPE_COLOR		6
+#define TYPE_BOOL_OR_STR        7
 
 #define OPT_CALLBACK_VALUE(s, l, v, h, i) \
 	{ OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
@@ -94,6 +95,8 @@ static int option_parse_type(const struct option *opt, const char *arg,
 			new_type = TYPE_INT;
 		else if (!strcmp(arg, "bool-or-int"))
 			new_type = TYPE_BOOL_OR_INT;
+		else if (!strcmp(arg, "bool-or-str"))
+			new_type = TYPE_BOOL_OR_STR;
 		else if (!strcmp(arg, "path"))
 			new_type = TYPE_PATH;
 		else if (!strcmp(arg, "expiry-date"))
@@ -149,6 +152,7 @@ static struct option builtin_config_options[] = {
 	OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
 	OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT),
 	OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
+	OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR),
 	OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
 	OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
 	OPT_GROUP(N_("Other")),
@@ -250,6 +254,13 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
 				strbuf_addstr(buf, v ? "true" : "false");
 			else
 				strbuf_addf(buf, "%d", v);
+		} else if (type == TYPE_BOOL_OR_STR) {
+			int is_bool, v;
+			v = git_config_bool_or_str(NULL, key_, value_, &is_bool);
+			if (is_bool)
+				strbuf_addstr(buf, v ? "true" : "false");
+			else
+				strbuf_addstr(buf, value_);
 		} else if (type == TYPE_PATH) {
 			const char *v;
 			if (git_config_pathname(&v, key_, value_) < 0)
@@ -411,6 +422,14 @@ static char *normalize_value(const char *key, const char *value)
 		else
 			return xstrdup(v ? "true" : "false");
 	}
+	if (type == TYPE_BOOL_OR_STR) {
+		int is_bool, v;
+		v = git_config_bool_or_str(NULL, key, value, &is_bool);
+		if (!is_bool)
+			return xstrdup(value);
+		else
+			return xstrdup(v ? "true" : "false");
+	}
 	if (type == TYPE_COLOR) {
 		char v[COLOR_MAXLEN];
 		if (git_config_color(v, key, value))
diff --git a/config.c b/config.c
index 8db9c77098..4c6c06d10b 100644
--- a/config.c
+++ b/config.c
@@ -1100,6 +1100,20 @@ int git_config_bool_or_int(const char *name, const char *value, int *is_bool)
 	return git_config_int(name, value);
 }
 
+int git_config_bool_or_str(const char **dest, const char *name, const char *value, int *is_bool)
+{
+	int v = git_parse_maybe_bool_text(value);
+	if (0 <= v) {
+		*is_bool = 1;
+		return v;
+	}
+	*is_bool = 0;
+	if (dest != NULL)
+	  return git_config_string(dest, name, value);
+	else
+	  return 0;
+}
+
 int git_config_bool(const char *name, const char *value)
 {
 	int discard;
diff --git a/config.h b/config.h
index 060874488f..175b88d9c5 100644
--- a/config.h
+++ b/config.h
@@ -217,6 +217,13 @@ ssize_t git_config_ssize_t(const char *, const char *);
  */
 int git_config_bool_or_int(const char *, const char *, int *);
 
+/**
+ * Same as `git_config_bool`, except that `is_bool` flag is unset, then if
+ * `dest` parameter is non-NULL, it allocates and copies the value string
+ * into the `dest`, if `dest` is NULL and `is_bool` flag is unset it return 0.
+ */
+int git_config_bool_or_str(const char **, const char *, const char *, int *);
+
 /**
  * Parse a string into a boolean value, respecting keywords like "true" and
  * "false". Integer values are converted into true/false values (when they
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..1838a8c35b 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,83 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "$meld_help_msg"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$("$meld_path" --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "$meld_has_output_option"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true|false)
+			: use configured value
+			;;
+		*)
+			: empty or invalid configured value, detecting "--output" automatically
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="*|*'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "$meld_use_auto_merge_option"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_use_auto_merge_option=$(
+			git --bool-or-str config mergetool.meld.useAutoMerge)
+		case "$meld_use_auto_merge_option" in
+		true|false)
+			: use well formatted boolean value
+			;;
+		auto)
+			# testing the "--auto-merge" option only if config is "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--auto-merge"*|*'[OPTION...]'*)
+				meld_use_auto_merge_option=true
+				;;
+			*)
+				meld_use_auto_merge_option=false
+				;;
+			esac
+			;;
+		*)
+			meld_use_auto_merge_option=false
+			;;
+		esac
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* [PATCH v16] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-12  8:39                           ` [PATCH v15] " sunlin via GitGitGadget
@ 2020-07-12  9:08                             ` sunlin via GitGitGadget
  2020-07-12 18:04                               ` Junio C Hamano
  2020-07-12 23:32                               ` [PATCH v17] " sunlin via GitGitGadget
  0 siblings, 2 replies; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-07-12  9:08 UTC (permalink / raw)
  To: git; +Cc: sunlin, Lin Sun

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
telling it to auto-merge non-conflicting parts and highlight the conflicting
parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
for detecting the `--auto-merge` option automatically.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v16
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v16
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v15:

 1:  02d849784f ! 1:  d235a576b4 Support auto-merge for meld to follow the vim-diff behavior
     @@ mergetools/meld: diff_cmd () {
      -	else
      -		meld_has_output_option=false
      +		meld_use_auto_merge_option=$(
     -+			git --bool-or-str config mergetool.meld.useAutoMerge)
     ++			git config --bool-or-str mergetool.meld.useAutoMerge)
      +		case "$meld_use_auto_merge_option" in
      +		true|false)
      +			: use well formatted boolean value


 Documentation/config/mergetool.txt | 10 ++++
 builtin/config.c                   | 19 +++++++
 config.c                           | 14 ++++++
 config.h                           |  7 +++
 mergetools/meld                    | 81 ++++++++++++++++++++++++------
 5 files changed, 115 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..16a27443a3 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	When the `--auto-merge` is given, meld will merge all non-conflicting
+	parts automatically, highlight the conflicting parts and wait for
+	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
+	Git to unconditionally use the `--auto-merge` option with `meld`.
+	Setting this value to `auto` makes git detect whether `--auto-merge`
+	is supported and will only use `--auto-merge` when available.  A
+	value of `false` avoids using `--auto-merge` altogether, and is the
+	default value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/builtin/config.c b/builtin/config.c
index ee4aef6a35..6f2ddadc80 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -65,6 +65,7 @@ static int show_scope;
 #define TYPE_PATH		4
 #define TYPE_EXPIRY_DATE	5
 #define TYPE_COLOR		6
+#define TYPE_BOOL_OR_STR        7
 
 #define OPT_CALLBACK_VALUE(s, l, v, h, i) \
 	{ OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
@@ -94,6 +95,8 @@ static int option_parse_type(const struct option *opt, const char *arg,
 			new_type = TYPE_INT;
 		else if (!strcmp(arg, "bool-or-int"))
 			new_type = TYPE_BOOL_OR_INT;
+		else if (!strcmp(arg, "bool-or-str"))
+			new_type = TYPE_BOOL_OR_STR;
 		else if (!strcmp(arg, "path"))
 			new_type = TYPE_PATH;
 		else if (!strcmp(arg, "expiry-date"))
@@ -149,6 +152,7 @@ static struct option builtin_config_options[] = {
 	OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
 	OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT),
 	OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
+	OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR),
 	OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
 	OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
 	OPT_GROUP(N_("Other")),
@@ -250,6 +254,13 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
 				strbuf_addstr(buf, v ? "true" : "false");
 			else
 				strbuf_addf(buf, "%d", v);
+		} else if (type == TYPE_BOOL_OR_STR) {
+			int is_bool, v;
+			v = git_config_bool_or_str(NULL, key_, value_, &is_bool);
+			if (is_bool)
+				strbuf_addstr(buf, v ? "true" : "false");
+			else
+				strbuf_addstr(buf, value_);
 		} else if (type == TYPE_PATH) {
 			const char *v;
 			if (git_config_pathname(&v, key_, value_) < 0)
@@ -411,6 +422,14 @@ static char *normalize_value(const char *key, const char *value)
 		else
 			return xstrdup(v ? "true" : "false");
 	}
+	if (type == TYPE_BOOL_OR_STR) {
+		int is_bool, v;
+		v = git_config_bool_or_str(NULL, key, value, &is_bool);
+		if (!is_bool)
+			return xstrdup(value);
+		else
+			return xstrdup(v ? "true" : "false");
+	}
 	if (type == TYPE_COLOR) {
 		char v[COLOR_MAXLEN];
 		if (git_config_color(v, key, value))
diff --git a/config.c b/config.c
index 8db9c77098..4c6c06d10b 100644
--- a/config.c
+++ b/config.c
@@ -1100,6 +1100,20 @@ int git_config_bool_or_int(const char *name, const char *value, int *is_bool)
 	return git_config_int(name, value);
 }
 
+int git_config_bool_or_str(const char **dest, const char *name, const char *value, int *is_bool)
+{
+	int v = git_parse_maybe_bool_text(value);
+	if (0 <= v) {
+		*is_bool = 1;
+		return v;
+	}
+	*is_bool = 0;
+	if (dest != NULL)
+	  return git_config_string(dest, name, value);
+	else
+	  return 0;
+}
+
 int git_config_bool(const char *name, const char *value)
 {
 	int discard;
diff --git a/config.h b/config.h
index 060874488f..175b88d9c5 100644
--- a/config.h
+++ b/config.h
@@ -217,6 +217,13 @@ ssize_t git_config_ssize_t(const char *, const char *);
  */
 int git_config_bool_or_int(const char *, const char *, int *);
 
+/**
+ * Same as `git_config_bool`, except that `is_bool` flag is unset, then if
+ * `dest` parameter is non-NULL, it allocates and copies the value string
+ * into the `dest`, if `dest` is NULL and `is_bool` flag is unset it return 0.
+ */
+int git_config_bool_or_str(const char **, const char *, const char *, int *);
+
 /**
  * Parse a string into a boolean value, respecting keywords like "true" and
  * "false". Integer values are converted into true/false values (when they
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..bc2ea894d7 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,83 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "$meld_help_msg"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$("$meld_path" --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "$meld_has_output_option"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true|false)
+			: use configured value
+			;;
+		*)
+			: empty or invalid configured value, detecting "--output" automatically
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="*|*'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "$meld_use_auto_merge_option"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_use_auto_merge_option=$(
+			git config --bool-or-str mergetool.meld.useAutoMerge)
+		case "$meld_use_auto_merge_option" in
+		true|false)
+			: use well formatted boolean value
+			;;
+		auto)
+			# testing the "--auto-merge" option only if config is "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--auto-merge"*|*'[OPTION...]'*)
+				meld_use_auto_merge_option=true
+				;;
+			*)
+				meld_use_auto_merge_option=false
+				;;
+			esac
+			;;
+		*)
+			meld_use_auto_merge_option=false
+			;;
+		esac
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* RE: [PATCH v13] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-09  3:24                           ` lin.sun
  2020-07-09  4:49                             ` Junio C Hamano
@ 2020-07-12 14:07                             ` lin.sun
  2020-07-12 23:38                               ` lin.sun
  1 sibling, 1 reply; 74+ messages in thread
From: lin.sun @ 2020-07-12 14:07 UTC (permalink / raw)
  To: 'Junio C Hamano', 'sunlin via GitGitGadget'
  Cc: git, 'sunlin',
	'Đoàn Trần Công Danh'

Hi Junio,

I had add a new c function ` git_config_bool_or_str()` to support get the 
configured value for true/false/auto with git. It will make the `mergetool/meld`
only calling `git config` once for getting the `useAutoMerge`.

Please review the [PATH v16], thanks.
https://lore.kernel.org/git/pull.781.v16.git.git.1594544903477.gitgitgadget@gmail.com

Regards
Lin


^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v16] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-12  9:08                             ` [PATCH v16] " sunlin via GitGitGadget
@ 2020-07-12 18:04                               ` Junio C Hamano
  2020-07-12 23:26                                 ` lin.sun
  2020-07-13  5:14                                 ` Junio C Hamano
  2020-07-12 23:32                               ` [PATCH v17] " sunlin via GitGitGadget
  1 sibling, 2 replies; 74+ messages in thread
From: Junio C Hamano @ 2020-07-12 18:04 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, Lin Sun

"sunlin via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: Lin Sun <lin.sun@zoom.us>
>
> Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
> telling it to auto-merge non-conflicting parts and highlight the conflicting
> parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
> for detecting the `--auto-merge` option automatically.
>
> Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
> Helped-by: David Aguilar <davvid@gmail.com>
> Signed-off-by: Lin Sun <lin.sun@zoom.us>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
>     Enable auto-merge for meld to follow the vimdiff beharior
>     
>     Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
>     the mergetool "vimdiff" will merge the no-conflict changes and highlight
>     the conflict parts. This patch will make the mergetool "meld" similar to
>     "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.
>
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v16
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v16
> Pull-Request: https://github.com/git/git/pull/781
>
> Range-diff vs v15:
>
>  1:  02d849784f ! 1:  d235a576b4 Support auto-merge for meld to follow the vim-diff behavior
>      @@ mergetools/meld: diff_cmd () {
>       -	else
>       -		meld_has_output_option=false
>       +		meld_use_auto_merge_option=$(
>      -+			git --bool-or-str config mergetool.meld.useAutoMerge)
>      ++			git config --bool-or-str mergetool.meld.useAutoMerge)

It is quite clear in this hunk that that the previous one was not
even proofread before sending X-<.

> +		} else if (type == TYPE_BOOL_OR_STR) {
> +			int is_bool, v;
> +			v = git_config_bool_or_str(NULL, key_, value_, &is_bool);
> +			if (is_bool)
> +				strbuf_addstr(buf, v ? "true" : "false");
> +			else
> +				strbuf_addstr(buf, value_);
>  		} else if (type == TYPE_PATH) {
>  			const char *v;
>  			if (git_config_pathname(&v, key_, value_) < 0)
> @@ -411,6 +422,14 @@ static char *normalize_value(const char *key, const char *value)
>  		else
>  			return xstrdup(v ? "true" : "false");
>  	}
> +	if (type == TYPE_BOOL_OR_STR) {
> +		int is_bool, v;
> +		v = git_config_bool_or_str(NULL, key, value, &is_bool);
> +		if (!is_bool)
> +			return xstrdup(value);
> +		else
> +			return xstrdup(v ? "true" : "false");
> +	}

That's unfortunate that we need almost identical code duplicated
here and above.  It probably is a tad larger than what we typcally
call #leftoverbits, so please ignore it for now.

> diff --git a/config.c b/config.c
> index 8db9c77098..4c6c06d10b 100644
> --- a/config.c
> +++ b/config.c
> @@ -1100,6 +1100,20 @@ int git_config_bool_or_int(const char *name, const char *value, int *is_bool)
>  	return git_config_int(name, value);
>  }
>  
> +int git_config_bool_or_str(const char **dest, const char *name, const char *value, int *is_bool)
> +{
> +	int v = git_parse_maybe_bool_text(value);
> +	if (0 <= v) {
> +		*is_bool = 1;
> +		return v;
> +	}
> +	*is_bool = 0;
> +	if (dest != NULL)
> +	  return git_config_string(dest, name, value);
> +	else
> +	  return 0;
> +}

Wrong indentation.

I do not think this is a good interface at all, from at least three
points.

 - What happens when the value is set to "2"?  git_config_bool()
   would say, because it calls git_config_bool_or_int() and learns
   that the value is an integer 2 and uses !! operator on it to
   normalize it to 1, we judge it as "true".  Your implementation
   says it is not a bool and instead it is a string "2".  When
   telling a boolean and an integer apart, saying 2 is not a bool
   makes sense, but given that "interpret this value as boolean"
   logic in git_config_bool() says "2" is a true, the logic to tell
   a boolean and a string apart probably should say that the user
   who wrote "2" there meant true, i.e. boolean.

 - What's the returned value from this function and how can the
   caller sensibly use it?  If it happened to be (narrowly defined)
   bool, the returned value is 0 for false and 1 for true.
   Otherwise, the caller gets 0 if it forgets to pass dest, or 0 if
   value successfully gets returned as a string, or -1 upon an
   error.  Hence it is impossible for the caller to use

	if (git_config_bool_or_str(...)) {
		... do one thing ...
	} else {
		... do something else ...
	}

 - There is no point to pass dest to this function.  If it is not
   bool, then the caller can do strdup() the value.

> diff --git a/config.h b/config.h
> index 060874488f..175b88d9c5 100644
> --- a/config.h
> +++ b/config.h
> @@ -217,6 +217,13 @@ ssize_t git_config_ssize_t(const char *, const char *);
>   */
>  int git_config_bool_or_int(const char *, const char *, int *);
>  
> +/**
> + * Same as `git_config_bool`, except that `is_bool` flag is unset, then if
> + * `dest` parameter is non-NULL, it allocates and copies the value string
> + * into the `dest`, if `dest` is NULL and `is_bool` flag is unset it return 0.
> + */

is_bool is not an "in-parameter" flag but a pointer to point at
where the result is stored, so the above description does not make
much sense.  I suspect, from the actual implementation, that you
wanted to say

    Parse "value" to see if it is a boolean, and if so set *is_bool
    to true and leave *dest untouched.  If it is not a boolean, set
    *is_bool to false and assign a copy of value to *dest.

But again, I do not think this function is designed right, so let's
not spend any more time polishing what you wrote for now.

I would expect something like this in builtin/config.c would be
sufficient:

	if (type == TYPE_BOOL_OR_STRING) {
		int v = git_parse_maybe_bool(value);
		if (v < 0)
			return xstrdup(value);
		else
			return xstrdup(v ? "true" : "false");
	}

i.e. we do not need a new helper in the lower level of the API stack.

> +		meld_use_auto_merge_option=$(
> +			git config --bool-or-str mergetool.meld.useAutoMerge)

If the body is made on a separate line for readability, doing it more
like so would be even more readable:

		meld_use_auto_merge_option=$(
			git config --bool-or-str mergetool.meld.useAutoMerge
		)

> +		case "$meld_use_auto_merge_option" in
> +		true|false)
> +			: use well formatted boolean value
> +			;;
> +		auto)
> +			# testing the "--auto-merge" option only if config is "auto"
> +			init_meld_help_msg
> +
> +			case "$meld_help_msg" in
> +			*"--auto-merge"*|*'[OPTION...]'*)
> +				meld_use_auto_merge_option=true
> +				;;
> +			*)
> +				meld_use_auto_merge_option=false
> +				;;
> +			esac
> +			;;
> +		*)
> +			meld_use_auto_merge_option=false

Now that the --bool-or-string would be silent, you have to give an
error message yourself here, no?  Have you hand-tested the result of
applying your patch to see if all the cases we care about (i.e.
various scenarios we raised and thought together how the code should
react to the situation during the review discussion so far)?

We are not in a hurry, and we will not be paying too much attention
on topics that are not yet in 'next' until the upcoming release is
done anyway, so take your time to try polishing before sending
anything out.

Thanks.

^ permalink raw reply	[flat|nested] 74+ messages in thread

* RE: [PATCH v16] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-12 18:04                               ` Junio C Hamano
@ 2020-07-12 23:26                                 ` lin.sun
  2020-07-13  5:14                                 ` Junio C Hamano
  1 sibling, 0 replies; 74+ messages in thread
From: lin.sun @ 2020-07-12 23:26 UTC (permalink / raw)
  To: 'Junio C Hamano', 'sunlin via GitGitGadget'
  Cc: git, 'sunlin'

Hi Junio,

Apologize for the [PATCH v16] which is not well thoughtful, and I totally agree that we will not paying too much attention before upcoming release. 
I'll rollback changes to preview one,  thank you so much.

Best Regards
Lin


^ permalink raw reply	[flat|nested] 74+ messages in thread

* [PATCH v17] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-12  9:08                             ` [PATCH v16] " sunlin via GitGitGadget
  2020-07-12 18:04                               ` Junio C Hamano
@ 2020-07-12 23:32                               ` sunlin via GitGitGadget
  2020-07-24  0:58                                 ` Junio C Hamano
  2020-09-12  7:21                                 ` [PATCH v18] " sunlin via GitGitGadget
  1 sibling, 2 replies; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-07-12 23:32 UTC (permalink / raw)
  To: git; +Cc: sunlin, Lin Sun

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
telling it to auto-merge non-conflicting parts and highlight the conflicting
parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
for detecting the `--auto-merge` option automatically.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v17
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v17
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v16:

 1:  d235a576b4 ! 1:  ce4e4cbfc0 Support auto-merge for meld to follow the vim-diff behavior
     @@ Documentation/config/mergetool.txt: mergetool.meld.hasOutput::
       	After performing a merge, the original file with conflict markers
       	can be saved as a file with a `.orig` extension.  If this variable
      
     - ## builtin/config.c ##
     -@@ builtin/config.c: static int show_scope;
     - #define TYPE_PATH		4
     - #define TYPE_EXPIRY_DATE	5
     - #define TYPE_COLOR		6
     -+#define TYPE_BOOL_OR_STR        7
     - 
     - #define OPT_CALLBACK_VALUE(s, l, v, h, i) \
     - 	{ OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
     -@@ builtin/config.c: static int option_parse_type(const struct option *opt, const char *arg,
     - 			new_type = TYPE_INT;
     - 		else if (!strcmp(arg, "bool-or-int"))
     - 			new_type = TYPE_BOOL_OR_INT;
     -+		else if (!strcmp(arg, "bool-or-str"))
     -+			new_type = TYPE_BOOL_OR_STR;
     - 		else if (!strcmp(arg, "path"))
     - 			new_type = TYPE_PATH;
     - 		else if (!strcmp(arg, "expiry-date"))
     -@@ builtin/config.c: static struct option builtin_config_options[] = {
     - 	OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
     - 	OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT),
     - 	OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
     -+	OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR),
     - 	OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
     - 	OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
     - 	OPT_GROUP(N_("Other")),
     -@@ builtin/config.c: static int format_config(struct strbuf *buf, const char *key_, const char *value
     - 				strbuf_addstr(buf, v ? "true" : "false");
     - 			else
     - 				strbuf_addf(buf, "%d", v);
     -+		} else if (type == TYPE_BOOL_OR_STR) {
     -+			int is_bool, v;
     -+			v = git_config_bool_or_str(NULL, key_, value_, &is_bool);
     -+			if (is_bool)
     -+				strbuf_addstr(buf, v ? "true" : "false");
     -+			else
     -+				strbuf_addstr(buf, value_);
     - 		} else if (type == TYPE_PATH) {
     - 			const char *v;
     - 			if (git_config_pathname(&v, key_, value_) < 0)
     -@@ builtin/config.c: static char *normalize_value(const char *key, const char *value)
     - 		else
     - 			return xstrdup(v ? "true" : "false");
     - 	}
     -+	if (type == TYPE_BOOL_OR_STR) {
     -+		int is_bool, v;
     -+		v = git_config_bool_or_str(NULL, key, value, &is_bool);
     -+		if (!is_bool)
     -+			return xstrdup(value);
     -+		else
     -+			return xstrdup(v ? "true" : "false");
     -+	}
     - 	if (type == TYPE_COLOR) {
     - 		char v[COLOR_MAXLEN];
     - 		if (git_config_color(v, key, value))
     -
     - ## config.c ##
     -@@ config.c: int git_config_bool_or_int(const char *name, const char *value, int *is_bool)
     - 	return git_config_int(name, value);
     - }
     - 
     -+int git_config_bool_or_str(const char **dest, const char *name, const char *value, int *is_bool)
     -+{
     -+	int v = git_parse_maybe_bool_text(value);
     -+	if (0 <= v) {
     -+		*is_bool = 1;
     -+		return v;
     -+	}
     -+	*is_bool = 0;
     -+	if (dest != NULL)
     -+	  return git_config_string(dest, name, value);
     -+	else
     -+	  return 0;
     -+}
     -+
     - int git_config_bool(const char *name, const char *value)
     - {
     - 	int discard;
     -
     - ## config.h ##
     -@@ config.h: ssize_t git_config_ssize_t(const char *, const char *);
     -  */
     - int git_config_bool_or_int(const char *, const char *, int *);
     - 
     -+/**
     -+ * Same as `git_config_bool`, except that `is_bool` flag is unset, then if
     -+ * `dest` parameter is non-NULL, it allocates and copies the value string
     -+ * into the `dest`, if `dest` is NULL and `is_bool` flag is unset it return 0.
     -+ */
     -+int git_config_bool_or_str(const char **, const char *, const char *, int *);
     -+
     - /**
     -  * Parse a string into a boolean value, respecting keywords like "true" and
     -  * "false". Integer values are converted into true/false values (when they
     -
       ## mergetools/meld ##
      @@ mergetools/meld: diff_cmd () {
       }
     @@ mergetools/meld: diff_cmd () {
      -		meld_has_output_option=true
      -	else
      -		meld_has_output_option=false
     -+		meld_use_auto_merge_option=$(
     -+			git config --bool-or-str mergetool.meld.useAutoMerge)
     ++		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
      +		case "$meld_use_auto_merge_option" in
      +		true|false)
      +			: use well formatted boolean value
     @@ mergetools/meld: diff_cmd () {
      +			esac
      +			;;
      +		*)
     -+			meld_use_auto_merge_option=false
     ++			# try other boolean value with git
     ++			if meld_use_auto_merge_option=$(
     ++				 git config --bool mergetool.meld.useAutoMerge)
     ++			then
     ++				: use normalized boolean value
     ++			else
     ++				meld_use_auto_merge_option=false
     ++			fi
      +			;;
      +		esac
       	fi


 Documentation/config/mergetool.txt | 10 ++++
 mergetools/meld                    | 87 ++++++++++++++++++++++++------
 2 files changed, 81 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..16a27443a3 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	When the `--auto-merge` is given, meld will merge all non-conflicting
+	parts automatically, highlight the conflicting parts and wait for
+	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
+	Git to unconditionally use the `--auto-merge` option with `meld`.
+	Setting this value to `auto` makes git detect whether `--auto-merge`
+	is supported and will only use `--auto-merge` when available.  A
+	value of `false` avoids using `--auto-merge` altogether, and is the
+	default value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..d95b4ee630 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,89 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "$meld_help_msg"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$("$meld_path" --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "$meld_has_output_option"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true|false)
+			: use configured value
+			;;
+		*)
+			: empty or invalid configured value, detecting "--output" automatically
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="*|*'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "$meld_use_auto_merge_option"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
+		case "$meld_use_auto_merge_option" in
+		true|false)
+			: use well formatted boolean value
+			;;
+		auto)
+			# testing the "--auto-merge" option only if config is "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--auto-merge"*|*'[OPTION...]'*)
+				meld_use_auto_merge_option=true
+				;;
+			*)
+				meld_use_auto_merge_option=false
+				;;
+			esac
+			;;
+		*)
+			# try other boolean value with git
+			if meld_use_auto_merge_option=$(
+				 git config --bool mergetool.meld.useAutoMerge)
+			then
+				: use normalized boolean value
+			else
+				meld_use_auto_merge_option=false
+			fi
+			;;
+		esac
 	fi
 }

base-commit: 07d8ea56f2ecb64b75b92264770c0a664231ce17
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* RE: [PATCH v13] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-12 14:07                             ` lin.sun
@ 2020-07-12 23:38                               ` lin.sun
  0 siblings, 0 replies; 74+ messages in thread
From: lin.sun @ 2020-07-12 23:38 UTC (permalink / raw)
  To: 'Junio C Hamano', 'sunlin via GitGitGadget'
  Cc: git, 'sunlin',
	'Đoàn Trần Công Danh'

Hi Junio,

I had rollback the changes, which is submit as [PATCH v17], it's same as [PATCH v14].

You can just ignore it. Thanks

https://lore.kernel.org/git/pull.781.v17.git.git.1594596738929.gitgitgadget@gmail.com
https://lore.kernel.org/git/pull.781.v14.git.git.1594268906195.gitgitgadget@gmail.com

Regards
Lin


^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v16] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-12 18:04                               ` Junio C Hamano
  2020-07-12 23:26                                 ` lin.sun
@ 2020-07-13  5:14                                 ` Junio C Hamano
  2020-07-13  6:58                                   ` lin.sun
  1 sibling, 1 reply; 74+ messages in thread
From: Junio C Hamano @ 2020-07-13  5:14 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, Lin Sun

Junio C Hamano <gitster@pobox.com> writes:

> ...
> Now that the --bool-or-string would be silent, you have to give an
> error message yourself here, no?  Have you hand-tested the result of
> applying your patch to see if all the cases we care about (i.e.
> various scenarios we raised and thought together how the code should
> react to the situation during the review discussion so far)?
>
> We are not in a hurry, and we will not be paying too much attention
> on topics that are not yet in 'next' until the upcoming release is
> done anyway, so take your time to try polishing before sending
> anything out.

Just for fun, I've queued the following on top of v16 and merged the
result to 'seen'.

As this adds a new feature to "git config", it also needs updates to
Documentation/git-config.txt and tests for the feature, and it
probably makes sense to make it a two-patch series.  Everything
related to the "git config" enhancement as 1/2, and change to
mergetools/meld as 2/2.

 builtin/config.c | 16 +++++++---------
 config.c         | 14 --------------
 config.h         |  7 -------
 mergetools/meld  | 16 ++++++++++------
 4 files changed, 17 insertions(+), 36 deletions(-)

diff --git a/builtin/config.c b/builtin/config.c
index 6f2ddadc80..7891e070a4 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -65,7 +65,7 @@ static int show_scope;
 #define TYPE_PATH		4
 #define TYPE_EXPIRY_DATE	5
 #define TYPE_COLOR		6
-#define TYPE_BOOL_OR_STR        7
+#define TYPE_BOOL_OR_STR	7
 
 #define OPT_CALLBACK_VALUE(s, l, v, h, i) \
 	{ OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
@@ -255,12 +255,11 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
 			else
 				strbuf_addf(buf, "%d", v);
 		} else if (type == TYPE_BOOL_OR_STR) {
-			int is_bool, v;
-			v = git_config_bool_or_str(NULL, key_, value_, &is_bool);
-			if (is_bool)
-				strbuf_addstr(buf, v ? "true" : "false");
-			else
+			int v = git_parse_maybe_bool(value_);
+			if (v < 0)
 				strbuf_addstr(buf, value_);
+			else
+				strbuf_addstr(buf, v ? "true" : "false");
 		} else if (type == TYPE_PATH) {
 			const char *v;
 			if (git_config_pathname(&v, key_, value_) < 0)
@@ -423,9 +422,8 @@ static char *normalize_value(const char *key, const char *value)
 			return xstrdup(v ? "true" : "false");
 	}
 	if (type == TYPE_BOOL_OR_STR) {
-		int is_bool, v;
-		v = git_config_bool_or_str(NULL, key, value, &is_bool);
-		if (!is_bool)
+		int v = git_parse_maybe_bool(value);
+		if (v < 0)
 			return xstrdup(value);
 		else
 			return xstrdup(v ? "true" : "false");
diff --git a/config.c b/config.c
index 4c6c06d10b..8db9c77098 100644
--- a/config.c
+++ b/config.c
@@ -1100,20 +1100,6 @@ int git_config_bool_or_int(const char *name, const char *value, int *is_bool)
 	return git_config_int(name, value);
 }
 
-int git_config_bool_or_str(const char **dest, const char *name, const char *value, int *is_bool)
-{
-	int v = git_parse_maybe_bool_text(value);
-	if (0 <= v) {
-		*is_bool = 1;
-		return v;
-	}
-	*is_bool = 0;
-	if (dest != NULL)
-	  return git_config_string(dest, name, value);
-	else
-	  return 0;
-}
-
 int git_config_bool(const char *name, const char *value)
 {
 	int discard;
diff --git a/config.h b/config.h
index 175b88d9c5..060874488f 100644
--- a/config.h
+++ b/config.h
@@ -217,13 +217,6 @@ ssize_t git_config_ssize_t(const char *, const char *);
  */
 int git_config_bool_or_int(const char *, const char *, int *);
 
-/**
- * Same as `git_config_bool`, except that `is_bool` flag is unset, then if
- * `dest` parameter is non-NULL, it allocates and copies the value string
- * into the `dest`, if `dest` is NULL and `is_bool` flag is unset it return 0.
- */
-int git_config_bool_or_str(const char **, const char *, const char *, int *);
-
 /**
  * Parse a string into a boolean value, respecting keywords like "true" and
  * "false". Integer values are converted into true/false values (when they
diff --git a/mergetools/meld b/mergetools/meld
index bc2ea894d7..aab4ebb935 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -36,7 +36,7 @@ check_meld_for_features () {
 	then
 		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
 		case "$meld_has_output_option" in
-		true|false)
+		true | false)
 			: use configured value
 			;;
 		*)
@@ -44,7 +44,7 @@ check_meld_for_features () {
 			init_meld_help_msg
 
 			case "$meld_help_msg" in
-			*"--output="*|*'[OPTION...]'*)
+			*"--output="* | *'[OPTION...]'*)
 				# All version that has [OPTION...] supports --output
 				meld_has_output_option=true
 				;;
@@ -59,9 +59,10 @@ check_meld_for_features () {
 	if test -z "$meld_use_auto_merge_option"
 	then
 		meld_use_auto_merge_option=$(
-			git config --bool-or-str mergetool.meld.useAutoMerge)
+			git config --bool-or-str mergetool.meld.useAutoMerge
+		)
 		case "$meld_use_auto_merge_option" in
-		true|false)
+		true | false)
 			: use well formatted boolean value
 			;;
 		auto)
@@ -69,7 +70,7 @@ check_meld_for_features () {
 			init_meld_help_msg
 
 			case "$meld_help_msg" in
-			*"--auto-merge"*|*'[OPTION...]'*)
+			*"--auto-merge"* | *'[OPTION...]'*)
 				meld_use_auto_merge_option=true
 				;;
 			*)
@@ -77,9 +78,12 @@ check_meld_for_features () {
 				;;
 			esac
 			;;
-		*)
+		"")
 			meld_use_auto_merge_option=false
 			;;
+		*)
+			die "unknown mergetool.meld.useAutoMerge: $meld_use_auto_merge_option"
+			;;
 		esac
 	fi
 }
-- 
2.28.0-rc0


^ permalink raw reply related	[flat|nested] 74+ messages in thread

* RE: [PATCH v16] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-13  5:14                                 ` Junio C Hamano
@ 2020-07-13  6:58                                   ` lin.sun
  0 siblings, 0 replies; 74+ messages in thread
From: lin.sun @ 2020-07-13  6:58 UTC (permalink / raw)
  To: 'Junio C Hamano', 'sunlin via GitGitGadget'
  Cc: git, 'sunlin'

Hi Junio,

> As this adds a new feature to "git config", it also needs updates to Documentation/git-config.txt and tests for the feature, and it probably makes sense to make it a two-patch series.  Everything related to the "git config" enhancement as 1/2, and change to mergetools/meld as 2/2.
Thank you for your comments, these are key points for adding new feature into git.
I'll try my best to make new pull-requests for option `--bool-or-string` after current feature is applied upstream. 

Regards
Lin


^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v17] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-12 23:32                               ` [PATCH v17] " sunlin via GitGitGadget
@ 2020-07-24  0:58                                 ` Junio C Hamano
  2020-09-03 21:48                                   ` Junio C Hamano
  2020-09-12  7:21                                 ` [PATCH v18] " sunlin via GitGitGadget
  1 sibling, 1 reply; 74+ messages in thread
From: Junio C Hamano @ 2020-07-24  0:58 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, Lin Sun

"sunlin via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: Lin Sun <lin.sun@zoom.us>
>
> Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
> telling it to auto-merge non-conflicting parts and highlight the conflicting
> parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
> for detecting the `--auto-merge` option automatically.
>
> Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
> Helped-by: David Aguilar <davvid@gmail.com>
> Signed-off-by: Lin Sun <lin.sun@zoom.us>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
>     Enable auto-merge for meld to follow the vimdiff beharior
>     
>     Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
>     the mergetool "vimdiff" will merge the no-conflict changes and highlight
>     the conflict parts. This patch will make the mergetool "meld" similar to
>     "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

This version seems to revert the bool-or-str change that would
become useful with a bit more polishing, with docs and tests.

Intended?

It also seems to repeat many issues that have been pointed out
during the reviews of previous revisions.  I'd rather not have to
repeat pointing them out all over again, obviously.

I have queued v16 (the one with the beginning of bool-or-str) with
minimum fixups for issues I pointed out in the review of that
revision queued on top of it as SQUASH??? commit.  Please find it in
the 'seen' branch.

Also,

    Subject: Support auto-merge for meld to follow the vim-diff behavior

needs fixing.

cf. https://git-scm.com/docs/SubmittingPatches#describe-changes

Two tricks to pick a good title are:

 - Read a pageful or two of "git shortlog --no-merges" output to get
   accustomed to the general pattern in the entire project.  It
   would become clear why titles with "area:" prefix help the
   patches with them easier to locate.

 - Read a pageful of "git shortlog --no-merges -- mergetools"
   (i.e. the same but limited to the files you are touching) to see
   how the changes that contributed over time to build the subsystem
   are called, so that the new patches can fit in the pattern.

I think something along the lines of

    Subject: [PATCH] mergetool/meld: optionally allow --auto-merge behaviour

or something would fit well.

Thanks.

^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v17] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-24  0:58                                 ` Junio C Hamano
@ 2020-09-03 21:48                                   ` Junio C Hamano
       [not found]                                     ` <C35AC799-B4F6-4A5E-92FA-21065310B379@hxcore.ol>
  0 siblings, 1 reply; 74+ messages in thread
From: Junio C Hamano @ 2020-09-03 21:48 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, sunlin, Lin Sun

Junio C Hamano <gitster@pobox.com> writes:

> I have queued v16 (the one with the beginning of bool-or-str) with
> minimum fixups for issues I pointed out in the review of that
> revision queued on top of it as SQUASH??? commit.  Please find it in
> the 'seen' branch.
>
> Also,
>
>     Subject: Support auto-merge for meld to follow the vim-diff behavior
>
> needs fixing.
> ...

Anything new on this topic?  No rush, but I'd hate to see a
basically good topic to be left in the stalled state too long.

Thanks.

^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v17] Support auto-merge for meld to follow the vim-diff behavior
       [not found]                                     ` <C35AC799-B4F6-4A5E-92FA-21065310B379@hxcore.ol>
@ 2020-09-09  1:31                                       ` Lin Sun
  2020-09-09 20:43                                         ` Junio C Hamano
  0 siblings, 1 reply; 74+ messages in thread
From: Lin Sun @ 2020-09-09  1:31 UTC (permalink / raw)
  To: Junio C Hamano, sunlin via GitGitGadget; +Cc: git, sunlin

[-- Attachment #1: Type: text/plain, Size: 981 bytes --]

Hi Junio,

Sorry again, I have to re-send this mail in plain text mode for the
mail system rejecting it with " <git@vger.kernel.org> Content-Policy
reject msg: The message contains HTML subpart, therefore we
    consider it SPAM or Outlook Virus."
--------------------------------------------------------
I tried to send an update to you in the morning but now the mail
missed from my drafts and “send box”, I’m not sure if the mail already
sent or not.
So I sent this mail with
“0001-Support-auto-merge-for-meld-to-follow-the-vim-diff-b.patch” for
assurement.
If you already received this patch before, please ignore current mail.
--------------------------------------------------------
After applying the changes with your SQUASH??? Commit, I test the
cases with useAutoMerge flag None/true/false/auto, it works like a
charm.
So I sent out the last patch (no changes since your SQUASH commit),
please review it. Thank you.

Best Regards
Lin Sun

[-- Attachment #2: 0001-Support-auto-merge-for-meld-to-follow-the-vim-diff-b.patch --]
[-- Type: application/octet-stream, Size: 7211 bytes --]

From 1b931e610ddfc02dc2e88234b106e3d3ff841b01 Mon Sep 17 00:00:00 2001
From: Lin Sun <lin.sun@zoom.us>
Date: Thu, 7 May 2020 07:31:14 +0800
Subject: [PATCH] Support auto-merge for meld to follow the vim-diff behavior
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
telling it to auto-merge non-conflicting parts and highlight the conflicting
parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
for detecting the `--auto-merge` option automatically.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/config/mergetool.txt | 10 +++++
 builtin/config.c                   | 17 ++++++++
 mergetools/meld                    | 85 +++++++++++++++++++++++++++++++-------
 3 files changed, 96 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31d..16a2744 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	When the `--auto-merge` is given, meld will merge all non-conflicting
+	parts automatically, highlight the conflicting parts and wait for
+	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
+	Git to unconditionally use the `--auto-merge` option with `meld`.
+	Setting this value to `auto` makes git detect whether `--auto-merge`
+	is supported and will only use `--auto-merge` when available.  A
+	value of `false` avoids using `--auto-merge` altogether, and is the
+	default value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/builtin/config.c b/builtin/config.c
index 5e39f61..ae077c9 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -65,6 +65,7 @@ static int show_scope;
 #define TYPE_PATH		4
 #define TYPE_EXPIRY_DATE	5
 #define TYPE_COLOR		6
+#define TYPE_BOOL_OR_STR	7
 
 #define OPT_CALLBACK_VALUE(s, l, v, h, i) \
 	{ OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
@@ -94,6 +95,8 @@ static int option_parse_type(const struct option *opt, const char *arg,
 			new_type = TYPE_INT;
 		else if (!strcmp(arg, "bool-or-int"))
 			new_type = TYPE_BOOL_OR_INT;
+		else if (!strcmp(arg, "bool-or-str"))
+			new_type = TYPE_BOOL_OR_STR;
 		else if (!strcmp(arg, "path"))
 			new_type = TYPE_PATH;
 		else if (!strcmp(arg, "expiry-date"))
@@ -149,6 +152,7 @@ static struct option builtin_config_options[] = {
 	OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
 	OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT),
 	OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
+	OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR),
 	OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
 	OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
 	OPT_GROUP(N_("Other")),
@@ -250,6 +254,12 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
 				strbuf_addstr(buf, v ? "true" : "false");
 			else
 				strbuf_addf(buf, "%d", v);
+		} else if (type == TYPE_BOOL_OR_STR) {
+			int v = git_parse_maybe_bool(value_);
+			if (v < 0)
+				strbuf_addstr(buf, value_);
+			else
+				strbuf_addstr(buf, v ? "true" : "false");
 		} else if (type == TYPE_PATH) {
 			const char *v;
 			if (git_config_pathname(&v, key_, value_) < 0)
@@ -411,6 +421,13 @@ static char *normalize_value(const char *key, const char *value)
 		else
 			return xstrdup(v ? "true" : "false");
 	}
+	if (type == TYPE_BOOL_OR_STR) {
+		int v = git_parse_maybe_bool(value);
+		if (v < 0)
+			return xstrdup(value);
+		else
+			return xstrdup(v ? "true" : "false");
+	}
 	if (type == TYPE_COLOR) {
 		char v[COLOR_MAXLEN];
 		if (git_config_color(v, key, value))
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470..aab4ebb 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,87 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "$meld_help_msg"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$("$meld_path" --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "$meld_has_output_option"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true | false)
+			: use configured value
+			;;
+		*)
+			: empty or invalid configured value, detecting "--output" automatically
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="* | *'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "$meld_use_auto_merge_option"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_use_auto_merge_option=$(
+			git config --bool-or-str mergetool.meld.useAutoMerge
+		)
+		case "$meld_use_auto_merge_option" in
+		true | false)
+			: use well formatted boolean value
+			;;
+		auto)
+			# testing the "--auto-merge" option only if config is "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--auto-merge"* | *'[OPTION...]'*)
+				meld_use_auto_merge_option=true
+				;;
+			*)
+				meld_use_auto_merge_option=false
+				;;
+			esac
+			;;
+		"")
+			meld_use_auto_merge_option=false
+			;;
+		*)
+			die "unknown mergetool.meld.useAutoMerge: $meld_use_auto_merge_option"
+			;;
+		esac
 	fi
 }
-- 
2.2.0


^ permalink raw reply related	[flat|nested] 74+ messages in thread

* Re: [PATCH v17] Support auto-merge for meld to follow the vim-diff behavior
  2020-09-09  1:31                                       ` Lin Sun
@ 2020-09-09 20:43                                         ` Junio C Hamano
  0 siblings, 0 replies; 74+ messages in thread
From: Junio C Hamano @ 2020-09-09 20:43 UTC (permalink / raw)
  To: Lin Sun; +Cc: sunlin via GitGitGadget, git, sunlin

Thanks.  Will replace.

For those who are watching from the sideline, here is the patch inline.

-- >8 --
From: Lin Sun <lin.sun@zoom.us>
Date: Thu, 7 May 2020 07:31:14 +0800
Subject: [PATCH] Support auto-merge for meld to follow the vim-diff behavior
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
telling it to auto-merge non-conflicting parts and highlight the conflicting
parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
for detecting the `--auto-merge` option automatically.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/config/mergetool.txt | 10 ++++
 builtin/config.c                   | 17 ++++++
 mergetools/meld                    | 85 ++++++++++++++++++++++++------
 3 files changed, 96 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..16a27443a3 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	When the `--auto-merge` is given, meld will merge all non-conflicting
+	parts automatically, highlight the conflicting parts and wait for
+	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
+	Git to unconditionally use the `--auto-merge` option with `meld`.
+	Setting this value to `auto` makes git detect whether `--auto-merge`
+	is supported and will only use `--auto-merge` when available.  A
+	value of `false` avoids using `--auto-merge` altogether, and is the
+	default value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/builtin/config.c b/builtin/config.c
index ee4aef6a35..7891e070a4 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -65,6 +65,7 @@ static int show_scope;
 #define TYPE_PATH		4
 #define TYPE_EXPIRY_DATE	5
 #define TYPE_COLOR		6
+#define TYPE_BOOL_OR_STR	7
 
 #define OPT_CALLBACK_VALUE(s, l, v, h, i) \
 	{ OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
@@ -94,6 +95,8 @@ static int option_parse_type(const struct option *opt, const char *arg,
 			new_type = TYPE_INT;
 		else if (!strcmp(arg, "bool-or-int"))
 			new_type = TYPE_BOOL_OR_INT;
+		else if (!strcmp(arg, "bool-or-str"))
+			new_type = TYPE_BOOL_OR_STR;
 		else if (!strcmp(arg, "path"))
 			new_type = TYPE_PATH;
 		else if (!strcmp(arg, "expiry-date"))
@@ -149,6 +152,7 @@ static struct option builtin_config_options[] = {
 	OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
 	OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT),
 	OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
+	OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR),
 	OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
 	OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
 	OPT_GROUP(N_("Other")),
@@ -250,6 +254,12 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
 				strbuf_addstr(buf, v ? "true" : "false");
 			else
 				strbuf_addf(buf, "%d", v);
+		} else if (type == TYPE_BOOL_OR_STR) {
+			int v = git_parse_maybe_bool(value_);
+			if (v < 0)
+				strbuf_addstr(buf, value_);
+			else
+				strbuf_addstr(buf, v ? "true" : "false");
 		} else if (type == TYPE_PATH) {
 			const char *v;
 			if (git_config_pathname(&v, key_, value_) < 0)
@@ -411,6 +421,13 @@ static char *normalize_value(const char *key, const char *value)
 		else
 			return xstrdup(v ? "true" : "false");
 	}
+	if (type == TYPE_BOOL_OR_STR) {
+		int v = git_parse_maybe_bool(value);
+		if (v < 0)
+			return xstrdup(value);
+		else
+			return xstrdup(v ? "true" : "false");
+	}
 	if (type == TYPE_COLOR) {
 		char v[COLOR_MAXLEN];
 		if (git_config_color(v, key, value))
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..aab4ebb935 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,87 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "$meld_help_msg"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$("$meld_path" --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "$meld_has_output_option"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true | false)
+			: use configured value
+			;;
+		*)
+			: empty or invalid configured value, detecting "--output" automatically
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="* | *'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "$meld_use_auto_merge_option"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_use_auto_merge_option=$(
+			git config --bool-or-str mergetool.meld.useAutoMerge
+		)
+		case "$meld_use_auto_merge_option" in
+		true | false)
+			: use well formatted boolean value
+			;;
+		auto)
+			# testing the "--auto-merge" option only if config is "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--auto-merge"* | *'[OPTION...]'*)
+				meld_use_auto_merge_option=true
+				;;
+			*)
+				meld_use_auto_merge_option=false
+				;;
+			esac
+			;;
+		"")
+			meld_use_auto_merge_option=false
+			;;
+		*)
+			die "unknown mergetool.meld.useAutoMerge: $meld_use_auto_merge_option"
+			;;
+		esac
 	fi
 }
-- 
2.28.0-558-g7a0184fd7b


^ permalink raw reply related	[flat|nested] 74+ messages in thread

* [PATCH v18] Support auto-merge for meld to follow the vim-diff behavior
  2020-07-12 23:32                               ` [PATCH v17] " sunlin via GitGitGadget
  2020-07-24  0:58                                 ` Junio C Hamano
@ 2020-09-12  7:21                                 ` sunlin via GitGitGadget
  2020-09-14 20:07                                   ` Junio C Hamano
  1 sibling, 1 reply; 74+ messages in thread
From: sunlin via GitGitGadget @ 2020-09-12  7:21 UTC (permalink / raw)
  To: git; +Cc: Lin Sun, sunlin, Lin Sun

From: Lin Sun <lin.sun@zoom.us>

Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
telling it to auto-merge non-conflicting parts and highlight the conflicting
parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
for detecting the `--auto-merge` option automatically.

Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Lin Sun <lin.sun@zoom.us>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
    Enable auto-merge for meld to follow the vimdiff beharior
    
    Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
    the mergetool "vimdiff" will merge the no-conflict changes and highlight
    the conflict parts. This patch will make the mergetool "meld" similar to
    "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-781%2Fsunlin7%2Fmaster-v18
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-781/sunlin7/master-v18
Pull-Request: https://github.com/git/git/pull/781

Range-diff vs v17:

 1:  ce4e4cbfc0 ! 1:  1b931e610d Support auto-merge for meld to follow the vim-diff behavior
     @@ Documentation/config/mergetool.txt: mergetool.meld.hasOutput::
       	After performing a merge, the original file with conflict markers
       	can be saved as a file with a `.orig` extension.  If this variable
      
     + ## builtin/config.c ##
     +@@ builtin/config.c: static int show_scope;
     + #define TYPE_PATH		4
     + #define TYPE_EXPIRY_DATE	5
     + #define TYPE_COLOR		6
     ++#define TYPE_BOOL_OR_STR	7
     + 
     + #define OPT_CALLBACK_VALUE(s, l, v, h, i) \
     + 	{ OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
     +@@ builtin/config.c: static int option_parse_type(const struct option *opt, const char *arg,
     + 			new_type = TYPE_INT;
     + 		else if (!strcmp(arg, "bool-or-int"))
     + 			new_type = TYPE_BOOL_OR_INT;
     ++		else if (!strcmp(arg, "bool-or-str"))
     ++			new_type = TYPE_BOOL_OR_STR;
     + 		else if (!strcmp(arg, "path"))
     + 			new_type = TYPE_PATH;
     + 		else if (!strcmp(arg, "expiry-date"))
     +@@ builtin/config.c: static struct option builtin_config_options[] = {
     + 	OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
     + 	OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT),
     + 	OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
     ++	OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR),
     + 	OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
     + 	OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
     + 	OPT_GROUP(N_("Other")),
     +@@ builtin/config.c: static int format_config(struct strbuf *buf, const char *key_, const char *value
     + 				strbuf_addstr(buf, v ? "true" : "false");
     + 			else
     + 				strbuf_addf(buf, "%d", v);
     ++		} else if (type == TYPE_BOOL_OR_STR) {
     ++			int v = git_parse_maybe_bool(value_);
     ++			if (v < 0)
     ++				strbuf_addstr(buf, value_);
     ++			else
     ++				strbuf_addstr(buf, v ? "true" : "false");
     + 		} else if (type == TYPE_PATH) {
     + 			const char *v;
     + 			if (git_config_pathname(&v, key_, value_) < 0)
     +@@ builtin/config.c: static char *normalize_value(const char *key, const char *value)
     + 		else
     + 			return xstrdup(v ? "true" : "false");
     + 	}
     ++	if (type == TYPE_BOOL_OR_STR) {
     ++		int v = git_parse_maybe_bool(value);
     ++		if (v < 0)
     ++			return xstrdup(value);
     ++		else
     ++			return xstrdup(v ? "true" : "false");
     ++	}
     + 	if (type == TYPE_COLOR) {
     + 		char v[COLOR_MAXLEN];
     + 		if (git_config_color(v, key, value))
     +
       ## mergetools/meld ##
      @@ mergetools/meld: diff_cmd () {
       }
     @@ mergetools/meld: diff_cmd () {
      -		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
      +		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
      +		case "$meld_has_output_option" in
     -+		true|false)
     ++		true | false)
      +			: use configured value
      +			;;
      +		*)
     @@ mergetools/meld: diff_cmd () {
      +			init_meld_help_msg
      +
      +			case "$meld_help_msg" in
     -+			*"--output="*|*'[OPTION...]'*)
     ++			*"--output="* | *'[OPTION...]'*)
      +				# All version that has [OPTION...] supports --output
      +				meld_has_output_option=true
      +				;;
     @@ mergetools/meld: diff_cmd () {
      -		meld_has_output_option=true
      -	else
      -		meld_has_output_option=false
     -+		meld_use_auto_merge_option=$(git config mergetool.meld.useAutoMerge)
     ++		meld_use_auto_merge_option=$(
     ++			git config --bool-or-str mergetool.meld.useAutoMerge
     ++		)
      +		case "$meld_use_auto_merge_option" in
     -+		true|false)
     ++		true | false)
      +			: use well formatted boolean value
      +			;;
      +		auto)
     @@ mergetools/meld: diff_cmd () {
      +			init_meld_help_msg
      +
      +			case "$meld_help_msg" in
     -+			*"--auto-merge"*|*'[OPTION...]'*)
     ++			*"--auto-merge"* | *'[OPTION...]'*)
      +				meld_use_auto_merge_option=true
      +				;;
      +			*)
     @@ mergetools/meld: diff_cmd () {
      +				;;
      +			esac
      +			;;
     ++		"")
     ++			meld_use_auto_merge_option=false
     ++			;;
      +		*)
     -+			# try other boolean value with git
     -+			if meld_use_auto_merge_option=$(
     -+				 git config --bool mergetool.meld.useAutoMerge)
     -+			then
     -+				: use normalized boolean value
     -+			else
     -+				meld_use_auto_merge_option=false
     -+			fi
     ++			die "unknown mergetool.meld.useAutoMerge: $meld_use_auto_merge_option"
      +			;;
      +		esac
       	fi


 Documentation/config/mergetool.txt | 10 ++++
 builtin/config.c                   | 17 ++++++
 mergetools/meld                    | 85 ++++++++++++++++++++++++------
 3 files changed, 96 insertions(+), 16 deletions(-)

diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 09ed31dbfa..16a27443a3 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
 	to `true` tells Git to unconditionally use the `--output` option,
 	and `false` avoids using `--output`.
 
+mergetool.meld.useAutoMerge::
+	When the `--auto-merge` is given, meld will merge all non-conflicting
+	parts automatically, highlight the conflicting parts and wait for
+	user decision.  Setting `mergetool.meld.useAutoMerge` to `true` tells
+	Git to unconditionally use the `--auto-merge` option with `meld`.
+	Setting this value to `auto` makes git detect whether `--auto-merge`
+	is supported and will only use `--auto-merge` when available.  A
+	value of `false` avoids using `--auto-merge` altogether, and is the
+	default value.
+
 mergetool.keepBackup::
 	After performing a merge, the original file with conflict markers
 	can be saved as a file with a `.orig` extension.  If this variable
diff --git a/builtin/config.c b/builtin/config.c
index 5e39f61885..ae077c9f2f 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -65,6 +65,7 @@ static int show_scope;
 #define TYPE_PATH		4
 #define TYPE_EXPIRY_DATE	5
 #define TYPE_COLOR		6
+#define TYPE_BOOL_OR_STR	7
 
 #define OPT_CALLBACK_VALUE(s, l, v, h, i) \
 	{ OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
@@ -94,6 +95,8 @@ static int option_parse_type(const struct option *opt, const char *arg,
 			new_type = TYPE_INT;
 		else if (!strcmp(arg, "bool-or-int"))
 			new_type = TYPE_BOOL_OR_INT;
+		else if (!strcmp(arg, "bool-or-str"))
+			new_type = TYPE_BOOL_OR_STR;
 		else if (!strcmp(arg, "path"))
 			new_type = TYPE_PATH;
 		else if (!strcmp(arg, "expiry-date"))
@@ -149,6 +152,7 @@ static struct option builtin_config_options[] = {
 	OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
 	OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT),
 	OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
+	OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR),
 	OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
 	OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
 	OPT_GROUP(N_("Other")),
@@ -250,6 +254,12 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
 				strbuf_addstr(buf, v ? "true" : "false");
 			else
 				strbuf_addf(buf, "%d", v);
+		} else if (type == TYPE_BOOL_OR_STR) {
+			int v = git_parse_maybe_bool(value_);
+			if (v < 0)
+				strbuf_addstr(buf, value_);
+			else
+				strbuf_addstr(buf, v ? "true" : "false");
 		} else if (type == TYPE_PATH) {
 			const char *v;
 			if (git_config_pathname(&v, key_, value_) < 0)
@@ -411,6 +421,13 @@ static char *normalize_value(const char *key, const char *value)
 		else
 			return xstrdup(v ? "true" : "false");
 	}
+	if (type == TYPE_BOOL_OR_STR) {
+		int v = git_parse_maybe_bool(value);
+		if (v < 0)
+			return xstrdup(value);
+		else
+			return xstrdup(v ? "true" : "false");
+	}
 	if (type == TYPE_COLOR) {
 		char v[COLOR_MAXLEN];
 		if (git_config_color(v, key, value))
diff --git a/mergetools/meld b/mergetools/meld
index 7a08470f88..aab4ebb935 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -3,34 +3,87 @@ diff_cmd () {
 }
 
 merge_cmd () {
-	if test -z "${meld_has_output_option:+set}"
+	check_meld_for_features
+
+	option_auto_merge=
+	if test "$meld_use_auto_merge_option" = true
 	then
-		check_meld_for_output_version
+		option_auto_merge="--auto-merge"
 	fi
 
 	if test "$meld_has_output_option" = true
 	then
-		"$merge_tool_path" --output="$MERGED" \
+		"$merge_tool_path" $option_auto_merge --output="$MERGED" \
 			"$LOCAL" "$BASE" "$REMOTE"
 	else
-		"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
+		"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
 	fi
 }
 
-# Check whether we should use 'meld --output <file>'
-check_meld_for_output_version () {
-	meld_path="$(git config mergetool.meld.path)"
-	meld_path="${meld_path:-meld}"
+# Get meld help message
+init_meld_help_msg () {
+	if test -z "$meld_help_msg"
+	then
+		meld_path="$(git config mergetool.meld.path || echo meld)"
+		meld_help_msg=$("$meld_path" --help 2>&1)
+	fi
+}
 
-	if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+# Check the features and set flags
+check_meld_for_features () {
+	# Check whether we should use 'meld --output <file>'
+	if test -z "$meld_has_output_option"
 	then
-		: use configured value
-	elif "$meld_path" --help 2>&1 |
-		grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
+		meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
+		case "$meld_has_output_option" in
+		true | false)
+			: use configured value
+			;;
+		*)
+			: empty or invalid configured value, detecting "--output" automatically
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--output="* | *'[OPTION...]'*)
+				# All version that has [OPTION...] supports --output
+				meld_has_output_option=true
+				;;
+			*)
+				meld_has_output_option=false
+				;;
+			esac
+			;;
+		esac
+	fi
+	# Check whether we should use 'meld --auto-merge ...'
+	if test -z "$meld_use_auto_merge_option"
 	then
-		: old ones mention --output and new ones just say OPTION...
-		meld_has_output_option=true
-	else
-		meld_has_output_option=false
+		meld_use_auto_merge_option=$(
+			git config --bool-or-str mergetool.meld.useAutoMerge
+		)
+		case "$meld_use_auto_merge_option" in
+		true | false)
+			: use well formatted boolean value
+			;;
+		auto)
+			# testing the "--auto-merge" option only if config is "auto"
+			init_meld_help_msg
+
+			case "$meld_help_msg" in
+			*"--auto-merge"* | *'[OPTION...]'*)
+				meld_use_auto_merge_option=true
+				;;
+			*)
+				meld_use_auto_merge_option=false
+				;;
+			esac
+			;;
+		"")
+			meld_use_auto_merge_option=false
+			;;
+		*)
+			die "unknown mergetool.meld.useAutoMerge: $meld_use_auto_merge_option"
+			;;
+		esac
 	fi
 }

base-commit: 3a238e539bcdfe3f9eb5010fd218640c1b499f7a
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 74+ messages in thread

* Re: [PATCH v18] Support auto-merge for meld to follow the vim-diff behavior
  2020-09-12  7:21                                 ` [PATCH v18] " sunlin via GitGitGadget
@ 2020-09-14 20:07                                   ` Junio C Hamano
  2020-09-15  0:55                                     ` Lin Sun
  0 siblings, 1 reply; 74+ messages in thread
From: Junio C Hamano @ 2020-09-14 20:07 UTC (permalink / raw)
  To: sunlin via GitGitGadget; +Cc: git, Lin Sun, sunlin

"sunlin via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: Lin Sun <lin.sun@zoom.us>
>
> Make the mergetool used with "meld" backend behave similarly to "vimdiff" by
> telling it to auto-merge non-conflicting parts and highlight the conflicting
> parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto`
> for detecting the `--auto-merge` option automatically.
>
> Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
> Helped-by: David Aguilar <davvid@gmail.com>
> Signed-off-by: Lin Sun <lin.sun@zoom.us>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
>     Enable auto-merge for meld to follow the vimdiff beharior
>     
>     Hi, the mergetool "meld" does NOT merge the no-conflict changes, while
>     the mergetool "vimdiff" will merge the no-conflict changes and highlight
>     the conflict parts. This patch will make the mergetool "meld" similar to
>     "vimdiff", auto-merge the no-conflict changes, highlight conflict parts.

Thanks.

^ permalink raw reply	[flat|nested] 74+ messages in thread

* Re: [PATCH v18] Support auto-merge for meld to follow the vim-diff behavior
  2020-09-14 20:07                                   ` Junio C Hamano
@ 2020-09-15  0:55                                     ` Lin Sun
  0 siblings, 0 replies; 74+ messages in thread
From: Lin Sun @ 2020-09-15  0:55 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: sunlin via GitGitGadget, git, sunlin

Hi Junio,

> conflict …
It’s my typo. Thank you for fixing it.

Best Regards
Lin Sun

^ permalink raw reply	[flat|nested] 74+ messages in thread

end of thread, other threads:[~2020-09-15  0:55 UTC | newest]

Thread overview: 74+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-08  1:25 [PATCH] Enable auto-merge for meld to follow the vim-diff beharior sunlin via GitGitGadget
2020-06-08  9:49 ` Pratyush Yadav
2020-06-09  3:19 ` [PATCH v2] " sunlin via GitGitGadget
2020-06-29  7:07   ` [PATCH v3] " sunlin via GitGitGadget
2020-06-29 12:32     ` Fwd: " Git Gadget
2020-06-30  0:06     ` Junio C Hamano
2020-06-30  7:42       ` David Aguilar
2020-06-30 11:25         ` lin.sun
2020-06-30 11:37         ` lin.sun
2020-06-30 15:51         ` Junio C Hamano
2020-06-30 11:26     ` [PATCH v4] " sunlin via GitGitGadget
2020-06-30 16:23       ` Đoàn Trần Công Danh
2020-06-30 23:01         ` Đoàn Trần Công Danh
2020-07-01  7:06       ` [PATCH v5] " sunlin via GitGitGadget
2020-07-01  7:23         ` lin.sun
2020-07-01 18:19           ` David Aguilar
2020-07-01 14:17         ` Đoàn Trần Công Danh
2020-07-01 15:32           ` lin.sun
2020-07-01 22:02             ` lin.sun
2020-07-01 23:06               ` Đoàn Trần Công Danh
2020-07-01 19:51           ` Junio C Hamano
2020-07-02  0:20             ` lin.sun
2020-07-02  0:44         ` [PATCH v6] Support auto-merge for meld to follow the vim-diff behavior sunlin via GitGitGadget
2020-07-02  2:35           ` lin.sun
2020-07-03  1:50           ` Junio C Hamano
2020-07-03  3:53             ` lin.sun
2020-07-03 15:58             ` Đoàn Trần Công Danh
2020-07-06  6:23               ` Junio C Hamano
2020-07-03  3:26           ` [PATCH v7] " sunlin via GitGitGadget
2020-07-03  4:50             ` Junio C Hamano
2020-07-04  1:18               ` lin.sun
2020-07-06  2:36                 ` lin.sun
2020-07-04  1:16             ` [PATCH v8] " sunlin via GitGitGadget
2020-07-06  2:27               ` [PATCH v9] " sunlin via GitGitGadget
2020-07-06 22:31                 ` Junio C Hamano
2020-07-07  6:34                   ` lin.sun
2020-07-07 16:43                     ` Junio C Hamano
2020-07-08  1:20                       ` lin.sun
2020-07-08  1:51                         ` Junio C Hamano
2020-07-07  6:17                 ` [PATCH v10] " sunlin via GitGitGadget
2020-07-07  6:25                   ` Junio C Hamano
2020-07-07  6:38                     ` lin.sun
2020-07-07  6:44                       ` lin.sun
2020-07-07  7:13                   ` [PATCH v11] " sunlin via GitGitGadget
2020-07-07 15:31                     ` Đoàn Trần Công Danh
2020-07-08  0:57                       ` lin.sun
2020-07-08  3:25                     ` [PATCH v12] " sunlin via GitGitGadget
2020-07-08  3:31                       ` lin.sun
2020-07-08 15:42                       ` Đoàn Trần Công Danh
2020-07-08 15:47                         ` lin.sun
2020-07-09  0:35                       ` [PATCH v13] " sunlin via GitGitGadget
2020-07-09  0:39                         ` lin.sun
2020-07-09  2:42                         ` Junio C Hamano
2020-07-09  2:56                         ` Junio C Hamano
2020-07-09  3:24                           ` lin.sun
2020-07-09  4:49                             ` Junio C Hamano
2020-07-09  5:31                               ` Junio C Hamano
2020-07-12 14:07                             ` lin.sun
2020-07-12 23:38                               ` lin.sun
2020-07-09  4:28                         ` [PATCH v14] " sunlin via GitGitGadget
2020-07-12  8:39                           ` [PATCH v15] " sunlin via GitGitGadget
2020-07-12  9:08                             ` [PATCH v16] " sunlin via GitGitGadget
2020-07-12 18:04                               ` Junio C Hamano
2020-07-12 23:26                                 ` lin.sun
2020-07-13  5:14                                 ` Junio C Hamano
2020-07-13  6:58                                   ` lin.sun
2020-07-12 23:32                               ` [PATCH v17] " sunlin via GitGitGadget
2020-07-24  0:58                                 ` Junio C Hamano
2020-09-03 21:48                                   ` Junio C Hamano
     [not found]                                     ` <C35AC799-B4F6-4A5E-92FA-21065310B379@hxcore.ol>
2020-09-09  1:31                                       ` Lin Sun
2020-09-09 20:43                                         ` Junio C Hamano
2020-09-12  7:21                                 ` [PATCH v18] " sunlin via GitGitGadget
2020-09-14 20:07                                   ` Junio C Hamano
2020-09-15  0:55                                     ` Lin Sun

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).