git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Alex Henrie <alexhenrie24@gmail.com>
Cc: git@vger.kernel.org, felipe.contreras@gmail.com,
	ray@ameretat.dev, peff@peff.net, vondruch@redhat.com,
	tytso@mit.edu
Subject: Re: [RFC 2/2] pull: default pull.ff to "only" when pull.rebase is not set either
Date: Wed, 02 Dec 2020 18:21:01 -0800	[thread overview]
Message-ID: <xmqqmtyviq9e.fsf@gitster.c.googlers.com> (raw)
In-Reply-To: <20201125020931.248427-2-alexhenrie24@gmail.com> (Alex Henrie's message of "Tue, 24 Nov 2020 19:09:31 -0700")

Alex Henrie <alexhenrie24@gmail.com> writes:

> diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt
> index eb0aabd396..1eb79e2939 100644
> --- a/Documentation/merge-options.txt
> +++ b/Documentation/merge-options.txt
> @@ -43,10 +43,16 @@ set to `no` at the beginning of them.
>  --no-ff::
>  --ff-only::
>  	Specifies how a merge is handled when the merged-in history is
> -	already a descendant of the current history.  `--ff` is the
> -	default unless merging an annotated (and possibly signed) tag
> -	that is not stored in its natural place in the `refs/tags/`
> -	hierarchy, in which case `--no-ff` is assumed.
> +	already a descendant of the current history.
> +	+
> +	In `git pull`, `--ff-only` is the default unless `--rebase` or
> +	`--no-rebase` is specified, in which case the default is `--ff`.
> +	However, the default changes again to `--no-ff` in the unlikely
> +	scenario where an annotated (and possibly signed) tag that is not
> +	stored in its natural place in the `refs/tags/` hierarchy is being
> +	merged.
> +	+
> +	In `git merge`, `--ff` is always the default.

As we can see one line below, I think these new paragraphs must be
dedented.

> +
> With `--ff`, when possible resolve the merge as a fast-forward (only
> update the branch pointer to match the merged branch; do not create a
> diff --git a/builtin/pull.c b/builtin/pull.c
> index 4d80efe5b7..c703560a77 100644
> --- a/builtin/pull.c
> +++ b/builtin/pull.c
> @@ -292,17 +292,21 @@ static void set_reflog_message(int argc, const char **argv)
>  }
>  
>  /**
> - * If pull.ff is unset, returns NULL. If pull.ff is "true", returns "--ff". If
> - * pull.ff is "false", returns "--no-ff". If pull.ff is "only", returns
> - * "--ff-only". Otherwise, if pull.ff is set to an invalid value, die with an
> - * error.
> + * If pull.ff is unset, returns NULL if pull.rebase is set or "--ff-only" if
> + * pull.rebase is not set. If pull.ff is "true", returns "--ff". If pull.ff is
> + * "false", returns "--no-ff". If pull.ff is "only", returns "--ff-only".
> + * Otherwise, if pull.ff is set to an invalid value, die with an error.
>   */
>  static const char *config_get_ff(void)
>  {
>  	const char *value;
>  
> -	if (git_config_get_value("pull.ff", &value))
> -		return NULL;
> +	if (git_config_get_value("pull.ff", &value)) {
> +		if (opt_rebase < 0)
> +			return "--ff-only";
> +		else
> +			return NULL;
> +	}

So, the idea is that we currently return NULL when pull.ff is set,
but now we also check "pull.rebase" etc. and give "--ff-only" when
we did not choose --[no-]rebase and lack the configuration.  So the
default (i.e. when pull.ff and pull.rebase are not set) would be as
if the user said

	git pull --ff-only --no-rebase

I am not seeing what problem this tries to solve, exactly, though.

I would have expected that for those who did not choose between
merge and rebase (either with the pull.rebase configuration or from
the command line --[no-]rebase option) the command would behave as
if --ff-only is given, regardless of how pull.ff configuration is
set.  That way, those who are unconfigured will just follow along
what happens at the upstream, until they have their own development,
at which point "--ff-only" can no longer be satisfied and their
"pull" would fail until they choose how to consolidate their work
with the upstream.

And once they choose between merge and rebase, we no longer have to
force "--ff-only" and things will start working as specified by the
user.  In other words, what I would have expected in the previous
paragraph is a minimum and natural extension of the current "you
must pick between merge and rebase or you'll get an advice message
until you do so"---we do not warn for those who haven't chosen as
long as they are only riding along with the upstream without having
their own development.

Having said that, back to what you did in your patch (read: the
following comments are not about achieving what I would have
expected; it is about what this patch from you seems to be trying to
do).

The above code in config_get_ff() obviously depends on the order in
the caller to make this call and determine opt_rebase's value and I
see you tweaked the caller to call config_get_rebase() before it
makes a call to this helper.

It feels a bit brittle now because of this subtle dependency.

Perhaps it is a good idea to introduce another helper that
cmd_pull() calls, and make that helper call these two helpers that
determine the value of opt_rebase and opt_ff, to hide the
dependency.

> @@ -322,7 +326,7 @@ static const char *config_get_ff(void)
>   * value of "branch.$curr_branch.rebase", where $curr_branch is the current
>   * branch, and if HEAD is detached or the configuration key does not exist,
>   * looks for the value of "pull.rebase". If both configuration keys do not
> - * exist, returns REBASE_FALSE.
> + * exist, returns REBASE_INVALID.
>   */
>  static enum rebase_type config_get_rebase(void)
>  {
> @@ -344,23 +348,7 @@ static enum rebase_type config_get_rebase(void)
>  	if (!git_config_get_value("pull.rebase", &value))
>  		return parse_config_rebase("pull.rebase", value, 1);
>  
> -	if (opt_verbosity >= 0 && !opt_ff) {
> -		warning(_("Starting in Git 3.0, the default behavior of `git pull` will change\n"
> -			"when it is not specified how to reconcile divergent branches. You can\n"
> -			"squelch this message by running one of the following commands sometime\n"
> -			"before your next pull:\n"
> -			"\n"
> -			"  git config pull.rebase false  # merge (the current default)\n"
> -			"  git config pull.rebase true   # rebase\n"
> -			"  git config pull.ff only       # fast-forward only (the future default)\n"
> -			"\n"
> -			"You can replace \"git config\" with \"git config --global\" to set a default\n"
> -			"preference for all repositories. You can also pass --rebase, --no-rebase,\n"
> -			"or --ff-only on the command line to override the configured default per\n"
> -			"invocation.\n"));
> -	}
> -
> -	return REBASE_FALSE;
> +	return REBASE_INVALID;
>  }

Hmph, and who reacts to this REBASE_INVALID value?  Shouldn't there
be something that catches this INVALID value and stop/complain?

>  
>  /**
> @@ -931,11 +919,14 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>  
>  	parse_repo_refspecs(argc, argv, &repo, &refspecs);
>  
> +	if (opt_rebase < 0)
> +		opt_rebase = config_get_rebase();
> +
>  	if (!opt_ff)
>  		opt_ff = xstrdup_or_null(config_get_ff());
>  
>  	if (opt_rebase < 0)
> -		opt_rebase = config_get_rebase();
> +		opt_rebase = REBASE_FALSE;
>  
>  	if (read_cache_unmerged())
>  		die_resolve_conflict("pull");

Another thing.  Does "git pull --rebase --ff-only" behave sensibly?
"rebase our history on top of theirs only if we are truly ahead" is
a bit strange way to say "we only ride along without having our own
development, and once we discover we have our own stuff, stop us".
IIRC, "git pull --rebase" ignored the "--ff-only" request and
rebased our own stuff on top of their history anyway, which we would
want to fix.

  parent reply	other threads:[~2020-12-03  2:24 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-25  2:09 [RFC 1/2] pull: warn that pulling will not merge by default in Git 3.0 Alex Henrie
2020-11-25  2:09 ` [RFC 2/2] pull: default pull.ff to "only" when pull.rebase is not set either Alex Henrie
2020-11-25  3:45   ` Felipe Contreras
2020-11-25  3:47     ` Felipe Contreras
2020-11-25 13:25       ` Philip Oakley
2020-12-02  4:43         ` Felipe Contreras
2020-12-03  2:21   ` Junio C Hamano [this message]
2020-12-03  9:07     ` Felipe Contreras
2020-12-03 18:06       ` Junio C Hamano
2020-12-03 19:29         ` Junio C Hamano
2020-12-03 23:05           ` Felipe Contreras
2020-12-04  0:53             ` Jacob Keller
2020-12-04  2:06           ` Junio C Hamano
2020-12-04  6:37             ` Felipe Contreras
2020-12-04 19:37               ` Junio C Hamano
2020-12-04 21:11                 ` Felipe Contreras
2020-12-11 20:38     ` Alex Henrie
2020-12-12  1:08       ` Felipe Contreras

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=xmqqmtyviq9e.fsf@gitster.c.googlers.com \
    --to=gitster@pobox.com \
    --cc=alexhenrie24@gmail.com \
    --cc=felipe.contreras@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=peff@peff.net \
    --cc=ray@ameretat.dev \
    --cc=tytso@mit.edu \
    --cc=vondruch@redhat.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).