单个文件的硬重置

1738

如何放弃对单个文件的更改并使用最新的HEAD副本覆盖它?我想只对一个文件执行git reset --hard


7
下面是git checkout的答案。在git中,“revert”是你对提交进行的一种操作。 “Revert”会将历史提交的反向重现到您的工作目录中,因此您可以创建一个新提交来“撤消”已经回滚的提交。我发现这是那些从svn转到git的人们经常困惑的地方。 - Dan Ray
1
如果你想知道为什么不能使用路径进行硬重置,请查看我的答案这里 - user
这个问题假设你知道什么是硬重置。 - user8434768
请参见仅将一个文件存储起来的操作:https://dev59.com/m3A75IYBdhLWcg3w6Nhj?rq=1 - qwr
git restore -s main pathTo/MyFile - guettli
9个回答

2992

要将 my-file.txt 的工作副本和其在 Git 索引中的状态都重置为 HEAD 的状态:

git checkout HEAD -- my-file.txt

-- 意味着 "将此点之后的所有参数视为文件名"。更多细节请参考这个答案。感谢VonC指出这一点。


79
更完整的回答。+1 ;) 对于“--”,请参见https://dev59.com/umw15IYBdhLWcg3whME1以及更一般的问题,请参见https://dev59.com/iXM_5IYBdhLWcg3w3nRs#1192194 - VonC
13
还有,不要忘记可以使用HEAD~1来引用先前的提交,以表示倒数第二个提交。 - Ryanmt
24
如果你在当前分支的开头,可以省略 HEAD - 参见 http://www.norbauer.com/rails-consulting/notes/git-revert-reset-a-single-file.html。 - cxw
7
为什么 reset 命令(如其所说)"无法重置带路径的硬重置",以及为什么 checkout 命令不能(或不应该)用于整个设置的硬重置?(我的意思是为什么它被设计成这样。) - Sz.
2
很抱歉,@cxw,这并不完全正确。从git checkout的man页面中可以看到:“通过使用索引或<tree-ish>中的内容替换工作树中的路径来覆盖它们。”也就是说,如果省略了<tree-ish>,则会使用索引中的任何内容来更新工作树。这可能与HEAD相同,也可能不同。 - tuntap
显示剩余3条评论

452

Git 2.23(2019年8月)开始,您可以使用restore命令进行操作(更多信息):

git restore pathTo/MyFile

以上命令将会在当前分支的最新提交HEAD上恢复MyFile

如果您想要获取来自其他提交的更改,可以在提交历史记录中向后查找。下面的命令将获取比最后一个提交早两个提交的MyFile。由于您现在使用的是master~2而不是默认的master,因此需要使用-s--source)选项以恢复源文件:

git restore -s master~2 pathTo/MyFile

你也可以从其他分支获取文件!

git restore -s my-feature-branch pathTo/MyFile

20
目前为止最简单的方法。不幸的是,这个答案没有得到足够的关注。 - singrium
12
值得注意的是,git文档仍将此命令标记为实验性的 - Malhelo
3
"git: 'restore' 不是一个 git 命令。" git 版本为 2.8.2.windows.1 - Buttle Butkus
9
@ButtleButkus在此答案中已经提到2.8版发布于2016年3月28日,并且需要使用2.23或更高版本。 - Chris
3
覆盖本地更改是这个命令的主要目的。是否有其他操作会与此命令混淆? - Chris
显示剩余2条评论

232

重置到最新版本:

若要将单个文件硬重置为最新版本:

git checkout @ -- myfile.ext

请注意,@表示HEAD的缩写。旧版本的git可能不支持这种简写形式。

重置到索引:

为了将单个文件硬重置到索引,假设索引非空,否则重置到HEAD

git checkout -- myfile.ext

重点是为了安全起见,除非你特别想要重置到索引,否则不要在命令中遗漏@HEAD


