Bug 2048309

Summary: Git now ignores the pull.rebase configuration setting when you run 'git pull'
Product: [Fedora] Fedora Reporter: Chris Siebenmann <cks-rhbugzilla>
Component: gitAssignee: Todd Zullinger <tmz>
Status: CLOSED CANTFIX QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 34CC: amahdal, besser82, chrisw, johannes, opohorel, pstodulk, sebastian.kisela, tmz
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2022-02-02 15:44:20 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Chris Siebenmann 2022-01-30 22:14:53 UTC
Description of problem:
Starting recently (apparently in the Fedora 34 git-2.34.1-1.fc34.x86_64), 'git pull' ignores a configured setting of pull.rebase being true and does not rebase. 'git pull --rebase' continues to work.

Version-Release number of selected component (if applicable):
git-2.34.1-1.fc34.x86_64

How reproducible:
Always

Steps to Reproduce:
1. Arrange a repository with additional commits over upstream to rebase and then set 'git config pull.rebase true' in it.
2. Pull with plain 'git pull'

Actual results:

: hawklords.cs ; git config pull.rebase
true
: hawklords.cs ; git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
: hawklords.cs ; git pull
remote: Enumerating objects: 31, done.
remote: Counting objects: 100% (26/26), done.
remote: Total 31 (delta 26), reused 26 (delta 26), pack-reused 5
Unpacking objects: 100% (31/31), 49.96 KiB | 763.00 KiB/s, done.
From https://github.com/darktable-org/darktable
   624ff0ff4..d535db9d8  master          -> origin/master
   f8c72bea6..20982aac1  darktable-3.8.x -> origin/darktable-3.8.x
fatal: Not possible to fast-forward, aborting.
: hawklords.cs ; git pull --rebase
 data/themes/darktable.css |  6 +--
 src/common/exif.cc        | 93 +++++++++++++++++++++++++++++++++++------------
 src/common/history.c      | 20 +++++++++-
 src/common/history.h      |  5 ++-
 src/develop/develop.c     |  8 ++--
 src/gui/gtk.c             |  8 +---
 6 files changed, 97 insertions(+), 43 deletions(-)
Successfully rebased and updated refs/heads/master.

Expected results:
The 'git pull' acted like 'git pull --rebase' and automatically rebased.

Comment 1 Todd Zullinger 2022-01-31 02:15:05 UTC
You may have a `pull.ff` setting which is affecting your pull.  What does:

  git config --show-origin --show-scope --get-regexp 'pull\.(ff|rebase)'

output?

That would explain why `git pull --rebase` continues to work.  The interaction of the various pull ff/merge/rebase options has had a lot of discussion upstream.  I'm not sure anyone's entirely happy with how complicated and convoluted it can be in practice.

You can countermand a global `pull.ff` locally via `git config pull.ff false`.  But that isn't quite the same as having `pull.ff` unset, so it's likely preferable to only set `pull.ff` locally.

Comment 2 Chris Siebenmann 2022-01-31 14:24:06 UTC
I have pull.ff set globally because I want it to be the default behavior (I have a lot of tracking repos that should only ever fast-forward, especially on a plain pull):

global  file:/homes/hawklords/cks/.gitconfig    pull.ff only
local   file:.git/config        pull.rebase true

This appears to be a Git behavior change, because it certainly used to work.

Comment 3 Todd Zullinger 2022-01-31 15:52:19 UTC
It certainly has changed, the release notes for 2.34.0 mention this:

 * "git pull" had various corner cases that were not well thought out
   around its --rebase backend, e.g. "git pull --ff-only" did not stop
   but went ahead and rebased when the history on other side is not a
   descendant of our history.  The series tries to fix them up.

https://github.com/git/git/blob/master/Documentation/RelNotes/2.34.0.txt#L206-L209

If you want to default to `pull.ff only` globally, then you'll need to use `git pull --rebase` when you want to override it or set pull.ff in individual repos (if you're alright with how thay behaves).

Comment 4 Chris Siebenmann 2022-01-31 21:00:50 UTC
It appears to work to set 'pull.ff only' globally, then locally in a repository set 'pull.ff true' and 'pull.rebase true'. The interaction of all of these is not clear to me from the current manual pages; it's possible that 'pull.ff only' is effectively the default even if not configured globally.

Comment 5 Todd Zullinger 2022-01-31 21:37:19 UTC
It's certainly not an easy area to understand and work with, that's true.

I don't know if any of the following will help or hurt, but here's a little more detail about it...

If pull.ff is not set, it isn't _quite_ the same as when it's set to any of only, true, or false, AFAIK.

The code for this is in builtin/pull.c:config_get_ff(), which has the comment:

  /**
   * 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.
   */

Source: https://github.com/git/git/blob/v2.34.1/builtin/pull.c#L298-L322

Elsewhere in builtin/pull.c, in the main command body, git does:

  opt_ff = xstrdup_or_null(config_get_ff());
  if (opt_rebase >= 0 && opt_ff && !strcmp(opt_ff, "--ff-only"))
      opt_ff = "--ff";

Source: https://github.com/git/git/blob/v2.34.1/builtin/pull.c#L1009-L1024

There have been many long threads on the git list regarding how to improve this without causing existing users pain.  There are a lot of combinations and no one has yet come up with a clearly superior method of getting from where things are now to where they might ideally be if it were being designed from scratch today.  Felipe Contreras submitted a few series aiming to create a pull.mode config to provide one place to configure pull rather than having pull.ff, pull.rebase, and merge.ff all interact.  But that was mired in various issues (many of them seemingly tangential to the change, sadly).

The change in f34 was designed to avoid a common pitfall where users configure pull.rebase and then cause themselves and/or others a lot of grief with merge conflicts or lost data.

I'll close this as either NOTABUG or WONTFIX.  Neither are entirely true, but they're the closest available options, I think. :)