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