git push --force-with-lease 与 --force
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/52823692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
git push --force-with-lease vs. --force
提问by Alexander Mills
I am trying to understand the difference between
我试图理解两者之间的区别
git push --force
and
和
git push --force-with-lease
My guess is that the latter only pushes to the remote if the remote does not have commits that the local branch doesn't have?
我的猜测是,如果远程没有本地分支没有的提交,后者只会推送到远程?
回答by chevybow
force
overwrites a remote branch with your local branch.
force
用您的本地分支覆盖远程分支。
--force-with-lease
is a safer option that will not overwrite any work on the remote branch if more commits were added to the remote branch (by another team-member or coworker or what have you). It ensures you do not overwrite someone elses work by force pushing.
--force-with-lease
是一个更安全的选项,如果将更多提交添加到远程分支(由另一个团队成员或同事或您拥有的东西),则不会覆盖远程分支上的任何工作。它确保您不会通过强制推送覆盖其他人的工作。
I think your general idea surrounding the command is correct. If the remote branch has the same value as the remote branch on your local machine- you will overwrite remote. If it doesn't have the same value- it indicates a change that someone else made to the remote branch while you were working on your code and thus will not overwrite any code. Obviously if there are additional commits in remote then the values won't be the same.
我认为您对命令的总体看法是正确的。如果远程分支与本地机器上的远程分支具有相同的值 - 您将覆盖 remote。如果它没有相同的值 - 它表示其他人在您处理代码时对远程分支进行了更改,因此不会覆盖任何代码。显然,如果远程中有其他提交,则值将不相同。
I just think of --force-with-lease
as the option to use when I want to make sure I don't overwrite any teammates code. A lot of teams at my company use --force-with-lease
as the default option for a fail-safe. Its unnecessary in most circumstances but will save you lots of headache if you happen to overwrite something that another person contributed to remote.
--force-with-lease
当我想确保我不会覆盖任何队友代码时,我只是想使用这个选项。我公司的许多团队都将其--force-with-lease
用作故障安全的默认选项。在大多数情况下它是不必要的,但是如果您碰巧覆盖了另一个人为远程贡献的内容,则会为您省去很多麻烦。
I'm sure you looked at the docs but there might be some more wordy explanation contained in here:
我确定您查看了文档,但此处可能包含一些更冗长的解释:
回答by VonC
Looking for an answer drawing from credible and/or official sources.
寻找来自可靠和/或官方来源的答案。
The "compare and swap" mentioned by torekin the commentsand in his other answeris further illustrated by the sources of Git itself.
torek在评论和他的其他答案中提到的“比较和交换”由Git 本身的来源进一步说明。
the latter only pushes to the remote if the remote does not have commits that the local branch doesn't have?
如果远程没有本地分支没有的提交,后者只会推送到远程?
That feature was introduced in this commit(Dec. 2013, Git v1.8.5-rc0)
该功能在此提交中引入(2013 年 12 月,Git v1.8.5-rc0)
--force-with-lease
will protect all remote refs that are going to be updated by requiring their current value to be the same as some reasonable default, unless otherwise specified;For now, "some reasonable default" is tentatively defined as "the value of the remote-tracking branch we have for the ref of the remote being updated", and it is an error if we do not have such a remote-tracking branch.
--force-with-lease
除非另有说明,否则将通过要求它们的当前值与某些合理的默认值相同来保护所有将要更新的远程引用;目前,“一些合理的默认值”被暂时定义为“我们拥有的远程跟踪分支的值,用于更新远程的引用”,如果我们没有这样的远程跟踪分支,这是一个错误。
So "lease" means:
所以“租赁”的意思是:
"
force-with-lease
": You assume you took the lease on the ref when you fetched to decide what the rebased history should be, and you can push back only if the lease has not been broken.
"
force-with-lease
": 你假设你在获取时已经租用了 ref 来决定重新定位的历史应该是什么,并且只有在租约没有被破坏的情况下你才能推迟。
The sources still mentions "cas":
消息来源仍然提到“cas”:
- This option was originally called "
cas
" (for "compare and swap"), the name which nobody liked because it was too technical.- The second attempt called it "lockref" (because it is conceptually like pushing after taking a lock) but the word "lock" was hated because it implied that it may reject push by others, which is not the way this option works.
- This round calls it "force-with-lease".
You assume you took the lease on the ref when you fetched to decide what the rebased history should be, and you can push back only if the lease has not been broken.
- 这个选项最初被称为“
cas
”(表示“比较和交换”),这个名字没有人喜欢,因为它太技术性了。- 第二次尝试将其称为“lockref”(因为它在概念上类似于在获取锁后推送)但是“锁”这个词被讨厌,因为它暗示它可能会拒绝其他人的推送,这不是此选项的工作方式。
- 这一轮称之为“强制租赁”。
您假设您在获取时租用了 ref 以决定重新定位的历史记录应该是什么,并且只有在租用未被破坏的情况下才能推迟。
So: "git push --force-with-lease
vs. --force
"
所以:“git push --force-with-lease
对--force
”
As I mentioned in "push --force-with-lease
by default", as Git 2.13 (Q2 2017) mentions, that the option --force-with-lease
can be ignoredif a background process (like the ones you find in an IDE with a Git plugin) runs git fetch origin
.
In that case, --force
prevails.
正如我在“push --force-with-lease
默认情况下”中提到的,正如 Git 2.13(2017 年第二季度)所提到的,如果后台进程(例如您在带有 Git 插件的 IDE 中找到的进程)运行,则--force-with-lease
可以忽略该选项git fetch origin
。
在这种情况下,--force
占上风。
回答by Shakil
git push --forceis destructive because it unconditionally overwrites the remote repository with whatever one have locally. git's push --forceis strongly discouraged as it can destroy other commits already pushed to a shared repository. One of the most common causes of force pushes is when we're forced to rebase a branch.
git push --force是破坏性的,因为它无条件地用本地的任何内容覆盖远程存储库。强烈建议不要使用git 的push --force,因为它会破坏已经推送到共享存储库的其他提交。强制推送的最常见原因之一是当我们被迫重新设置分支时。
For example. We have a project with a feature branch that both Alice and Bob are going to work on. They both clone this repository and start work. Alice initially completes her part of the feature, and pushes this up to the main repository. This is all well and good. Bob also finishes his work, but before pushing it up he notices some changes had been merged into master. Wanting to keep a clean tree, he performs a rebase against the master branch. Of-course, when he goes to push this rebased branch it will be rejected. However not realising that Alice has already pushed her work, he performs a push --force. Unfortunately, this will erase all record of Alice's changes in the central repository.
例如。我们有一个带有功能分支的项目,Alice 和 Bob 都将在该项目上工作。他们都克隆了这个存储库并开始工作。Alice 最初完成了她的部分功能,并将其推送到主存储库。这一切都很好。Bob 也完成了他的工作,但在推动它之前,他注意到一些更改已合并到 master 中。为了保持一棵干净的树,他对主分支执行了变基。当然,当他去推送这个 rebase 的分支时,它会被拒绝。然而没有意识到 Alice 已经推动了她的工作,他执行了 push --force。不幸的是,这将删除 Alice 在中央存储库中的所有更改记录。
What --force-with-leasedoes is refuse to update a branch unless it is the state that we expect; i.e. nobody has updated the branch upstream. In practice this works by checking that the upstream ref is what we expect, because refs are hashes, and implicitly encode the chain of parents into their value.
什么--force-与租赁确实是垃圾更新某个分支,除非它是我们所期望的状态; 即没有人更新上游分支。在实践中,这是通过检查上游 ref 是否符合我们的预期来实现的,因为 ref 是散列,并将父链隐式编码为它们的值。
Hereis a good post regarding git push --force and git push --force-with-lease.
这是一篇关于 git push --force 和 git push --force-with-lease 的好帖子。
回答by G. Sylvie Davies
Assuming any pre-receive hooks on the server accept the push, this will always succeed:
假设服务器上的任何 pre-receive 钩子接受推送,这将始终成功:
git push --force
Whereas this runs a specific client-side check before proceeding:
而这会在继续之前运行特定的客户端检查:
git push --force-with-lease
You can run the specific check yourself manually. Here's the "lease-checking" algorithm:
您可以自己手动运行特定检查。这是“租约检查”算法:
Figure out your current branch.
Run
git for-each-ref refs/remotes
. Take note of the commit-id your git client thinks corresponds to the upstream state of your current branch.
找出你当前的分支。
运行
git for-each-ref refs/remotes
。记下您的 git 客户端认为对应于您当前分支的上游状态的 commit-id。
E.g., if you are on branch "foo", take note of the commit-id associated with "refs/remotes/origin/foo".
例如,如果您在分支“foo”上,请注意与“refs/remotes/origin/foo”相关联的提交 ID。
Determine the actual commit-id of the remote branch on the upstream git server right now.
Only let the "git push" proceed if the commit-ids you extracted from step 2 and step 3 agree. In other words, only proceed if your local git clone's notion of upstream agrees with actual upstream.
立即确定上游 git 服务器上远程分支的实际提交 ID。
如果您从第 2 步和第 3 步中提取的提交 ID 一致,则仅让“git push”继续进行。换句话说,只有当您本地 git clone 的上游概念与实际上游一致时才继续。
There's a sad implication here: since git fetch
updates all refs under "refs/remotes/origin/*" to their latest versions, this combination of commands is essentially identical to git push --force
:
这里有一个可悲的含义:由于将git fetch
“refs/remotes/origin/*”下的所有 refs 更新为最新版本,因此这种命令组合本质上等同于git push --force
:
git fetch
# The command below behaves identically to "git push --force"
# if a "git fetch" just happened!
git push --force-with-lease
To work around this inherent weakness in git push --force-with-lease
I try to never run git fetch
. Instead I always run git pull --rebase
whenever I need to sync with upstream, since git pull
only updates a single ref under refs/remotes, keeping the "lease" of --force-with-lease
useful.
为了解决这个固有的弱点,git push --force-with-lease
我尽量不要跑步git fetch
。相反,我总是git pull --rebase
在需要与上游同步时运行,因为git pull
只更新 refs/remotes 下的单个 ref,保持“租约”--force-with-lease
有用。
回答by Fish
Force-with-lease is not necessarily safe. It just works as Sylvie said. One note: In git a branch is just a pointer on a commit. And commits point to zero or more parent commits. Even if you changed the branch entirely with a hard git reset and a forced push or a push with - - force-with-lease without wanting it, that's not necessarily a big problem. You can use your local git reflog to see how your local tip on the branches (Where was HEAD at that time? ) has changed and reset and push the branch again. Then you only lose new commits on the remote branch, but even they might be restored by the team members.
强制租赁不一定安全。它就像 Sylvie 所说的那样有效。一个注意事项:在 git 中,分支只是提交上的一个指针。并且提交指向零个或多个父提交。即使您在不想要它的情况下使用硬 git reset 和强制推送或使用 --force-with-lease 推送完全更改了分支,这也不一定是大问题。您可以使用本地 git reflog 来查看分支上的本地提示(当时 HEAD 在哪里?)如何更改并重置并再次推送分支。然后你只会丢失远程分支上的新提交,但即使它们也可能被团队成员恢复。