【问题标题】:Revert changes to a specific file from a specific commit从特定提交还原对特定文件的更改
【发布时间】:2014-07-19 14:41:59
【问题描述】:

几周前(即之前的许多提交),我做了一个涉及许多文件的 git 提交。大部分提交都很棒。

但是,我现在想撤消我对其中一个文件所做的更改,但我不想覆盖对该文件所做的任何更改之后 提交。

有没有办法让我恢复特定的提交,但仅限于该提交中的一个文件?

【问题讨论】:

标签: git


【解决方案1】:

Torek's answer 肯定更好(而且简单!),但为了完整起见,我想为这个问题添加一些替代(一些天真的)解决方案。

解决方案 1:反向补丁(天真,与 Torek 的解决方案相比)

这与 Torek 的解决方案非常相似。要撤消特定提交对特定文件所做的更改,只需通过将参数反转为 git diff 来获得该提交的反向差异:

git diff <commit> <commit>^ -- <filepath> | git apply

通常,要获取&lt;commit&gt; 引入的更改,您使用命令

git diff <commit>^ <commit>

但是通过颠倒顺序,你最终会得到这些变化的逆,这是一个可以用作补丁的有效差异!

解决方案 2:还原所有文件,然后只提交对特定文件的更改(非常幼稚)

更天真的解决方案是还原添加了您要撤消的更改的提交,但不提交还原。然后从索引和工作副本中删除对其他文件的所有更改:

git revert --no-commit <commit>

# Unstage all changes that revert all files
git reset -- .

# Stage and commit just the reversion changes that you want
git add <yourFile>
git commit -m "Revert changes to <yourFile> from <commit>"

# Undo all reversions changes to the other files
git checkout -- .

这是必要的,因为git revert 不会恢复对单个文件的更改,它目前只恢复整个提交。

【讨论】:

    【解决方案2】:

    在该提交中为该文件获取一个准备好补丁的差异,然后反向应用补丁:

    git show <commit-id> -- <path> | git apply -R -
    

    确保您喜欢结果,如果喜欢,请添加并提交适当的消息。

    【讨论】:

    • 谢谢,但失败了:error: &lt;myFileName&gt;: patch does not apply
    • 这意味着从那时起更改中的某些内容发生了变化,即存在冲突。你可以:尝试添加-3(又名--3way)来使用git的合并机制;或添加--reject(在这两种情况下,添加到git apply 选项),但您必须手动解决冲突。
    • 我想指出,获得反向补丁的天真方法是简单地做git diff &lt;commit&gt; &lt;commit&gt;^ -- &lt;path&gt; | git apply,但我不知道你可以只使用git apply --reverse,那就是绝对是天才!为什么git apply -R - 在最后会有最后的破折号?
    • @Cupcake: git apply 想取一个文件名;文档说- can be used to read from the standard input。不确定它是否会读取标准输入(我总是给它提供文件,至少据我所知)。
    • 谢谢!我用git show &lt;commit-id&gt; -- &lt;path&gt; | git apply -3 -R -
    猜你喜欢
    • 2020-02-14
    • 1970-01-01
    • 2015-09-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 2015-11-24
    • 2014-09-11
    • 1970-01-01
    相关资源
    最近更新 更多