我见过的关于撤销 git pull 的问题略有不同。
这是我的操作:
在目录 A
中有一个项目(不是仓库)。我在其中初始化了一个仓库,添加了文件,但没有进行任何提交。然后我从仓库 B 拉取,覆盖了一堆我已经暂存的文件。
我本以为可以使用 git reset --hard
来撤消合并。当然,这只是检出了我刚才拉取的提交的 HEAD。
我应该在执行拉取操作前创建一个分支并进行提交,事后诸葛亮。是否有办法让我恢复旧的未暂存文件?
我见过的关于撤销 git pull 的问题略有不同。
这是我的操作:
在目录 A
中有一个项目(不是仓库)。我在其中初始化了一个仓库,添加了文件,但没有进行任何提交。然后我从仓库 B 拉取,覆盖了一堆我已经暂存的文件。
我本以为可以使用 git reset --hard
来撤消合并。当然,这只是检出了我刚才拉取的提交的 HEAD。
我应该在执行拉取操作前创建一个分支并进行提交,事后诸葛亮。是否有办法让我恢复旧的未暂存文件?
git pull
命令相当于执行 git fetch
和 git merge
命令。它是合并步骤覆盖了您的更改。要恢复到合并之前的状态,请使用 git log
查找最新的提交,然后使用 git reset --hard 1234abcd
命令,其中 1234abcd 是所需提交的哈希值。
请注意,在执行重置操作后,git pull
命令将再次合并更改。若要永久撤消更改,请使用 git revert
命令,它会创建一个额外的提交来撤销更改。
git reset --hard
会覆盖已暂存的更改(git reset
也是如此,但 git reset --soft
不会)。如果更改没有被提交,那么它就没有被保存。 - Jay Conrodmerge
不能在有未提交更改的存储库上工作。至于数据,我认为暂存的文件被记录在git的内部数据存储中,因此仍然可能从那里挖掘出它们。 - Gintautas Miliauskasgit reflog
。后者显示在您的存储库中进行的操作列表,git pull
命令应该是其中的一部分。只需将git reset --hard X
设置为该命令之前的状态即可。我认为你现在无法完全恢复。最好的方法是使用 git status
命令检查哪些文件仍然完好无损。如果未提交的文件不存在于此处,则已丢失。
下次在执行 git pull
前,考虑使用 git stash
,或者更好的方法是使用 git fetch
。
如果你是高级的Git用户,并且这些文件非常重要:
如果这些文件已经被暂存,你可以尝试从对象仓库中提取它们。但这些操作直接涉及到Git的核心部分,我不认为你应该尝试。
如果你真的想要,可以阅读以下内容:
git-fetch
,最后执行了 git-merge
。效果非常好。 - Benbob刚刚重新阅读了您的问题。我忽略了您是从项目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 -- <file>
来放弃工作目录中的更改。如果我正确地理解了你的问题,那就是你想做的事情。
git reset --merge
。那些没有受到合并影响的文件保持不变,由于如果您对合并将修改的文件进行了更改,git 将拒绝尝试合并它们,因此它可以很好地覆盖你的基础! - Cascabelreset --hard
命令将它们清除了? - Cascabelreset --hard
。这有点像rm -rf
,在不正确的操作下很危险。 - Benbob