我在试着理解两者的区别
git push --force
而且
git push --force-with-lease
我的猜测是后者只推到远程如果远程具有本地分支没有的提交?
force用本地分支覆盖远程分支。
force
--force-with-lease是一个更安全的选项,它不会覆盖远程分支上的任何工作,如果更多的提交被添加到远程分支(由另一个团队成员或同事或其他什么人添加)。它确保你不会通过强行推动而覆盖别人的工作。
--force-with-lease
我认为你关于命令的总体想法是正确的。如果远程分支与本地机器上的远程分支具有相同的值-您将覆盖remote。如果它没有相同的值—它表明在您处理代码时其他人对远程分支所做的更改,因此不会覆盖任何代码。显然,如果远程中有额外的提交,那么这些值就不会相同。
我只是认为--force-with-lease作为我想要确保我不覆盖任何队友代码时使用的选项。我公司的许多团队使用--force-with-lease作为故障保险的默认选项。这在大多数情况下是不必要的,但如果你碰巧覆盖了另一个人贡献给远程的东西,它会为你省去很多麻烦。
我相信你看了文件,但这里可能有一些更啰嗦的解释:
https://git-scm.com/docs/git-push
从可信的和/或官方来源寻找答案。
“比较和交换”;torek在的评论和他的另一个回答中提到的是由Git本身的来源进一步说明的。
后者只推送到远程,如果远程没有提交,本地分支没有?
该特性在这个承诺(2013年12月,Git v1.8.5-rc0)中引入
--force-with-lease将保护所有将被更新的远程引用,要求它们的当前值与一些合理的默认值相同,除非另有指定; 目前,“一些合理的违约”;暂定定义为"用于更新远程的引用的远程跟踪分支的值",如果我们没有这样的远程跟踪分支,这是一个错误。
--force-with-lease将保护所有将被更新的远程引用,要求它们的当前值与一些合理的默认值相同,除非另有指定;
目前,“一些合理的违约”;暂定定义为"用于更新远程的引用的远程跟踪分支的值",如果我们没有这样的远程跟踪分支,这是一个错误。
所以“lease"意思是:
:您假设在获取时对ref进行了租约以决定重基历史应该是什么,并且只有在租约没有被打破时才能推回。
资料来源仍然提到“cas"”:
这个选项最初被称为“cas"(代表“比较和交换”),没有人喜欢这个名字,因为它太专业了。 第二次尝试称之为“lockref"(因为它在概念上就像开了锁后推)但“锁”这个词;被讨厌是因为这意味着它可能会拒绝其他人的推动,而这并不是这个选项的工作方式。 这一轮称之为“强制租赁”。 您假设在获取时对ref进行了租用,以决定应该是什么重基历史,并且只有在 租约未被打破。
cas
所以:git push --force-with-lease vs # eyz1;
git fetch origin
--force
Pavlus添加在评论中:
它本身并没有被忽略,只是现在你对本地远程头和远程头有相同的引用,所以--force-with-lease将正确地运行——比较这两个,如果在获取和推送之间的时间间隔内,有人更新了远程,它不会像--force那样运行,它仍然会失败。
参见提交cd85b44(2020年7月21日)by 布莱恩·m·卡尔森(bk2204)。 (由滨野朱尼奥——gitster——在提交c2796ac中合并,2020年7月30日)
bk2204
gitster
remote-curl:使--force-with-lease适用于非ascii引用名称 < p > # EYZ0 署名:brian m. carlson
remote-curl
当调用远程传输助手并传递带有参数的选项时,必要时将参数作为c风格字符串引用。 这就是cas选项的情况,当我们传递一个非ascii的refname时,它实现了--force-with-lease命令行标志 然而,远程的curl helper并不是设计来解析这样的参数的,这意味着如果我们试图使用--force-with-lease与HTTP推送和非ascii refname一起使用,我们会得到这样的错误: error: cannot parse expected object name '0000000000000000000000000000000000000000"' 注意双引号,get_oid已经提醒我们,在十六进制对象ID中是无效的。 即使我们能够解析它,我们也会向服务器发送错误的数据:我们会发送一个转义的ref,它的行为不会像用户想要的那样,可能会意外地导致更新或删除我们不想要的ref。 由于我们需要在这里使用带引号的c风格字符串,因此只需检查第一个参数是否为双引号,如果是,则取消其引号。 注意,如果refname包含双引号,那么我们已经用双引号对其进行了标记,因此不存在歧义 我们仅在智能协议中测试这种情况,因为基于dave的协议无法处理这种功能。 我们使用UTF-8,因为这在我们的测试中更好,对Windows更友好,但代码应该适用于所有非ascii引用 当我们这样做的时候,因为选项的名称现在已经很好地建立起来,并且不会改变,让我们内联它,而不是使用#define常量。
然而,远程的curl helper并不是设计来解析这样的参数的,这意味着如果我们试图使用--force-with-lease与HTTP推送和非ascii refname一起使用,我们会得到这样的错误:
curl
error: cannot parse expected object name '0000000000000000000000000000000000000000"'
注意双引号,get_oid已经提醒我们,在十六进制对象ID中是无效的。
get_oid
即使我们能够解析它,我们也会向服务器发送错误的数据:我们会发送一个转义的ref,它的行为不会像用户想要的那样,可能会意外地导致更新或删除我们不想要的ref。
当我们这样做的时候,因为选项的名称现在已经很好地建立起来,并且不会改变,让我们内联它,而不是使用#define常量。
Git 2.30 (Q1 2021)添加了git push --force-if-includes
git push --force-if-includes
当基于远程引用的本地分支被重绕并将被强制推到远程上时,&;--force-if-includes"运行一个检查,确保在最后一次更新到本地分支之间(例如,通过"git pull")和在推送之前对远程跟踪引用可能发生的任何更新(从另一个存储库推送),在允许强制更新之前已经在本地集成。
--force-if-includes
git pull
假设服务器上的任何pre-receive钩子都接受推送,这将总是成功:
而这在继续之前会运行特定的客户端检查:
您可以自己手动运行特定的检查。下面是“租赁检查”算法:
计算出当前的分支。
# EYZ0运行。注意git客户端认为对应于当前分支上游状态的commit-id。
例如,如果你在分支“foo”上,请注意与“refs/remotes/origin/foo”相关的commit-id。
现在就确定上游git服务器上远程分支的实际提交id。
只有在从第2步和第3步提取的commit-id同意的情况下,才允许“git推送”继续进行。换句话说,只有当本地git克隆的上游概念与实际的上游一致时,才继续执行。
这里有一个悲伤的暗示:因为git fetch将“refs/remotes/origin/*”下的所有引用更新到最新版本,这个命令组合本质上与git push --force相同:
git fetch
git fetch # The command below behaves identically to "git push --force" # if a "git fetch" just happened! git push --force-with-lease
为了解决git push --force-with-lease的这个固有弱点,我尝试从不运行git fetch。相反,当我需要与上游同步时,我总是运行git pull --rebase,因为git pull只在refs/remotes下更新一个ref,保持--force-with-lease的“租约”有用。
git pull --rebase
git push --force是破坏性的,因为它无条件地用本地存储库覆盖远程存储库。git的push --force被强烈反对,因为它会破坏其他已经推送到共享存储库的提交。强制推送的最常见原因之一是当我们被迫重新设置分支时。
push --force
--force-with-lease所做的是拒绝更新分支,除非它是我们所期望的状态;也就是说,没有人更新上游的分支。在实践中,这是通过检查上游的ref是否是我们所期望的,因为ref是哈希值,并隐式地将父链编码到它们的值中。
这里有一个关于git push --force和git push --force-with-lease的好帖子:-被认为有害的力量;理解git的-force-with-lease
强制租赁并不一定安全。就像西尔维说的那样。注意:在git中,分支只是一个提交上的指针。并且提交指向零个或多个父提交。即使你通过硬git重置和强制推送完全改变了分支,或者在不想要的情况下使用- force-with-lease推送,这也不一定是一个大问题。你可以使用你的本地git reflog来查看你的本地tip在分支上的情况(当时HEAD在哪里?)已更改和重置,并再次推动分支。那么您只会丢失远程分支上的新提交,但即使它们也可能被团队成员恢复。