4
为什么在myfile.ext之前要加上"--"? - Lance Kind
7
据我理解,这是用于标记其后跟随的文件名清单的。如果没有它,有时git会错误地解释参数。 - Asclepius
9
不仅限于文件名。许多实用程序中广泛使用的约定将选项与位置参数分离。请参阅man bash页面。也在此答案中提到:https://unix.stackexchange.com/a/187548/142855 - boweeb
6
传统上,双短横线 -- 用于告诉程序:“我已经完成了所有 '选项' 的设置,从现在开始,接下来的所有内容都将是位置参数。”传统上,“选项” 是像 --recursive 这样的标记,它们可以以任何顺序出现,甚至可以在简短形式中组合在一起,例如 rm -rf。相反,“位置参数” 更像是在编程语言中传递给函数的参数:它们在标记列表中的位置定义了程序要如何使用它们(通常是文件名)。-- 消除了哪个是哪个的歧义。 - iono
这并不是“硬”重置任何东西,它只是应用了某个提交的更改并需要额外的提交。然而,在分支级别上进行硬重置,您的更改将被简单地还原到您想要重置到的提交,而不需要任何额外的提交。 - Farid

99

要还原到上游/主分支,请执行以下操作:

git checkout upstream/master -- myfile.txt

fatal: invalid reference: upstream/master - vsync
3
在这个例子中,upstream 是他们远程仓库的名称。很可能你的是 origin - marcelocra

14

不必引用HEAD。

git checkout -- file.js就足够了。


10

您可以使用以下命令:

git checkout filename

如果您有一个与文件名相同的分支,您必须使用以下命令:

git checkout -- filename

1
这将不会“硬重置”文件 - 它只是将索引状态复制到工作树。进行“硬重置”会先重置索引。 - A.H.

8

您可以使用以下命令重置单个文件

git checkout HEAD -- path_to_file/file_name

列出所有更改的文件,使用以下命令获取 path_to_file/filename
git status

1
你可以使用以下命令:
git reset -- my-file.txt
这将在添加时更新my-file.txt的工作副本。

4
按照要求,不改变修改文件的内容。 - Rafael
4
@ADDQU,那不是问题的重点。问题是如何“硬重置”一个文件,而不是将其从暂存列表中移除。 - Rafael
@Rafael 您是正确的,但我想让您知道还有一种方法。 - ADDYQU

-29

如果你对git不太熟悉,那么这是一个简单、易学、实用的方法,可以帮助你轻松摆脱困境:

  1. 查看文件日志

    git log myFile.js

    提交 1023057173029091u23f01w276931f7f42595f84f 作者:kmiklas 日期:2018年8月7日,星期二 -0400

    JIRA-12345 - 使用新架构进行重构。

  2. 注意文件哈希值:

    1023057173029091u23f01w276931f7f42595f84f

  3. 使用哈希值显示文件。确保它是你想要的:

    git show 1023057173029091u23f01w276931f7f42595f84f:./myFile.js

  4. 将文件重定向到本地副本

    git show 1023057173029091u23f01w276931f7f42595f84f:./myFile.js > myFile.07aug2018.js

  5. 备份当前文件。

    cp myFile.js myFile.bak.js

  6. 在您喜欢的文本编辑器中打开两个文件。

    vim myFile.js
    vim myFile.07aug2018.js

  7. 从myFile.07aug2018.js复制并粘贴代码到myFile.js,并保存。

  8. 提交并推送myFile.js

  9. 再次查看日志,并确认您的文件已正确放置。

  10. 告诉您的客户拉取最新版本,高兴地看着它与旧版本一起工作。

这不是最性感或最 git 中心的解决方案,肯定是一个“手动”重置/回滚,但它有效。它需要对 git 的最少知识,并且不会干扰提交历史记录。


4
这个答案比它之前几年的任何解决方案都更加复杂和容易出错。 - Artif3x
6
为什么任何人都应该使用这个解决方案?真正的答案只有一个简单的命令。 - Milad Rahimi
2
这是某些情况下的最佳解决方案。对于那些遇到git故障并需要解决问题的人,以及需要解决问题的人来说,它具有优点。 - kmiklas
@kmiklas 出于好奇,这里的 特定情况 是指什么? - touch my body
它需要最少的git知识 - 这是一个(巨大的)缺点,而不是优点。 - refaelio

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