git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* bug: `git pull --rebase` breaks in the presence of pushurls
@ 2025-12-07 21:55 Kartik Agaram
  2025-12-08 14:30 ` Phillip Wood
  0 siblings, 1 reply; 13+ messages in thread
From: Kartik Agaram @ 2025-12-07 21:55 UTC (permalink / raw)
  To: git

What did you do before the bug happened? (Steps to reproduce your issue)

1. Create a bare hub repo.

  mkdir hub
  cd hub
  git init --bare
  cd ..

2. Create a bare mirror of the hub.

  git clone --bare hub mirror

3. Create a working directory A and set its pushurls to hub and mirror.

  git clone hub A
  cd A
  git remote set-url --add --push origin `dirname $PWD`/hub
  git remote set-url --add --push origin `dirname $PWD`/mirror

4. Create commit 1 and push it to both.

  echo a > a
  git add .
  git commit -m 'commit 1'
  git push

5. Create a second working directory B without pushurls.

  cd ..
  git clone hub B
  cd B

6. Create commit 2 in working directory B and push it to hub.

  echo b > b
  git add .
  git commit -m 'commit 2'
  git push

7. Create commit 3 in working directory A and try unsuccessfully to push it.

  cd ../A
  echo c > c
  git add .
  git commit -m 'commit 3'
  git push

This throws an error when pushing to hub, but successfully pushes to mirror.

8. Try to fix the problem:

  git pull --rebase

This completes successfully.

What did you expect to happen? (Expected behavior)

git log in working directory A should show all 3 commits

What happened instead? (Actual behavior)

git log shows commits 1 and 2 (created in B).

What's different between what you expected and what actually happened?

Commit 3 which was locally created is lost after the `git pull --rebase`.

Anything else you want to add:

I first encountered it in git 2.51.0. Also found to be present on HEAD of https://github.com/git/git

Problem exists independent of ~/.gitconfig.

[System Info]
git version:
git version 2.52.0.199.gbdc5341ff6
cpu: x86_64
built from commit: bdc5341ff65278a3cc80b2e8a02a2f02aa1fac06
sizeof-long: 8
sizeof-size_t: 8
shell-path: /bin/sh
rust: disabled
libcurl: 8.16.0
OpenSSL: OpenSSL 3.5.3 16 Sep 2025
zlib: 1.3.1
SHA-1: SHA1_DC
SHA-256: SHA256_BLK
default-ref-format: files
default-hash: sha1
uname: Linux 6.12.48-1-MANJARO #1 SMP PREEMPT_DYNAMIC Fri, 19 Sep 2025 16:11:04 +0000 x86_64
compiler info: gnuc: 15.2
libc info: glibc: 2.42
$SHELL (typically, interactive shell): /usr/bin/zsh


[Enabled Hooks]

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

* Re: bug: `git pull --rebase` breaks in the presence of pushurls
  2025-12-07 21:55 bug: `git pull --rebase` breaks in the presence of pushurls Kartik Agaram
@ 2025-12-08 14:30 ` Phillip Wood
  2025-12-08 16:04   ` Phillip Wood
                     ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Phillip Wood @ 2025-12-08 14:30 UTC (permalink / raw)
  To: Kartik Agaram, git

Hi Kartik


On 07/12/2025 21:55, Kartik Agaram wrote:

Thanks for the easy reproducer

> 7. Create commit 3 in working directory A and try unsuccessfully to push it.
> 
>    cd ../A
>    echo c > c
>    git add .
>    git commit -m 'commit 3'
>    git push> > This throws an error when pushing to hub, but successfully pushes to 
mirror.

"git push" updates refs/remotes/origin/master when pushing to "mirror".

> 8. Try to fix the problem:
> 
>    git pull --rebase

"git pull" tries to find the fork point between origin/master and master 
which is the tip of master because "git push" just updated origin/master 
to point to the same commit as master.

Unfortunately I'm not sure there is an easy way to fix this. For now I'd 
recommend doing

	git fetch && git rebase --no-fork-point

instead of running "git pull --rebase". We should perhaps add a 
"--no-fork-point" option to "git pull" as this isn't the first time that 
the fork-point has caused problems [1]. There was a patch to do that at 
[2] but it was lacking tests.

Thanks

Phillip

[1] 
https://lore.kernel.org/git/6bebcee9-1315-4ec3-a49b-d767f0f67bf7@gmail.com/
[2] 
https://lore.kernel.org/git/06beff46-cdaf-91c8-e6a3-6557694af618@gmail.com/

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

* Re: bug: `git pull --rebase` breaks in the presence of pushurls
  2025-12-08 14:30 ` Phillip Wood
