假设我从git repo中提取更改。然后,回购力量的作者推向中央回购。现在我不能拉,因为历史被重写了。
如果作者强行推送正确的版本,我怎样才能提取新提交(并放弃旧提交)?
我知道这是一个糟糕的git工作流程,但有时你无法避免这种情况。
答案 0 :(得分:46)
如果您要放弃工作,fetch
和reset
。例如,如果您有名为origin
的远程名称和名为master
的分支:
$ git fetch origin
$ git reset --hard origin/master # Destroys your work
如果你不想丢弃你的工作,你将不得不做git rebase --onto
。假设旧origin
看起来像这样:
A ---> B ---> C
^
origin/master
你有这个:
A ---> B ---> C ---> X ---> Y ---> Z
^ ^
| master
origin/master
现在,上游的变化改变了一切:
A ---> B ---> C ---> X ---> Y ---> Z
\ ^
---> B'---> C' master
^
origin/master
在上游更改之前,您必须运行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
注意B,C,X,Y和Z现在是如何“无法到达”的。它们最终将被Git从您的存储库中删除。在此期间(90天),Git会在reflog中保留一份副本,以防你犯了错误。
如果git reset
或git rebase
错误且意外丢失了一些本地更改,您可以在reflog中找到更改。
在评论中,用户建议git reflog expire
--expire=now
但不要运行此命令,因为这将 DESTROY 您的安全网。拥有reflog的全部目的是让Git在你运行错误的命令时有时会挽回你的脖子。
基本上,这个命令会做的是立即销毁上面例子中的B,C,X,Y和Z提交,这样你就无法取回它们。运行此命令没有什么好处,除了它可能节省一点磁盘空间,但Git将在90天后清除数据,因此这种好处是短暂的。
答案 1 :(得分:0)
我遇到了这种情况的稍微修改的版本。这是我所做的:
A--->B--->C--->D--->E
|
local-1/master
A--->B--->C--->D--->E
|
origin/master
A--->B--->C--->D--->E
|
local-2/master
A--->B--->CDE
|
local-1/master
A--->B--->CDE
|
origin/master
A--->B--->C--->D--->E
|
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
答案 2 :(得分:0)
如果未对本地分支进行任何更改,则可以尝试以下命令序列。请记住,这是达到要求的粗略方法。
git checkout master
git pull
git remote update origin -p
git branch -D myBranch
git checkout myBranch
git remote update origin -p
是可选的。
如果您进行了更改并且不关心本地分支的内容,则可以尝试以下操作:
git stash
git stash drop
git checkout master
git pull
git remote update origin -p
git branch -D myBranch
git checkout myBranch
这两种技术都非常冗长且繁琐。但是把工作做好。
答案 3 :(得分:0)
如果没有本地提交,这将从强制推送中恢复您的结帐。您将了解远程分支的最新情况,并且可以稍后提交您的本地工作。
git fetch
git stash
git reset --hard origin/master # destroys your work
git stash pop # restores your work as local changes
git mergetool # fix any conflicts
此时,您的本地更改与以前一样。您的结帐与 master 或您正在工作的任何分支上的所有更改都是最新的。