硬重置单个文件


1003

我的工作目录中目前有三个修改过的文件。但是,我希望其中之一可以重置为HEAD状态。

在SVN中,我会使用svn revert <filename>svn update <filename>如果需要,请紧随其后),但在Git中,我应该使用git reset --hard。但是,此命令不能在单个文件上运行。

Git中有什么方法可以放弃对单个文件的更改并用新的HEAD副本覆盖它?


3
git checkout下面是答案。在git中,“还原”是您要提交的内容。“还原”将历史提交的逆过程重放到您的工作目录中,因此您可以进行新的提交,以“撤消”还原的提交。我发现对于从svn转到git的人们来说,这经常是一个困惑点。
丹·雷


如果您对为什么无法使用路径进行硬重置感兴趣,请在此处查看我的答案。
用户

这个问题假设,人们知道什么是硬重置。

Answers:


1805

您可以使用以下命令:

git checkout HEAD -- my-file.txt

...这将my-file.txt使用HEAD中的状态更新索引的工作副本及其状态。

--基本上是指:将这之后的每个参数都视为文件名此答案中有更多详细信息。感谢VonC指出这一点。


58
更完整的答案。1)对于' - ',也见stackoverflow.com/questions/6561142/...(以及更一般地,stackoverflow.com/questions/1192180/...
VonC

8
另外,别忘了您可以引用先前的提交HEAD~1以表示倒数第二次提交。
Ryanmt

14
你可以离开了HEAD,如果你是在当前分支的头-看到norbauer.com/rails-consulting/notes/...
CXW

4
有什么见解为什么reset命令(如它所说的)“不能用路径进行硬重置”,然后为什么checkout不(不能使用)命令来硬重置整个集合呢?(我是说为什么要这样设计。)
Sz。

1
@cxw不幸的是,事实并非如此。在手册页上git checkout:“通过替换索引或<tree-ish>中的内容来覆盖工作树中的路径”。即,如果<tree-ish>省略,则索引中的任何内容都将用于更新工作树。这可能与HEAD相同,也可能没有。
tuntap '17

136

重置至头部:

要将单个文件硬重置为HEAD:

git checkout @ -- myfile.ext

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

重置为索引:

要将单个文件硬重置为index,假设索引为非空,否则为HEAD:

git checkout -- myfile.ext

关键是为了安全起见,除非您明确打算重置为索引,否则您不希望遗漏@HEAD退出命令


1
myfile.ext之前的“-”是怎么回事?
Lance Kind'July

3
@LanceKind据我了解,这是用来划分其后的文件名列表的边界。没有它,在某些情况下git会错误地解释参数。
Acumenus

2
不只是文件名。在许多实用程序中,广泛使用的约定将选项与位置参数分开。见man bash页面。在此答案中也提到了:unix.stackexchange.com/a/187548/142855
boweeb

1
按照惯例,--用来告诉程序I've finished specifying "options", and from here on, everything will be a positional argument.。按照惯例,“选项”是--recursive可以以任何顺序出现的令牌,甚至可以像一样以其短形式组合在一起rm -rf。相反,“位置参数”更像是用编程语言传递给函数的参数:它们在令牌列表中的位置定义了程序将要对它们进行什么操作(通常是文件名)。--消除了关于哪个的歧义。
iono


18

Git 2.23(2019年8月)开始,您可以使用restore更多信息):

git restore pathTo/MyFile

以上内容将在当前分支MyFile上的HEAD(最后一次提交)上恢复。

如果要从其他提交中获取更改,则可以倒退提交历史。下面的命令将MyFile在最后一次提交之前获得两次提交。您现在需要-s--source)选项,因为您现在使用master~2而不是master(默认)还原源代码:

git restore -s master~2 pathTo/MyFile

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

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

1
到目前为止最简单的方法。不幸的是,这个答案没有引起足够的重视。
singrium


4

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

git checkout HEAD -- path_to_file/file_name

列出所有更改的文件以path_to_file/filename通过以下命令获取

git status

1

您可以使用以下命令:

git reset -- my-file.txt

添加后,这将更新两个的工作副本my-file.txt


不会按要求更改已修改文件的内容。
拉斐尔

当您添加到存储中时,您是否编辑了文件?
ADDYQU

1
@ADDQU并不是重点。问题是如何“硬重置”文件,而不是将其从暂存列表中删除。
拉斐尔

@Rafael您是正确的,但我想让您知道也有办法。
ADDYQU

0

您可以使用以下命令:

git checkout filename

如果分支具有相同的文件名,则必须使用以下命令:

git checkout -- filename

1
这不会“硬重置”文件-它只会将索引状态复制到工作树中。“硬重置”将首先重置索引。
AH

-20

一种简单,方便,动手的方法,可让您摆脱热水,特别是如果您对git不太满意时:

  1. 查看文件日志

    git log myFile.js

    提交1023057173029091u23f01w276931f7f42595f84f作者:kmiklas日期:2018年8月7日星期二09:29:34 -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知识,并且不会干扰提交历史。


2
与任何早于几年的解决方案相比,该答案要复杂得多且容易出错。
Artif3x

2
为什么有人应该使用此解决方案!?真正的答案只是一个简单的命令。
Milad Rahimi

1
这是在某些情况下的最佳解决方案。对于那些在git发生故障的绑定中的人和需要解决方法的人来说,它是有好处的。
kmiklas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.