单个文件的硬重置

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 的手册页:“通过替换索引或 中的内容来覆盖工作树中的路径”。 IE。如果省略<tree-ish>,则索引中的任何内容都将用于更新工作树。这可能与 HEAD 不同,也可能不同。

以上是关于单个文件的硬重置的主要内容,如果未能解决你的问题,请参考以下文章

如何在单个 HTML / PHP 文件中嵌入图像?

在 Git 中重置所有暂存文件的最简单方法是啥?

linux中的硬连接和软连接

Linux下的硬链接和软链接

Linux文件系统的硬连接和软连接

更改 javascript 文件中的硬编码 ID