【问题标题】: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 的人来说,这是一个常见的困惑点。
  • 如果您对为什么不能对路径进行硬重置感兴趣,请查看我的回答 there
  • 这个问题假设人们知道硬重置是什么。

标签: git


【解决方案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 不太熟悉:

      1. 查看文件日志

        git log myFile.js

        提交 1023057173029091u23f01w276931f7f42595f84f 添加一名作者 日期:2018 年 8 月 7 日星期二 09:29:34 -0400

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

      2. 注意文件的哈希:

        1023057173029091u23f01w276931f7f42595f84f

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

        git 显示 1023057173029091u23f01w276931f7f42595f84f:./myFile.js

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

        git 显示 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 复制 n' 粘贴代码到 myFile.js,并保存。

      8. 提交并推送 myFile.js

      9. 再次查看日志,并确认您的文件正确就位。

      10. 告诉您的客户获取最新版本,并愉快地观看它与旧版本一起工作。

      不是最性感或最以 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 ;) 对于“--”,另请参阅 stackoverflow.com/questions/6561142/…(更一般地说,stackoverflow.com/questions/1192180/…
        • 另外,不要忘记您可以使用HEAD~1 引用以前的提交来指示倒数第二次提交。
        • 如果您是当前分支的负责人,您可以省略HEAD - 请参阅norbauer.com/rails-consulting/notes/…
        • 任何见解为什么reset 命令(如它所说)“不能使用路径进行硬重置”,然后为什么checkout 命令不(不能?)用于硬重置整套? (我的意思是为什么它被设计成这样。)
        • @cxw 不幸的是,这并不完全正确。来自git checkout 的手册页:“通过替换索引或 中的内容来覆盖工作树中的路径”。 IE。如果省略<tree-ish>,则索引中的任何内容都将用于更新工作树。这可能与 HEAD 不同,也可能不同。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-19
        • 1970-01-01
        • 1970-01-01
        • 2011-12-17
        • 1970-01-01
        • 2021-05-29
        相关资源
        最近更新 更多