题 使用Git将特定文件重置或还原到特定版本?


我已经对作为一组文件的一部分提交了几次的文件进行了一些更改,但现在想要将其上的更改重置/还原回以前的版本。

我做了一个 git log 随着一个 git diff 找到我需要的修订版,但是根本不知道如何将文件恢复到以前的状态。


3452
2017-10-18 23:34


起源


还原之后,别忘了 --cached 检查时 git diff。 链接 - Geoffrey Hale
当我用Google搜索我时,我发现了你的问题。但是在我阅读了解决方案之后,我检查了我的日志并发现,我将thouse更改作为一个独立的提交,所以我为该提交做了git revert,其他一切都按照我的意愿保留了。不是解决方案,有时候只是另一种方式。 - sudo97


答案:


假设您想要的提交的哈希是 c5f567

git checkout c5f567 -- file1/to/restore file2/to/restore

git checkout 手册页提供了更多信息。

如果你想恢复到之前的提交 c5f567,追加 ~1 (适用于任何号码):

git checkout c5f567~1 -- file1/to/restore file2/to/restore

作为旁注,我一直对这个命令感到不舒服,因为它用于普通事物(在分支之间切换)和不寻常的破坏性事物(丢弃工作目录中的变化)。


4672
2017-10-18 23:39



如果你搞砸了“abbcdf”而想要版本 就在之前 “abbcdf”,你可以做到 git checkout "abbcdf~1" path/to/file。 - shadowhand
@shadowhand:有没有办法扭转这种局面,所以它就是后来的版本? - aliteralmind
@aliteralmind:不,不幸的是,Git历史快捷方式符号仅在历史上倒退。 - Greg Hewgill
如果您打算使用分支名称 ABCDE (例如。 develop)你会想要的 git checkout develop -- file/to/restore (注意双破折号) - Ohad Schneider
@aliteralmind:实际上,是的,有办法做到这一点:“git log --reverse -1 --ancestry-path yourgitrev..master”然后使用适当的选项来获得git rev。 --ancestry-path将在两个提交之间“画一条线”,-1将显示一个版本,而--reverse将确保发出的第一个条目是最旧的一个。 - Chris Cogdon


您可以使用diff命令快速查看对文件所做的更改:

git diff <commit hash> <filename>

然后,要将特定文件还原到该提交,请使用reset命令:

git reset <commit hash> <filename>

您可能需要使用 --hard 如果您有本地修改选项。

管理航点的良好工作流程是使用标签在时间轴中清晰地标记点。我不太明白你的最后一句话,但你可能想要的是从前一个时间点分支出一个分支。为此,请使用方便的checkout命令:

git checkout <commit hash>
git checkout -b <new branch name>

然后,当您准备合并这些更改时,可以针对主线对其进行重新绑定:

git checkout <my branch>
git rebase master
git checkout master
git merge <my branch>

508
2017-12-17 06:59



'git checkout <commit hash>'命令让我回到了我正在寻找的项目的旧版本,我正在寻找感谢Chris。 - vidur punj
'git reset <commit hash> <filename>'没有更改我想要更改的特定文件。有没有办法检查文件的版本,特别是,不检查整个项目? - Danny
要还原文件 git checkout <commit hash> <filename> 我的工作比对我好 git reset - Motti Strom
不能用 git reset 要重置单个文件,您将收到错误 fatal: Cannot do hard reset with paths - slier
什么更轻松的说:你做不到 git reset --hard <commit hash> <filename>。这会出错 fatal: Cannot do hard reset with paths. 什么Motti Strom说:使用 git checkout <commit hash> <filename> - Hawkeye Parker


您可以使用任何对git提交的引用,包括SHA-1,如果这是最方便的。关键是命令看起来像这样:

git checkout [commit-ref] -- [filename]


306
2018-04-07 21:48



