为什么即使我的本地仓库与远程仓库保持一致,使用 `git push --force-with-lease` 也会失败并显示 "rejected ... stale info"?

69

我正在尝试强制推送一个特性分支的衍合到远程仓库。为了更加安全,我正在尝试使用--force-with-lease来确保自上次获取以来该分支没有发生其他更改。

由于我不理解原因,这个操作失败了:

$ git branch
* my-branch
  master

$ git push --force-with-lease origin my-branch -u
To gitlab.com:example/my-project.git
 ! [rejected]        my-branch -> my-branch (stale info)
error: failed to push some refs to 'git@gitlab.com:example/my-project.git'
我尝试了一次获取(fetch)操作,以查看我的本地缓存是否出现了某些不同步的情况:
$ git fetch

$ git push --force-with-lease origin my-branch -u
To gitlab.com:example/my-project.git
 ! [rejected]        my-branch -> my-branch (stale info)
error: failed to push some refs to 'git@gitlab.com:example/my-project.git'

我尝试简化push命令:

$ git push --force-with-lease
To gitlab.com:example/my-project.git
 ! [rejected]        my-branch -> my-branch (stale info)
error: failed to push some refs to 'git@gitlab.com:example/my-project.git'

我尝试将检查限制在我的分支中:

$ git push --force-with-lease=my-branch:origin/my-branch
To gitlab.com:example/my-project.git
 ! [rejected]        my-branch -> my-branch (stale info)
error: failed to push some refs to 'git@gitlab.com:example/my-project.git'

正如你所看到的,它每次都以相同的方式失败。

为什么我的推送失败了,我该怎么修复它?


(1) my-branch 上游已经存在一个设置吗?如果是的话,它是什么? (2) origin 的获取 refspec 是什么? - torek
@torek 我发现问题原因是远程分支已被删除,而默认情况下pull/fetch不会同步删除。这就是为什么即使本地与远程不同步,它看起来仍然同步。使用--prune选项在pull/fetch时可以纠正这个问题。 - Laurence Gonsalves
5个回答

65
在我的情况下,先执行简单的git fetch,然后再次进行推送解决了问题。

3
请注意,git fetch; git push --force-with-lease 实际上与 git push --force 几乎相同。通过 --force-with-lease 默认获得的“租约”是基于确认将要更新的远程引用与您最后获取的引用相同,因此在之前立即获取只是在那一瞬间内“保护”免受其他人推送的影响。 - Laurence Gonsalves

45
在这种情况下,问题是远程分支已被删除,但我的本地仓库中仍有一份副本。默认情况下,Fetch 不会删除本地副本,这就是为什么它没有效果的原因。在我重新基于之前,将 --prune 选项添加到我的初始 git pull 中可以解决此问题。

1
您可能还想在个人(--global)Git配置中将 fetch.prune 设置为 true。有趣的是,当您推送到没有任何值的远程时,git push --force-with-lease 会认为该值已过期。这是一种有效的看法,但并不实用:--force-with-lease 应该只将此情况视为“可以强制执行”。 - torek

10
如果您刚刚完成了rebase操作,不想重新开始,请运行git remote prune origin。然后再次运行git push --force-with-lease,它会生效。

2

当你使用gh pr checkout <num>检出到pr并在进行一些更改后尝试强制推送时,可能会遇到此问题。

正确的方式是将远程添加到他们的repo中,并检出用于创建pr的分支。然后你就可以推送你的提交了。它将显示在pr中。


在这种情况下,我发现在rebase之前确认local已经与remote更新到同步状态后,使用--force更容易。每个GitHub用户添加一个远程会很快变得难以管理。 - DA_123

1
我认为--force-with-lease在浅克隆方面可能存在一些问题。有几次我收到这个消息,但是--force可以正常工作 - 如果你遇到这种情况,请检查是否可能是因为你使用了浅克隆。
不幸的是,除了将浅克隆转换为完整克隆或者只使用-f之外,我不知道其他解决办法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接