58

假设我从 git repo 中提取更改。然后回购力量的作者推送到中央回购。现在我不能拉,因为历史被改写了。

假设作者强制推送了正确的版本,我怎样才能拉出新的提交(并放弃旧的提交)?

我知道这是糟糕的 git 工作流程,但有时你无法避免这种情况。

4

4 回答 4

112

丢弃本地更改

如果您想丢弃您的工作,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>旧分支的 SHA-1 在哪里。origin/master这给了你这个:

A ---> B ---> C ---> X ---> Y ---> Z
 \
  ---> B'---> C'---> X'---> Y'---> Z'
              ^                    ^
              |                    master
              origin/master

请注意 B、C、X、Y 和 Z 现在是如何“无法访问”的。它们最终会被 Git 从您的存储库中删除。在此期间(90 天),Git 会在 reflog 中保留一份副本,以防万一你犯了错误。

修正错误

如果您git resetgit rebase错误而意外丢失了一些本地更改,您可以在 reflog 中找到更改。

在评论中,用户建议git reflog expire使用--expire=now不要运行此命令,因为这会破坏您的安全网。使用 reflog 的全部目的是让 Git 有时会在您运行错误命令时拯救您。

基本上,此命令将立即销毁上述示例中的 B、C、X、Y 和 Z 提交,这样您就无法取回它们。运行这个命令并没有真正的好处,除了它可能会节省一点磁盘空间,但 Git 会在 90 天后清除数据,所以这个好处是短暂的。

于 2013-02-09T11:48:50.787 回答
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 上的所有更改,或者您正在使用的任何分支。

于 2021-01-23T18:04:10.283 回答
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

在 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
于 2018-09-28T16:19:00.447 回答
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

这两种技术都非常冗长且繁琐。但是把工作做好。

于 2020-08-11T11:57:43.993 回答