git 强制git push后如何拉?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14787776/
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
How to pull after a forced git push?
提问by Andrew Legacci
Suppose I pull changes from a git repo. Then the author of the repo force pushes to the central repo. Now I can't pull since the history is rewritten.
假设我从 git repo 中提取更改。然后回购力的作者推到中央回购。现在我不能拉,因为历史被改写了。
How can I pull the new commits (and abandon the old ones), assuming that the author force-pushed the correct version?
假设作者强制推送了正确的版本,我该如何拉新提交(并放弃旧提交)?
I know this is bad git workflow, but sometimes you can't avoid this.
我知道这是糟糕的 git 工作流程,但有时您无法避免这种情况。
回答by Dietrich Epp
Throwing away your local changes
丢弃您的本地更改
If you want to discard your work, fetch
and reset
. For example, if you have a remote named origin
and a branch named master
:
如果你想放弃你的工作,fetch
和reset
. 例如,如果您有一个名为的远程origin
和一个名为的分支master
:
$ git fetch origin
$ git reset --hard origin/master # Destroys your work
Keeping your local changes
保持本地更改
If you don't want to throw away your work, you will have to do a git rebase --onto
. Suppose the old origin
looks like this:
如果你不想扔掉你的工作,你将不得不做一个git rebase --onto
. 假设旧的origin
看起来像这样:
A ---> B ---> C
^
origin/master
And you have this:
你有这个:
A ---> B ---> C ---> X ---> Y ---> Z
^ ^
| master
origin/master
Now, the upstream changes change things:
现在,上游的变化改变了事情:
A ---> B ---> C ---> X ---> Y ---> Z
\ ^
---> B'---> C' master
^
origin/master
You would have to run git rebase --onto origin/master <C> master
, where <C>
is the SHA-1 of the old origin/master
branch before upstream changes. This gives you this:
您必须运行git rebase --onto origin/master <C> master
,在上游更改之前<C>
旧origin/master
分支的 SHA-1在哪里。这给你这个:
A ---> B ---> C ---> X ---> Y ---> Z
\
---> B'---> C'---> X'---> Y'---> Z'
^ ^
| master
origin/master
Notice how B, C, X, Y, and Z are now "unreachable". They will eventually be removed from your repository by Git. In the meantime (90 days), Git will keep a copy in the reflog in case it turns out you made a mistake.
请注意 B、C、X、Y 和 Z 现在如何“无法访问”。它们最终会被 Git 从您的存储库中删除。与此同时(90 天),Git 会在 reflog 中保留一份副本,以防你犯了错误。
Fixing mistakes
修正错误
If you git reset
or git rebase
wrong and accidentally lose some local changes, you can find the changes in the reflog.
如果你git reset
或git rebase
错了,不小心丢失了一些本地更改,你可以在 reflog 中找到这些更改。
In the comments, a user is suggesting git reflog expire
with --expire=now
but DO NOT RUN THIS COMMANDbecause this will DESTROYyour safety net. The whole purpose of having a reflog is so that Git will sometimes save your neck when you run the wrong command.
在评论中,用户建议git reflog expire
使用--expire=now
但不要运行此命令,因为这会破坏您的安全网。拥有 reflog 的全部目的是当你运行错误的命令时,Git 有时会保护你的脖子。
Basically, what this command will do is immediately destroy the B, C, X, Y, and Z commits in the examples above so you can't get them back. There's no real benefit to running this command, except it might save a little bit of disk space, but Git will already purge the data after 90 days so this benefit is short-lived.
基本上,此命令将立即销毁上面示例中的 B、C、X、Y 和 Z 提交,因此您无法取回它们。运行此命令并没有真正的好处,只是它可能会节省一点磁盘空间,但是 Git 会在 90 天后清除数据,因此这种好处是短暂的。
回答by keyur
I came across a slightly modified version of this scenario. Here's what I did:
我遇到了这个场景的一个稍微修改过的版本。这是我所做的:
Initial condition
初始条件
A--->B--->C--->D--->E
|
local-1/master
A--->B--->C--->D--->E
|
origin/master
A--->B--->C--->D--->E
|
local-2/master
Squash and force push
挤压和强力推动
A--->B--->CDE
|
local-1/master
A--->B--->CDE
|
origin/master
A--->B--->C--->D--->E
|
local-2/master
Sync changes on local-2/master
在 local-2/master 上同步更改
$ git reset --soft B
A--->B---> (local uncommitted changes)
|
local-2/master
$ git stash save "backup"
A--->B
|
local-2/master
$ git pull origin master
A--->B--->CDE
|
local-2/master