我一直遵循的规则是,一旦将 git 历史推送到远程存储库,就不要修改它。
但我想知道是否交互式变基到 push --force-with-lease 绕过了这个规则?
如果强制租赁成功,其他用户是否完全安全,或者此策略是否有任何警告?
预先感谢您提供任何意见。
Von*_*onC 16
使用 Git 2.30(2021 年第 1 季度)可以使其变得更安全:“ ( man ) ”很容易被误用而丢失提交,除非用户妥善保管自己的“ ”。git push --force-with-lease[=<ref>]git fetch
新选项“ --force-if-includes”尝试确保在检查即将被强制替换的远程引用尖端的提交后创建被强制推送的内容。
当远程跟踪引用有我们本地没有的更新时,它会拒绝分支的强制更新。
请参阅Srinidhi Kaushik ( )提交的提交 3b5bf96、提交 3b990aa、提交 99a1f9a(2020 年 10 月 3 日)。
请参阅Junio C Hamano ( )提交的 aed0800(2020 年 10 月 2 日)。(由Junio C Hamano 合并 -- --在提交 de0a7ef中,2020 年 10 月 27 日)clickyotomygitster
gitster
push--force-if-includes:添加对“ ”的reflog检查签署人:Srinidhi Kaushik
添加一项检查以验证是否可以从其“reflog”条目之一访问本地分支的远程跟踪引用。
该检查会迭代本地引用的引用日志,以查看是否存在远程跟踪引用的条目,并将看到的任何提交收集到列表中;如果引用日志中的条目与远程引用匹配,或者如果条目时间戳比远程引用的“引用日志”的最新条目更旧,则迭代停止。如果没有找到远程引用的条目,
"in_merge_bases_many()则调用“来检查是否可以从收集的提交列表中访问它。当基于远程引用的本地分支已被倒回并强制推送到远程时,“
--force-if-includes”运行检查以确保可能发生的远程跟踪引用的任何更新(通过从另一个存储库推送) )在本地分支的最后更新时间(git pull例如,通过“”)和推送时间之前,在允许强制更新之前已在本地集成。如果传递新选项时未指定“
--force-with-lease”,或与“”一起指定,--force-with-lease=<refname>:<expect>则为“无操作”。
Hum*_*man 15
我想描述一个看似合理的案例,在该案例中,这--force-with-lease并不能避免您覆盖同事的工作。
在签出最新的主分支时执行以下操作:
# Creating a new branch called feature/one
$ git checkout -b feature/one
# Do some changes and git add ...
$ git commit
# Push for the first time
$ git push --set-upstream origin feature/one
# Checkout another branch to work on something else
Run Code Online (Sandbox Code Playgroud)
Bob 机器上的情况
...--F--G--H <-- master (HEAD)
\
o--o <-- feature/one
Run Code Online (Sandbox Code Playgroud)
Alice 接手 feature/one 上的工作,并在 Bob 的工作之上提交内容并推送她的更改,同时一些不相关的拉取请求被合并到主分支。Alice 的工作树是什么样子的
...--F--G--H--I--J <-- master (HEAD)
\
o--o--x--x <-- feature/one
Run Code Online (Sandbox Code Playgroud)
Bob 的任务是在当前主分支上重新调整 Alice 的工作,并执行以下操作
git pull而他在 master 分支上,基本上就是 agit fetch和 agit merge
这一步的后果稍后会很重要。
Bob机器上的情况:
...--F--G--H--I--J <-- master (HEAD)
\
o--o <-- feature/one
Run Code Online (Sandbox Code Playgroud)
...--F--G--H--I--J <-- origin/master (HEAD)
\
o--o--x--x <-- origin/feature/one
Run Code Online (Sandbox Code Playgroud)
Bob 的机器现在包含一个最新的遥控器,但 origin/feature/one 中的更改尚未合并到 feature/one。
鲍勃检查分支git checkout feature/one
git pullBob 在 master 上重新建立了他的本地分支git rebase -i origin/master
bobs 机器上的情况如下所示:
...--F--G--H--I--J <-- master (HEAD)
\
o--o <-- feature/one
Run Code Online (Sandbox Code Playgroud)Bob 认为他成功地重新调整了他的分支并强制推送到feature/one,origin/feature/one因为 Bob 是一个好人,他推送了git push --force-with-lease origin feature/one并期望该选项
--force-with-lease将阻止他的推送操作,如果他要覆盖其他人的工作。
但这个选项不会拯救他,如果我正确理解
这篇博客文章,--force-with-lease那么鲍勃机器上的 origin/feature/one 和实际的 origin/feature/one 之间没有区别,因此假设 Bob 的工作树不会覆盖 Bob 机器上的任何内容。如果强制推到它,则远程。缺乏差异的原因在于在不同分支上执行隐式git fetch作为早期(在本节的步骤 1 中)的一部分。git pull
推送后,遥控器会是这样的
...--F--G--H--I--J <-- master (HEAD)
\
o--o <-- feature/one
Run Code Online (Sandbox Code Playgroud)
代替
...--F--G--H--I--J <-- master (HEAD)
\
o--o--x--x <-- feature/one
Run Code Online (Sandbox Code Playgroud)
这是上面链接的博客文章的相关部分:
提取将从远程提取对象和引用,但如果没有匹配的合并,则不会更新工作树。这将使远程的工作副本看起来好像远程的工作副本是最新的,而不实际包含新工作,并欺骗
--force-with-lease覆盖远程分支
这不安全。
请参阅这篇 atlassian 博客文章,其中描述了git push --force-with-lease比git push -f. 然而,它部分地覆盖了遥控器,使其不安全。
但是 --force 有一个不太为人所知的兄弟,可以部分防止破坏性的强制更新;这是--force-with-lease。
不同之处在于,--force-with-lease如果远程包含本地存储库不知道的工作,则会进行额外的检查并中止。但它仍然会覆盖远程分支,导致与 相同的问题-f,只是如果其他人同时推送,它不会这样做。