单个文件的硬重置
Posted
技术标签:
【中文标题】单个文件的硬重置【英文标题】:Hard reset of a single file 【发布时间】:2011-11-01 02:44:45 【问题描述】:我的工作目录中目前有三个修改过的文件。但是我希望其中一个重置为 HEAD 状态。
在 SVN 中,我会使用 svn revert <filename>
(如果需要,后跟 svn update <filename>
),但在 Git 中我应该使用 git reset --hard
。但是此命令不能对单个文件进行操作。
Git 有什么方法可以丢弃对单个文件的更改并用新的 HEAD 副本覆盖它?
【问题讨论】:
git checkout
下面是答案。在 git 中,“revert”是你对提交所做的事情。 “还原”将历史提交的逆向回放到您的工作目录中,因此您可以进行“撤消”还原的提交的新提交。我发现对于从 svn 进入 git 的人来说,这是一个常见的困惑点。
How do I reset/revert a specific file to a specific revision using Git? 的可能重复项
如果您对为什么不能对路径进行硬重置感兴趣,请查看我的回答 there。
这个问题假设人们知道硬重置是什么。
【参考方案1】:
要恢复到上游/主做:
git checkout upstream/master -- myfile.txt
【讨论】:
【参考方案2】:从 Git 2.23(2019 年 8 月)开始,您可以使用 restore
(more info):
git restore pathTo/MyFile
以上将在当前分支的HEAD
(最后一次提交)上恢复MyFile
。
如果您想从其他提交中获取更改,您可以返回提交历史记录。下面的命令将获得MyFile
在最后一个之前的两个提交。您现在需要-s
(--source
) 选项,因为现在您在恢复源时使用master~2
而不是master
(默认值):
git restore -s master~2 pathTo/MyFile
你也可以从其他分支获取文件!
git restore -s my-feature-branch pathTo/MyFile
【讨论】:
迄今为止最简单的方法。不幸的是,这个答案没有得到足够的关注。 需要注意的是,git文档还是把这个命令标记为experimental。 最后一个命令是唯一适用于我的命令。非常感谢! 完全按预期工作。这个命令真的应该得到更多的可见性。git: 'restore' is not a git command.
git 版本 2.8.2.windows.1【参考方案3】:
您可以使用以下命令:
git reset -- my-file.txt
这将在添加时同时更新my-file.txt
的工作副本。
【讨论】:
不按要求更改修改文件的内容。 这并不是@ADDQU 的特别之处。问题是如何“硬重置”文件,而不是将其从暂存列表中删除。 @Rafael 你是对的,但我想让你知道也有办法。【参考方案4】:不需要引用 HEAD。
git checkout -- file.js
就足够了
【讨论】:
【参考方案5】:您可以使用以下命令:
git checkout filename
如果你有一个具有相同文件名的分支,你必须使用这个命令:
git checkout -- filename
【讨论】:
这不会“硬重置”文件 - 它只会将索引状态复制到工作树。 “硬重置”将首先重置索引。【参考方案6】:重置到头部:
将单个文件硬重置为 HEAD:
git checkout @ -- myfile.ext
请注意,@
是 HEAD
的缩写。旧版本的 git 可能不支持短格式。
重置为索引:
将单个文件硬重置为index,假设索引非空,否则为HEAD:
git checkout -- myfile.ext
关键是为了安全起见,您不想在命令中遗漏@
或HEAD
,除非您明确打算仅重置为索引。
【讨论】:
myfile.ext 之前的“--”是怎么回事? @LanceKind 据我了解,这用于划分其后面的文件名列表。没有它,在某些情况下 git 会错误地解释参数。 不仅仅是文件名。在许多实用程序中,广泛使用的约定将选项与位置参数分开。请参阅man bash
页面。此答案中还提到:unix.stackexchange.com/a/187548/142855
通常,--
用于告诉程序I've finished specifying "options", and from here on, everything will be a positional argument.
。按照惯例,“选项”是像--recursive
这样的标记,它可以以任何顺序出现,甚至可以以它们的简短形式组合在一起,比如rm -rf
。相反,“位置参数”更像是在编程语言中传递给函数的参数:它们在标记列表中的 位置 定义了程序将如何处理它们(这些是通常是文件名)。 --
消除了关于哪个是哪个的歧义。
这不是“硬”重置任何它只是应用来自某些提交的更改并需要额外提交的东西。但是,在分支级别硬重置时,您的更改会简单地恢复到您想要重置的提交,而无需任何额外的提交【参考方案7】:
一个简单、容易、动手的方法让你摆脱困境,特别是如果你对 git 不太熟悉:
查看文件日志
git log myFile.js
提交 1023057173029091u23f01w276931f7f42595f84f 添加一名作者 日期:2018 年 8 月 7 日星期二 09:29:34 -0400
JIRA-12345 - 使用新架构进行重构。
注意文件的哈希:
1023057173029091u23f01w276931f7f42595f84f
使用哈希显示文件。确保它是你想要的:
git 显示 1023057173029091u23f01w276931f7f42595f84f:./myFile.js
将文件重定向到本地副本
git 显示 1023057173029091u23f01w276931f7f42595f84f:./myFile.js > myFile.07aug2018.js
备份您当前的文件。
cp myFile.js myFile.bak.js
在您喜欢的文本编辑器中打开这两个文件。
vim myFile.js vim myFile.07aug2018.js
从 myFile.07aug2018.js 复制 n' 粘贴代码到 myFile.js,并保存。
提交并推送 myFile.js
再次查看日志,并确认您的文件正确就位。
告诉您的客户获取最新版本,并愉快地观看它与旧版本一起工作。
不是最性感或最以 git 为中心的解决方案,绝对是“手动”重置/恢复,但它有效。它需要最少的 git 知识,并且不会干扰提交历史。
【讨论】:
这个答案比它早几年的任何解决方案都复杂且容易出错。 为什么有人要使用这个解决方案!?真正的答案只是一个简单的命令。 这是特定情况下的最佳解决方案。对于那些处于绑定状态、git 出现故障的人以及需要解决方法的人来说,它具有优点。 @kmiklas 出于好奇,certain circumstances
是什么理想?【参考方案8】:
您可以使用以下命令重置单个文件
git checkout HEAD -- path_to_file/file_name
使用以下命令列出所有更改的文件以获取path_to_file/filename
git status
【讨论】:
【参考方案9】:您可以使用以下命令:
git checkout HEAD -- my-file.txt
...这将使用 HEAD 更新 my-file.txt
的工作副本及其在索引中的状态。
--
基本上意味着:将此点之后的每个参数都视为文件名。更多细节在this answer。感谢VonC 指出这一点。
【讨论】:
更完整的答案。 +1 ;) 对于“--”,另请参阅 ***.com/questions/6561142/…(更一般地说,***.com/questions/1192180/…) 另外,不要忘记您可以使用HEAD~1
引用以前的提交来指示倒数第二次提交。
如果您是当前分支的负责人,您可以省略HEAD
- 请参阅norbauer.com/rails-consulting/notes/…
任何见解为什么reset
命令(如它所说)“不能使用路径进行硬重置”,然后为什么checkout
命令不(不能?)用于硬重置整套? (我的意思是为什么它被设计成这样。)
@cxw 不幸的是,这并不完全正确。来自git checkout
的手册页:“通过替换索引或 <tree-ish>
,则索引中的任何内容都将用于更新工作树。这可能与 HEAD 不同,也可能不同。以上是关于单个文件的硬重置的主要内容,如果未能解决你的问题,请参考以下文章