git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
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 v16] Support auto-merge for meld to follow the vim-diff behavior
Date: Sun, 12 Jul 2020 11:04:14 -0700	[thread overview]
Message-ID: <xmqqzh84pq3l.fsf@gitster.c.googlers.com> (raw)
In-Reply-To: <pull.781.v16.git.git.1594544903477.gitgitgadget@gmail.com> (sunlin via GitGitGadget's message of "Sun, 12 Jul 2020 09:08:23 +0000")

"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.

  reply	other threads:[~2020-07-12 18:05 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqzh84pq3l.fsf@gitster.c.googlers.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@gmail.com \
    --cc=lin.sun@zoom.us \
    --cc=sunlin7@yahoo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).