【问题标题】:Revert changes to a file in a commit在提交中恢复对文件的更改
【发布时间】:2011-02-06 22:12:40
【问题描述】:

我只想恢复特定提交对给定文件所做的更改。

我可以使用 git revert 命令吗?

还有其他简单的方法吗?

【问题讨论】:

标签: git version-control revert


【解决方案1】:

git revert 用于提交中的所有文件内容。

单个文件可以script it:

#!/bin/bash

function output_help {
    echo "usage: git-revert-single-file <sha1> <file>"
}

sha1=$1
file=$2

if [[ $sha1 ]]; then
git diff $sha1..$sha1^ -- $file | patch -p1
else
output_help
fi

(来自smtlaissezfairegit-shell-scripts 实用程序)


注意:

如果您尚未提交当前修改,另一种方法是 described here

git checkout -- filename

git checkout 有一些文件选项,从 HEAD 修改文件,覆盖您的更改。


Dropped.on.Caprica 提到in the comments

您可以为 git 添加一个别名,这样您就可以执行 git revert-file &lt;hash&gt; &lt;file-loc&gt; 并恢复该特定文件。
this gist

[alias]
  revert-file = !sh /home/some-user/git-file-revert.sh

【讨论】:

  • 只是为了添加到这里的讨论中,您可以向 git 添加一个别名,以便您可以执行 git revert-file &lt;hash&gt; &lt;file-loc&gt; 并恢复该特定文件。我从这个答案中解脱出来(尽管我必须进行一些编辑才能正常工作)。你可以在这里找到我的.gitconfig 和编辑脚本的副本:gist.github.com/droppedoncaprica/5b67ec0021371a0ad438
  • @Dropped.on.Caprica 好点。我已将其包含在答案中以提高知名度。
【解决方案2】:

我会简单地将--no-commit 选项用于git-revert,然后在最终提交之前从索引中删除您不希望恢复的文件。下面是一个示例,展示了如何在最近的第二次提交中轻松恢复对 foo.c 的更改:

$ git revert --no-commit HEAD~1
$ git reset HEAD
$ git add foo.c
$ git commit -m "Reverting recent change to foo.c"
$ git reset --hard HEAD

第一个git-reset“取消暂存”所有文件,这样我们就可以只添加我们想要恢复的文件。最后的git-reset --hard 删除了我们不想保留的剩余文件还原。

【讨论】:

    【解决方案3】:

    herehere 描述了我见过的最干净的方法

    git show some_commit_sha1 -- some_file.c | git apply -R
    

    与 VonC 的响应类似,但使用 git showgit apply

    【讨论】:

    • 做得很好。脚本解决方案对此太过分了。为什么不能只有 git revert sha-1 文件名?
    • 这适用于我的 Mac,但在 Windows(在 Cygwin 下)它给了我:fatal: unrecognized input
    • 只是一个提示,当补丁失败时,我几乎总是必须将 -3 标志添加到 git apply 以进行三向合并,因为我通常会及时更正更改。
    • 对大多数人来说可能很明显,但请确保some_file.c 包含文件的路径(如果有的话),否则您将默默地修补任何内容:)
    • 不适用于二进制文件。尽管如此,我还是复制了原始文件并执行了 git add/git commit --amend.
    【解决方案4】:

    假设可以更改提交历史记录,这里有一个工作流来恢复先前提交中单个文件中的更改:

    例如,您想在提交 aaa222 中恢复 1 个文件 (badfile.txt) 中的更改:

    aaa333 Good commit
    aaa222 Problem commit containing badfile.txt
    aaa111 Base commit
    

    基于基本提交,修改问题提交,然后继续。

    1) 启动交互式变基:

    git rebase -i aaa111
    

    2) 通过将pick 更改为e(用于编辑)在编辑器中标记问题提交以进行编辑:

    e aaa222
    pick aaa333
    

    3) 恢复对坏文件的更改:

    git show -- badfile.txt | git apply -R
    

    4) 添加更改并修改提交:

    git add badfile.txt
    git commit --amend
    

    5) 完成变基:

    git rebase --continue
    

    【讨论】:

    • 只想指出,这是假设您可以编辑 git 历史记录。上面的一些答案会创建一个新的提交,它会在不编辑历史记录的情况下反转特定的更改,这并不总是可能/允许的。
    • 太棒了。这正是我想要的。我已经有了这个想法,但是在执行edit 时的文件没有显示为已更改的交互式 rebase 时感到困惑。但是git show -- badfile.txt | git apply -R 给出了我需要的答案
    • 如果我理解这个 git apply -R 会删除该文件上的提交,将其设置回原来的更改状态?
    【解决方案5】:

    简单得多:

    git reset HEAD^ path/to/file/to/revert
    

    然后

    git commit --amend   
    

    然后

    git push -f
    

    文件消失了,提交哈希、消息等是相同的。

    【讨论】:

    • 为了完整起见,您需要git checkout -- path/to/file/to/revert 步骤吗?此外,哈希之后的哈希值是不一样的,对吧?最后一句话可能会更好,例如:“结果是最后一次提交被替换为新提交,不同之处仅在于它不包含对恢复文件的更改。”
    • @Kevin 你可能是对的。我必须仔细检查最后一行,但回顾几年前的情况,如果提交哈希没有改变,我会感到惊讶。
    【解决方案6】:
    git reset HEAD^ path/to/file/to/revert/in/commit
    

    上面的命令会从提交中取出文件,但它会反映在git status中。

    git checkout path/to/file/to/revert/in/commit
    

    上述命令将还原更改(因此您获得的文件与 HEAD 相同)。

    git commit
    

    (通过--amend 修改提交。)

    git push
    

    这样,已经在提交中的文件被删除并恢复。

    上述步骤应从提交的分支开始。

    【讨论】:

      【解决方案7】:

      您可以按照以下步骤操作:

      1. git revert -n &lt;*commit*&gt; (-n 还原所有更改但不会 提交他们)
      2. git add &lt;*filename*&gt;(您要还原和提交的文件的名称)
      3. git commit -m 'reverted message'(添加回复消息)
      4. 提交后丢弃其他文件更改,以便文件保留 使用您在还原之前提交的更改进行了更新

      【讨论】:

        【解决方案8】:

        如果您想重置上次提交后对文件所做的更改,我通常会使用这种方式。我认为这是最简单的解决方案。

        请注意,文件将被添加到暂存区。

        git checkout <prev_commit_hash> -- <path_to_your_file>
        

        希望对你有帮助:)

        【讨论】:

        • 如果您不想重写历史记录,这就是您要走的路。我一直在使用它来清理在壁球合并之前我真的不需要触摸的文件。无论如何,流失都会被铺平。
        猜你喜欢
        • 2019-07-11
        • 2020-12-22
        • 2013-01-29
        • 2020-05-15
        • 2011-03-15
        • 2011-08-14
        • 2016-03-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多