@ 2025-12-08 16:04   ` Phillip Wood
  2025-12-08 16:43   ` Kartik Agaram
  2025-12-08 22:24   ` Junio C Hamano
  2 siblings, 0 replies; 13+ messages in thread
From: Phillip Wood @ 2025-12-08 16:04 UTC (permalink / raw)
  To: Kartik Agaram, git

On 08/12/2025 14:30, Phillip Wood wrote:
> 
> Unfortunately I'm not sure there is an easy way to fix this.

Maybe we should skip the fork-point calculation if 
remote.<branch>.pushurl or remote.pushDefault are set?

Thanks

Phillip


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

* Re: bug: `git pull --rebase` breaks in the presence of pushurls
  2025-12-08 14:30 ` Phillip Wood
  2025-12-08 16:04   ` Phillip Wood
@ 2025-12-08 16:43   ` Kartik Agaram
  2025-12-08 22:24   ` Junio C Hamano
  2 siblings, 0 replies; 13+ messages in thread
From: Kartik Agaram @ 2025-12-08 16:43 UTC (permalink / raw)
  To: phillip.wood, git

> [for the successful pushurl] "git push" updated origin/master to point to the same commit as master.

Thank you, this is very helpful to help me understand what happened.

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

* Re: bug: `git pull --rebase` breaks in the presence of pushurls
  2025-12-08 14:30 ` Phillip Wood
  2025-12-08 16:04   ` Phillip Wood
  2025-12-08 16:43   ` Kartik Agaram
@ 2025-12-08 22:24   ` Junio C Hamano
  2025-12-09  1:48     ` Kartik Agaram
  2025-12-10 14:25     ` Phillip Wood
  2 siblings, 2 replies; 13+ messages in thread
From: Junio C Hamano @ 2025-12-08 22:24 UTC (permalink / raw)
  To: Phillip Wood; +Cc: Kartik Agaram, git

Phillip Wood <phillip.wood123@gmail.com> writes:

> "git push" updates refs/remotes/origin/master when pushing to "mirror".
>
>> 8. Try to fix the problem:
>> 
>>    git pull --rebase
>
> "git pull" tries to find the fork point between origin/master and master 
> which is the tip of master because "git push" just updated origin/master 
> to point to the same commit as master.
>
> Unfortunately I'm not sure there is an easy way to fix this. For now I'd 
> recommend doing
>
> 	git fetch && git rebase --no-fork-point
>
> instead of running "git pull --rebase".

Yeah, it is an integral part of "fetch" to update the
remote-tracking branches, so this is harder to fix.

It may be possible to stop doing the fork-point computation in the
"git rebase" phase, and instead do it _before_ we run "git fetch",
to figure out what part of our history needs to be transplanted on
top of the upstream, run "git fetch" (to let the tracking branches
updated), and then run "git rebase", telling it exactly what range
should be transplanted onto which commit to update the branch
currently checked out.  That would be a much larger change.


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

* Re: bug: `git pull --rebase` breaks in the presence of pushurls
  2025-12-08 22:24   ` Junio C Hamano
@ 2025-12-09  1:48     ` Kartik Agaram
  2025-12-09 16:03       ` Phillip Wood
  2025-12-10 14:25     ` Phillip Wood
  1 sibling, 1 reply; 13+ messages in thread
From: Kartik Agaram @ 2025-12-09  1:48 UTC (permalink / raw)
  To: Junio C Hamano, Phillip Wood; +Cc: git

Should `git push` perhaps only update refs/remotes/origin/master if push to all pushurls succeeds (with the same result)? It seems like that would fix this issue. Does it not work in other scenarios?

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

* Re: bug: `git pull --rebase` breaks in the presence of pushurls
  2025-12-09  1:48     ` Kartik Agaram