这个答案有什么区别 --,和接受的那个没有? - 2rs2ts
在git中,文件列表前面的' - '告诉git所有下一个参数都应该被解释为文件名,而不是分支名或其他任何东西。有时这是一个有用的歧义。 - foxxtrot
' - '不仅是一个git约定,而是你在* nix命令行中的各个地方找到的东西。 rm -- -f (删除一个名为的文件 -f)似乎是典型的例子。 这里有更多细节 - Hawkeye Parker
只需添加@HawkeyeParker所说的, rm 命令使用getopt(3)来解析其参数。 getopt 是解析命令参数的命令。 gnu.org/software/libc/manual/html_node/Getopt.html - Devy
@Honey是的,这就是我的意思,是的,可能根本不常见。我在不同的地方看过这个例子,也许只是让它变得难忘:众所周知rm -f是可怕的/危险的。但是,关键是,在* nix中有一个文件名 能够 以' - '开头,这会混淆各种命令行解释器,当他们看到' - '时,期望跟随命令选项。它可以是以' - '开头的任何文件;例如,“ - mySpecialFile”。 - Hawkeye Parker


git checkout -- foo

那会重置 foo 对HEAD。你也可以:

git checkout HEAD^ foo

一次修订,等等


244
2017-08-29 20:56



我建议使用语法 git checkout -- foo 如果,以避免任何错误 foo 是一个特殊的东西(如目录或文件名称 -f)。使用git,如果您不确定,请始终使用特殊参数为所有文件和目录添加前缀 --。 - Mikko Rantalainen
Mikko评论的另一个注释: -- 不是git命令,也不是git特有的。它是一个内置的bash,用于表示命令选项的结束。您也可以将它与许多其他bash命令一起使用。 - matthaeus
@matthaeus它既不是特定于bash也不是shell特征。它是在许多不同命令中实现的约定(并由getopt支持)。 - Greg Hewgill


要恢复到最常需要的最后提交的版本,您可以使用这个更简单的命令。

git checkout HEAD file/to/restore

106
2018-01-14 06:15



这个(git checkout HEAD文件/ to / restore)和git reset - 硬件文件/ to / restore之间的区别是什么? - Motti Shneor
1)更容易记住更一般的方式2)无需担心在输入文件名之前按Enter键 - Roman Susi


我刚才遇到了同样的问题而且发现了 这个答案 最容易理解(commit-ref 是要返回的日志中更改的SHA值):

git checkout [commit-ref] [filename]

这会将旧版本放在您的工作目录中,如果您愿意,可以从那里提交。


100
2018-05-27 17:52





如果您知道需要返回的提交数量,可以使用:

git checkout master~5 image.png

这假设你在 master 分支,你想要的版本是5提交回来。


85
2018-04-07 14:03





我想我已经找到了....来自 http://www-cs-students.stanford.edu/~blynn/gitmagic/ch02.html

有时候你只想回去忘记过去某一点的每一个变化,因为他们都错了。

从...开始:

$ git log

它显示了最近提交的列表及其SHA1哈希值。

接下来,键入:

$ git reset --hard SHA1_HASH

将状态恢复到给定提交并永久删除记录中的所有较新提交。


75
2017-12-17 06:53



Git从不删除任何东西。你的旧提交仍在那里,但除非有一个分支尖端指向它们,否则它们不再可用。在使用git-gc清理存储库之前,git reflog仍会显示它们。 - Bombe
@Bombe:谢谢您提供的信息。我检查了一个旧版本的文件。阅读完评论后,我可以使用“gitref”查找部分SHA1哈希值,并使用“checkout”返回最新版本。其他git用户可能会发现此信息有用。 - Winston C. Yang
可能跟着一个 git push --force - bshirley
如果您有未提交的更改, 你会松了 他们如果做git重置 - 硬 - Boklucius
@Bombe - “Git永远不会删除任何东西。你的旧提交仍然存在,但除非有一个分支尖端指向它们,否则它们不再可用。” - 但这样的提交会在一段时间后被修剪,所以“Git永远不会删除任何东西”是不真实的。 - Bulwersator