从旧的git提交中恢复文件

289

我有一个几周前提交的旧版本。我想只从这次提交中恢复单个文件。我应该怎么做?


6
可能是 Git 如何重置或恢复某个文件到特定的提交版本? 的重复问题。 - Mayeenul Islam
4个回答

322
git checkout 'master@{7 days ago}' -- path/to/file.txt

这不会更改 HEAD,它只会覆盖本地文件path/to/file.txt

请查看git-rev-parse手册,以获取可能的修订说明(当然,一个简单的哈希值(例如 dd9bacb)也可以很好地完成)

不要忘记提交更改(在审核之后...)


20
哇,@heneryville 和 sehe,我原本以为“7天前”是你们会找到哪次提交的元数据。谢谢! - AnneTheAgile
7
当想要选择特定的提交时,上述格式无效。而是使用Urs所展示的格式: git checkout commitShaNumber -- path/to/file.txt参考自:https://dev59.com/q3VC5IYBdhLWcg3wrDNd - AnneTheAgile
2
@AnneTheAgile 实际上,这仍然是完全相同的语法,我只是碰巧举了一个“复杂”的 revision-specification 的例子,因为这是 OP 提出的问题 :) - sehe
3
如果您的提交用于删除您正在尝试恢复的文件,只需使用 shacommit~1 (例如:git checkout 0f4bbdcd~1 -- path/to/file.txt)获取该提交之前的提交即可。请注意,这里的“shacommit”是指您要恢复的提交的SHA标识符。 - sdlins
我当时真的以为“7天前”是指提交的哈希码。 - Bilal Siddiqui

120
  1. 通过 git checkout [Revision_Key] -- path/to/file 命令从旧的提交中检出文件。
  2. 根据需要添加、提交和推送。

3
git checkout 可以处理单个文件(请参阅 sehe 的答案),无需复制粘贴。 - Koraktor
1
修订密钥是否总是提交的SHA1? - IslandCow
1
它们通常是SHA1的前6到8个字符就足以识别修订版本。 - Urs Reupke
4
不,它们可以是SHA1,但也可以是分支、标签或任何其他指向提交的内容,例如 HEADORIG_HEAD 或任何结合了 ^/~/@-样式注释的内容。 - Alois Mahdal
还适用于(非空)文件夹,如此处所述:https://dev59.com/DWkw5IYBdhLWcg3wwNR5 - Boris Däppen
2
你说要“添加”文件,但那是不正确的。该文件并没有放置在暂存区。它已经被添加了。 - xApple

72

所有答案都提到了 git checkout <tree-ish> -- <pathspec>。自 git v2.23.0 起,有一个新的 git restore 方法,它被认为是 git checkout 的一部分。请参阅变更的亮点在 github 博客

这个命令的默认行为是使用来自source参数的内容还原工作树的状态(在您的情况下将是提交哈希值)。

假设提交哈希值是abcdef,则该命令应如下所示:

git restore --source=abcdef file_name

默认情况下,更改会放置在工作树中。如果您想直接将更改放入索引中,以便可以立即提交:

git restore --source=abcdef --worktree --staged file_name

或者使用简短选项名称:

git restore -sabcdef -W -S file_name

6
这篇回答现在应该成为被接受的答案,因为它使其他回答几乎过时了。 - Akito

20

我需要恢复一个在git中提交的最近文件。

所以为了再次强调并提供另一个视角,你需要通过运行以下两个步骤来完成:

  1. git log -3
    这将显示最近的三个提交记录。阅读注释和作者的名称,以缩小你想要的确切版本。 记下你想要的提交版本的长提交ID(例如:b6b94f2c19c456336d60b9409fb1e373036d3d71)。

  2. git checkout b6b94f2c19c456336d60b9409fb1e373036d3d71 -- myfile.java
    传递提交ID和你想要恢复的文件名。确保在双破折号之前和之后有一个空格。

有许多其他方法可以实现此目的,但这是我能记得的最简单的方法。

注意:如果你在项目路径/文件夹内部,则不需要在checkout命令中键入完整的文件路径。


有史以来最好的评论。因为被接受的答案假设需要获取的文件已经被推送到上游,然而这个命令却获取/恢复了只存在本地的文件。 - alperc
1
刚刚在本地 git 仓库的根目录尝试了这个命令。我仍然需要提供文件的相对路径。只提供 -- [文件名] 并不起作用。 - Ben Wrighton
@ot0 不,它并不假设那样。它们是完全相同的答案。 - matt

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