【问题标题】:Undo a git pull撤消 git pull
【发布时间】:2011-01-17 23:54:14
【问题描述】:

我看到的撤消 git pull 的问题与我的略有不同。

这就是我所做的:

目录A 中有一个项目(不是repo)。我在其中初始化了一个存储库,添加了文件,但没有提交任何内容。然后我从存储库 B 中提取,它覆盖了我的一堆暂存文件。

我的印象是我可以使用git reset --hard 来撤消合并。当然,这只是检查了我刚刚拉入的提交的 HEAD。

在我做这个 pull 之前,我应该已经分支并提交了一些东西,事后看来很好。有什么方法可以取回未暂存的旧文件吗?

【问题讨论】:

  • git reset --merge 可以让您在未来免去一些悲伤。不受合并影响的文件会被单独留下,如果您对合并将触及的文件进行了修改,git 将拒绝尝试合并,因此它很好地覆盖了您的基础!
  • 另外,pull 真的会覆盖暂存文件吗?这对我来说没有意义。正如我在之前的评论中所说,git 在这种情况下会拒绝合并。是不是 reset --hard 让他们大吃一惊?
  • 是的,我认为是reset --hard。这有点像rm -rf,在坏人手中很危险。

标签: git version-control


【解决方案1】:

git pullgit fetch + git merge 相同。覆盖您的更改的是合并步骤。要恢复到合并前的状态,请使用 git log 查找您的最新提交,然后使用 git reset --hard 1234abcd 其中 1234abcd 是所需提交的哈希。

请注意,重置后git pull 将再次合并更改。要永久还原更改,请使用git revert,这将创建一个额外的提交来撤消更改。

【讨论】:

  • 这通常可以工作,但正如问题中所述,他只进行了更改。没有提交。因此也无需重置。
  • 问题是我在合并之前没有提交,只是一个阶段。很确定我只是不小心把所有文件都弄丢了。
  • ORIG_HEADHEAD 在合并或其他可能危险的命令之前的状态。不幸的是,正如其他评论者所指出的那样,这在这里无济于事。
  • git reset --hard 会覆盖分阶段的更改(git reset 也是如此,但git reset --soft 不会)。如果更改未提交,则不会保存。
  • 哦,你是对的。我认为merge 不适用于未提交更改的存储库。至于数据,我认为暂存文件记录在git的内部数据存储中,所以可能仍然可以从那里挖出来。
【解决方案2】:

这里似乎有恢复暂存文件的答案:

Recovering added file after doing git reset --hard HEAD^

【讨论】:

    【解决方案3】:

    要么只是重置为以前的 HEAD(即您在存储库中的提交,未从远程更新),要么使用 git reflog。后者显示在您的存储库中进行的操作列表,git pull 命令应该是其中的一部分。只需 git reset --hard X 到该命令之前的状态。

    或者只是从前一个 HEAD 分支(您可以删除/覆盖前一个分支),在那里进行更改并再次 git pull...

    【讨论】:

      【解决方案4】:

      我认为你现在无法完全恢复。您可以做的最好的事情是git status 检查哪些文件仍然完好无损。如果未提交的文件不在这里,它们就会丢失。

      下一次,考虑在git pull 之前使用git stash,或者更好的是使用git fetch


      如果您是高级 Git 用户,并且文件真的很重要:

      如果文件是暂存的,您可以从对象存储库中提取它们。但是这些直接进入了 git guts,我认为你不应该尝试。

      如果你真的想要,请阅读以下内容:

      【讨论】:

      • 没想过把它藏起来。无论如何,分支似乎是更安全的选择。吸取的教训,在我从我的 IDE 历史记录中恢复所有文件后,我初始化并提交,然后运行git-fetch,然后运行git-merge。效果很好。
      【解决方案5】:

      2011 年 1 月 17 日下午 6:53 更新

      只需重新阅读您的问题。我忽略了您是从项目 b 中提取而不是将文件复制到您的项目中。不确定我的答案是否仍然适用于您的情况。我认为您最好的选择是关注 geoffreyd's answer 并查看 StackOverflow 问题的答案 Recovering added file after doing git reset --hard HEAD^

      原答案

      只需做一个git checkout -- <file>

      这是我为确认上述内容而运行的示例...

      # Create a test directory and some test files
      $ mkdir blah
      $ echo "I've been overwritten" > test1.txt
      $ cd blah
      $ echo "I'm the real test1.txt" > test1.txt
      $ git init .
      Initialized empty Git repository in /Users/matthew/blah/.git/
      $ git add .
      $ cp ~/test1.txt .
      $ git status
      # On branch master
      #
      # Initial commit
      #
      # Changes to be committed:
      #   (use "git rm --cached <file>..." to unstage)
      #
      #   new file:   test1.txt
      #
      # Changed but not updated:
      #   (use "git add <file>..." to update what will be committed)
      #   (use "git checkout -- <file>..." to discard changes in working directory)
      #
      #   modified:   test1.txt
      #
      $ cat test1.txt
      I've been overwritten
      $ git checkout -- test1.txt
      $ cat test1.txt
      I'm the real test1.txt
      

      当您执行git status 时,它会告诉您使用git checkout -- &lt;file&gt; 放弃工作目录中的更改。如果我没看错你的问题,那就是你想要做的。

      【讨论】:

        猜你喜欢
        • 2012-06-10
        • 2011-01-13
        • 2011-08-14
        • 2020-09-25
        • 2013-11-20
        • 2015-10-20
        • 2016-02-08
        • 2017-08-06
        相关资源
        最近更新 更多