mark
mark

Reputation: 62804

git pull --rebase does not tolerate any modified files at all, contrary to git pull --no-rebase

Please, observe:

C:\xyz\55 [release/r-855 ↓1 +0 ~16 -0 !]> git pull --rebase
error: cannot pull with rebase: You have unstaged changes.
error: please commit or stash them.
C:\xyz\55 [release/r-855 ↓1 +0 ~16 -0 !]> git pull --no-rebase
From http://server.xyz.com:8080/tfs/defaultcollection/code/_git/xyz
 * [new branch]          wfm/tfs485759 -> origin/wfm/tfs485759
Updating 5f010c356..871eb9ca2
Fast-forward
 .../PayrollService/DAL/Payroll/PayRunDataProviderDAL.cs            | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
C:\xyz\55 [release/r-855 ≡ +0 ~16 -0 !]>

My conclusion is that git pull --rebase does not tolerate any modified files at all. This is unlike git pull --no-rebase, which is OK as long as none of the modified files clash with the new commits.

This kinda sucks.

Is my conclusion correct? Or can git pull --rebase be configured to behave more like --no-rebase when it comes to modified files?

Upvotes: 1

Views: 280

Answers (1)

VonC
VonC

Reputation: 1325117

git rebase, contrary to git merge (which is done by a normal pull) requires a clean working tree.
(git merge only requires that the merged files are not currently modified)

To get that clean working tree automatically, use git config --global rebase.autostash true.
That way, your git pull --rebase will work.


Warning though:

"git pull --rebase"(man) ignored the rebase.autostash configuration variable when the remote history is a descendant of our history, which has been corrected with Git 2.36 (Q2 2022).

See commit 3013d98 (13 Jan 2022) by Philippe Blain (phil-blain).
(Merged by Junio C Hamano -- gitster -- in commit 7a9ae6d, 05 Feb 2022)

pull --rebase: honor rebase.autostash when fast-forwarding

Reported-by: Tilman Vogel
Helped-by: Junio C Hamano
Signed-off-by: Philippe Blain

"pull --rebase" internally uses the merge machinery when the other history is a descendant of ours (i.e.
perform fast-forward).
This came from this thread, where the discussion was started from a feature request to do so.

It is a bit hard to read the rationale behind it in the discussion, but it seems that it was an established fact for everybody involved that does not even need to be mentioned that fast-forwarding done with "rebase" was much undesirable than done with "merge", and more importantly, the result left by "merge" is as good as (or better than) that by "rebase".

Except for one thing.

Because "git merge"(man) does not (and should not) honor rebase.autostash, "git pull"(man) needs to read it and forward it when we use git merge as a (hopefully better) substitute for "git rebase"(man) during the fast-forwarding.

But we forgot to do so (we only add "--[no-]autostash" to the "git merge" command when git pull itself was invoked with --[no-]autostash" command line option.

Make sure "git merge" is run git with --autostash when rebase.autostash is set and used to fast-forward the history on behalf of rebase".

Incidentally this change also takes care of the case where

  • "git pull --rebase"(man) (without other command line options) is run
  • "rebase.autostash" is not set
  • The history fast-forwards

In such a case, "git merge" is run with an explicit --no-autostash to prevent it from honoring merge.autostash configuration, which is what we want.
After all, we want the "git merge" to pretend as if it is git rebase while being used for this purpose.

Upvotes: 1

Related Questions