如何将文件重置或还原到特定版本?

5680
如何将已修改的文件恢复到特定提交哈希的先前版本(我通过git loggit diff确定)?

20
回滚后,检查 git diff 时不要忘记加上 --cached 参数。 - Geoffrey Hale
7
当我谷歌搜索我的问题时,发现了你的问题。但是当我阅读解决方案后,我检查了我的日志并发现我将这些更改作为独立提交进行了更改,所以我对该提交进行了git还原,而其他一切都像我想要的那样保留下来。这不是解决方案,只是另一种有时可以做到的方法。 - sudo97
我使用以下手动解决方案:$ git revert <commit>,然后取消隐藏所需更改,然后将这些所需更改上传到新提交中。 - Intenzion
36个回答

18

在我看来,之前的回答都不够清晰明了。我想要补充一下我的解释,这段操作非常容易。

首先,假设我有一个提交记录 abc1,而后我对文件 file.txt 进行了几次修改(或只进行了一次修改)。

现在,如果我发现在文件 file.txt 中出了些问题,想回到之前的提交记录 abc1

1. git checkout file.txt:这个操作将撤销本地的所有更改,如果您不需要它们的话。

2. git checkout abc1 file.txt:这个操作将把您的文件还原到您所需的版本。

3. git commit -m "Restored file.txt to version abc1":这个操作将提交您的还原操作。

  1. git push:这个操作将把所有内容推送到远程仓库。

当然,在步骤 2 和 3 之间,您可以运行 git status 命令来了解正在发生的事情。通常情况下,您应该会看到 file.txt 的状态已经被标记为添加状态,这就是为什么不需要运行 git add 命令的原因。


2
好的,我猜步骤1和2是互斥的:如果abc1是您的最后一次提交,则不需要步骤2。如果在abc1之后有其他提交,则可以直接执行步骤2。 - Jean Paul

15
git log --oneline  // you see commits, find commit hash to which you want reset
git diff y0urhash src/main/.../../YourFile.java   // to see difference
git reset y0urhash src/main/.../../YourFile.java   // revert to y0urhash commit
git status                                        // check files to commit
git commit -m "your commit message"
git push origin

Updates were rejected because the tip of your current branch is behind hint: its remote counterpart. Integrate the remote changes - john k

14

这里有许多答案声称使用 git reset ... <file>git checkout ... <file>,但是这样做会使您失去在您想要还原的提交之后提交的 <file> 上的所有修改。

如果您只想针对单个文件还原一个提交中的更改,就像 git revert 只针对一个文件(或一组提交文件)所做的一样,我建议使用 git diffgit apply,像这样操作(其中 <sha> = 您想要还原的提交哈希):

git diff <sha>^ <sha> path/to/file.ext | git apply -R

基本上,它将首先生成与您想要还原的更改对应的补丁,然后将补丁反向应用以删除这些更改。

当然,如果在 <sha1>HEAD 之间的任何提交中修改了被还原的行,则它将无法工作(冲突)。


1
那应该是批准的答案。 我可以建议一个稍微简化的版本: git show -p <sha> path/to/file.ext|git apply -R - Amaury D
你可以使用 <sha>^! 代替 <sha>^ <sha> - cambunctious

12
为了回到文件的先前提交版本,请获取提交号,比如eb917a1。
git checkout eb917a1 YourFileName

如果您只需要回到最近一次提交的版本

git reset HEAD YourFileName
git checkout YourFileName

这将简单地将您带到文件的最后一个提交状态


11

git checkout ref|commitHash -- filePath

例如:

git checkout HEAD~5 -- foo.bar
or 
git checkout 048ee28 -- foo.bar

11

这是一个非常简单的步骤。检出我们想要的提交ID的文件,这里是前一个提交ID,然后只需使用git commit --amend,我们就完成了。

# git checkout <previous commit_id> <file_name>
# git commit --amend

这非常方便。如果我们想将任何文件带到先前提交ID的顶部,我们可以轻松地实现。


谢谢,Abhishek。根据您的回答,我编写了这个Shell脚本:https://gist.github.com/ivanleoncz/c20033e5f4b24304cbc39e0bac1d43e8 请随意改进 :)。 - ivanleoncz
没有起作用。似乎只能撤销指定的提交。不能回滚到该提交之前的所有更改。 - john k

10

你可以通过以下4个步骤实现:

  1. 撤销包含所需撤销文件的整个提交 - 将在您的分支上创建一个新的提交
  2. 软重置该提交 - 删除提交并将更改移动到工作区
  3. 挑选需要恢复的文件并提交它们
  4. 删除您的工作区中的所有其他文件

您需要在终端中输入以下命令:

  1. git revert <commit_hash>
  2. git reset HEAD~1
  3. git add <file_i_want_to_revert> && git commit -m 'reverting file'
  4. git checkout .

祝你好运!


这不会撤销所有更改吗? - arcee123
1
@arcee123 是的,但随后的重置会撤销所有更改的还原。问题在于 git-revert 只对整个仓库进行操作,因此为了补偿,我们必须撤消其他所有操作。 - Timothy
2
我建议使用以下命令:
  1. git revert --no-commit <commit_hash>
  2. git reset HEAD 这样可以避免多余的提交,并且只在您的工作目录中进行所有更改。
- Timothy
@greg-hewgill的回答更好,而且非常准确。这个回答很糟糕,不应该使用。 - Daniel Tranca
这正是需要的真正还原特定文件的方法。我需要撤销一些文件的更改,这些更改来自于早期提交的一些文件,这些文件已经被推送到远程存储库中。我进行了还原、重置和提交操作: git revert _oldcommit_ --no-commit git reset -- _unchanged1_ _unchanged2_ ... git commit -m "branch without changes to specific files" 新分支的末端反映了除还原文件之外的所有更改。 - Suncat2000
@DanielTranca 如果您想要还原更改,Greg Hewgill的答案并不是更好的选择。可能会有其他提交更改了文件的其他部分。Nir M.的答案仅涉及将特定提交中更改的内容还原到单个文件中;他的答案是更好的还原方法,我通过自己实践证实了这一点。 - Suncat2000

9

使用 git log 命令获取特定版本的哈希值,然后使用 git checkout <hashkey> 命令进行切换。

注意:不要忘记在最后一个哈希值之前输入哈希值。最后一个哈希值指向当前位置(HEAD),不会造成任何更改。


8
显然,需要有人撰写一本易懂的git书籍,或者在文档中更好地解释git。面对这个问题,我猜测...
cd <working copy>
git revert master

撤销最后一次提交,看起来似乎成功了。
Ian

6

如果您在上一次提交时提交了错误的文件,请按照以下步骤操作:

  1. 打开源树,切换到此提交

打开源树

  1. 更改行并找到您提交的错误文件所在的提交

输入图像描述

  1. 在该提交中,您可以查看更改列表 源树中的文件列表
  2. 选择它,然后单击右侧的“...”按钮,单击“反转文件”
  3. 然后,您可以在底部左侧的“文件状态”选项卡中看到它, 然后点击“取消暂存”:

文件状态选项卡

  1. 打开Visual Studio Code,通过提交已删除的文件来恢复它们
  2. 完成以上步骤后,您可以在源树中的最后提交中查看结果

输入图像描述


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接