@ 2025-12-09 16:03       ` Phillip Wood
  0 siblings, 0 replies; 13+ messages in thread
From: Phillip Wood @ 2025-12-09 16:03 UTC (permalink / raw)
  To: Kartik Agaram, Junio C Hamano; +Cc: git

On 09/12/2025 01:48, Kartik Agaram wrote:
> Should `git push` perhaps only update refs/remotes/origin/master if push to all pushurls succeeds (with the same result)? It seems like that would fix this issue. Does it not work in other scenarios?

While that would help in your example, I don't think that helps in 
general as there is no guarantee that any of the push urls refer to the 
same server as the pull url. If you set a single push url that pushes to 
mirror in your example then "git pull --rebase" still drops the local 
commit. I'm a bit confused by remote.pushDefault as if I set that to a 
url rather than a remote then it does not update any remote tracking 
refs. I had assumed it would behave the same as remote.<remote>.pushurl.

Thanks

Phillip



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

* Re: bug: `git pull --rebase` breaks in the presence of pushurls
  2025-12-08 22:24   ` Junio C Hamano
  2025-12-09  1:48     ` Kartik Agaram
@ 2025-12-10 14:25     ` Phillip Wood
  2025-12-11  3:21       ` Junio C Hamano
  1 sibling, 1 reply; 13+ messages in thread
From: Phillip Wood @ 2025-12-10 14:25 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Kartik Agaram, git



On 08/12/2025 22:24, Junio C Hamano wrote:
> Phillip Wood <phillip.wood123@gmail.com> writes:
> 
>> "git push" updates refs/remotes/origin/master when pushing to "mirror".
>>
>>> 8. Try to fix the problem:
>>>
>>>     git pull --rebase
>>
>> "git pull" tries to find the fork point between origin/master and master
>> which is the tip of master because "git push" just updated origin/master
>> to point to the same commit as master.
>>
>> Unfortunately I'm not sure there is an easy way to fix this. For now I'd
>> recommend doing
>>
>> 	git fetch && git rebase --no-fork-point
>>
>> instead of running "git pull --rebase".
> 
> Yeah, it is an integral part of "fetch" to update the
> remote-tracking branches, so this is harder to fix.
> 
> It may be possible to stop doing the fork-point computation in the
> "git rebase" phase, and instead do it _before_ we run "git fetch",
> to figure out what part of our history needs to be transplanted on
> top of the upstream, run "git fetch" (to let the tracking branches
> updated), and then run "git rebase", telling it exactly what range
> should be transplanted onto which commit to update the branch
> currently checked out.  That would be a much larger change.

"git pull" already runs "git merge-base --fork-point" before it runs 
"git fetch". The problematic reflog entry comes from a previous push 
which pushes to a different server due to remote.<remote>.pushurl. 
Because we've just successfully pushed the local branch the fork point 
calculation thinks the remote tracking branch matches the local branch 
and so excludes all the local commits when we rebase but we didn't push 
it to the same server that we're fetching from. I wonder if we should 
disable the fork point calculation when there is a pushurl set.

Thanks

Phillip


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

* Re: bug: `git pull --rebase` breaks in the presence of pushurls
  2025-12-10 14:25     ` Phillip Wood
@ 2025-12-11  3:21       ` Junio C Hamano
  2025-12-11  5:35         ` K Jayatheerth
  2025-12-11 15:56         ` Phillip Wood
  0 siblings, 2 replies; 13+ messages in thread
From: Junio C Hamano @ 2025-12-11  3:21 UTC (permalink / raw)
  To: Phillip Wood; +Cc: Kartik Agaram, git

Phillip Wood <phillip.wood123@gmail.com> writes:

> "git pull" already runs "git merge-base --fork-point" before it runs 
> "git fetch". The problematic reflog entry comes from a previous push 
> which pushes to a different server due to remote.<remote>.pushurl. 

Ah, of course.  fork-point heuristics with a repository you yourself
push into would not make all that sense, since you are in control
when and what to push there in the first place :/.

> Because we've just successfully pushed the local branch the fork point 
> calculation thinks the remote tracking branch matches the local branch 
> and so excludes all the local commits when we rebase but we didn't push 
> it to the same server that we're fetching from. I wonder if we should 
> disable the fork point calculation when there is a pushurl set.

Tempting thought.  Or educate users with diagnoses and advise()?


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

* Re: bug: `git pull --rebase` breaks in the presence of pushurls
  2025-12-11  3:21       ` Junio C Hamano
@ 2025-12-11  5:35         ` K Jayatheerth
  2025-12-11 15:54           ` Phillip Wood
  2025-12-11 15:56         ` Phillip Wood
  1 sibling, 1 reply; 13+ messages in thread
From: K Jayatheerth @ 2025-12-11  5:35 UTC (permalink / raw)
  To: gitster; +Cc: ak, git, phillip.wood123

I’m trying to make sure I fully understand where the fork-point behavior is coming from.
I'm assuming get_rebase_fork_point() and get_rebase_newbase_and_upstream() are responsible.

And when we talk about the “fork-point heuristic” here,
we mean the logic that uses the reflog of the upstream branch
to detect whether the user has previously rebased or reset,
and uses that information to choose a
different merge-base than the raw merge-base HEAD upstream, correct?

Just checking that I’m following correctly
before thinking about possible approaches.

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

* Re: bug: `git pull --rebase` breaks in the presence of pushurls
  2025-12-11  5:35         ` K Jayatheerth
@ 2025-12-11 15:54           ` Phillip Wood
  2025-12-11 19:39             ` Phillip Wood
  0 siblings, 1 reply; 13+ messages in thread
From: Phillip Wood @ 2025-12-11 15:54 UTC (permalink / raw)
  To: K Jayatheerth, gitster; +Cc: ak, git

On 11/12/2025 05:35, K Jayatheerth wrote:
> I’m trying to make sure I fully understand where the fork-point behavior is coming from.
> I'm assuming get_rebase_fork_point() and get_rebase_newbase_and_upstream() are responsible.
> 
> And when we talk about the “fork-point heuristic” here,
> we mean the logic that uses the reflog of the upstream branch
> to detect whether the user has previously rebased or reset,
> and uses that information to choose a
> different merge-base than the raw merge-base HEAD upstream, correct?

Almost, it uses the reflog of the upstream branch to find the most 
recent entry that is a descendant of the local branch. It then uses that 
commit to limit the range of commits that get rebased in case the 
upstream branch has been reset or rewritten. There is a diagram in the 
documentation [1] which might help.

Thanks

Phillip

[1] https://git-scm.com/docs/git-merge-base#_discussion_on_fork_point_mode

> Just checking that I’m following correctly
> before thinking about possible approaches.


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

* Re: bug: `git pull --rebase` breaks in the presence of pushurls
  2025-12-11  3:21       ` Junio C Hamano
  2025-12-11  5:35         ` K Jayatheerth
@ 2025-12-11 15:56         ` Phillip Wood
  1 sibling, 0 replies; 13+ messages in thread
From: Phillip Wood @ 2025-12-11 15:56 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Kartik Agaram, git

On 11/12/2025 03:21, Junio C Hamano wrote:
> Phillip Wood <phillip.wood123@gmail.com> writes:
> 
>> "git pull" already runs "git merge-base --fork-point" before it runs
>> "git fetch". The problematic reflog entry comes from a previous push
>> which pushes to a different server due to remote.<remote>.pushurl.
> 
> Ah, of course.  fork-point heuristics with a repository you yourself
> push into would not make all that sense, since you are in control
> when and what to push there in the first place :/.
> 
>> Because we've just successfully pushed the local branch the fork point
>> calculation thinks the remote tracking branch matches the local branch
>> and so excludes all the local commits when we rebase but we didn't push
>> it to the same server that we're fetching from. I wonder if we should
>> disable the fork point calculation when there is a pushurl set.
> 
> Tempting thought.  Or educate users with diagnoses and advise()?

If we do that we'll also need to provide a way for the user to skip 
using the fork point when pulling. At the moment I think there is way 
for the user to turn it off.

Thanks

Phillip

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

* Re: bug: `git pull --rebase` breaks in the presence of pushurls
  2025-12-11 15:54           ` Phillip Wood
@ 2025-12-11 19:39             ` Phillip Wood
  0 siblings, 0 replies; 13+ messages in thread
From: Phillip Wood @ 2025-12-11 19:39 UTC (permalink / raw)
  To: K Jayatheerth, gitster; +Cc: ak, git

On 11/12/2025 15:54, Phillip Wood wrote:
> On 11/12/2025 05:35, K Jayatheerth wrote:
> Almost, it uses the reflog of the upstream branch to find the most 
> recent entry that is a descendant of the local branch.

Sorry that should say "is an ancestor of the local branch", it is trying 
to find the upstream reflog entry that the local branch is descended from.

> It then uses that 
> commit to limit the range of commits that get rebased in case the 
> upstream branch has been reset or rewritten. There is a diagram in the 
> documentation [1] which might help.
> 
> Thanks
> 
> Phillip
> 
> [1] https://git-scm.com/docs/git-merge-base#_discussion_on_fork_point_mode
> 
>> Just checking that I’m following correctly
>> before thinking about possible approaches.
> 


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

end of thread, other threads:[~2025-12-11 19:39 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-07 21:55 bug: `git pull --rebase` breaks in the presence of pushurls Kartik Agaram
2025-12-08 14:30 ` Phillip Wood
2025-12-08 16:04   ` Phillip Wood
2025-12-08 16:43   ` Kartik Agaram
2025-12-08 22:24   ` Junio C Hamano
2025-12-09  1:48     ` Kartik Agaram
2025-12-09 16:03       ` Phillip Wood
2025-12-10 14:25     ` Phillip Wood
2025-12-11  3:21       ` Junio C Hamano
2025-12-11  5:35         ` K Jayatheerth
2025-12-11 15:54           ` Phillip Wood
2025-12-11 19:39             ` Phillip Wood
2025-12-11 15:56         ` Phillip Wood

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