如何在我之前的提交中回滚1个文件更改

时间:2010-06-30 06:47:10

标签: git

我在git中做了2次提交(我没有推),其中'Commit 2'是最新的':

 git log -2
commit 791962d776f66253d656586b097b2677eaa983d1
Author: michael <michael@michael-laptop.(none)>
Date:   Tue Jun 29 23:20:58 2010 -0700

    Commit 2

commit b743075e81f6fe25fe48ddbef2b5e7cc06623533
Author: michael <michael@michael-laptop.(none)>
Date:   Tue Feb 16 23:09:53 2010 -0800

    Commit 1

在我的提交1 b743075e81f6fe25fe48ddbef2b5e7cc06623533中,我触摸/更改了许多文件:

   dir1/file1.cpp
   dir1/file1.h
   dir1/file2.cpp
   dir1/file2.h

我的问题是,如何回滚我对提交1的dir1 / file2.cpp,dir1 / file2.h所做的更改?并保持其他一切相同?

谢谢。

3 个答案:

答案 0 :(得分:5)

最简单的解决方案是,从您的最新提交(HEAD)到:

  • checkout旧版本的两个文件
  • 添加它们,
  • 然后提交。
    git checkout b743075e81 -- dir1/file2.cpp
    git checkout b743075e81 -- dir1/file2.h
    git add dir1/file2.cpp # only if you made additional changes
    git add dir1/file2.h   # only if you made additional changes
    git commit -m "revert dir1/file2.cpp and dir1/file2.h"

在评论中提及Chris Johnsen

  带有pathspecs的

git checkout会更新索引(例如带有路径规范的git reset)和工作树,因此除非进行了其他更改,否则不需要git add结帐。

答案 1 :(得分:3)

如果您已将提交推送到原点,则此处描述的其他解决方案(使用git resetgit checkout,后跟git commit)是您唯一明智的选择。< / p>

但是,如果尚未推送您的更改,您要删除文件曾提交的所有跟踪,交互式rebase是一个不错的选择。使用以下命令来重新设置最后两次提交:

git rebase --interactive HEAD~2

编辑器将打开,显示您的两个提交。您想编辑文件以显示以下内容,然后保存;特别是,您希望在第一次提交之前将pick更改为edit

edit b743075 Commit 1
pick 791962d Commit 2
然后,Git将我们置于一个状态,我们可以编辑第一个提交(不触及第二个提交)。它说你可以使用git commit --amend修改提交,但我们实际上想要在head之前重置提交,并完全撤消它:

git reset HEAD^

这会将Commit 1中的更改​​重新放回到您的工作树中。然后,git add仅保留您要保留的文件,并使用git commit重新提交它们:

git add dir1/file1.cpp
git add dir1/file1.h
git commit -m "Commit 1"

最后,执行硬重置以删除您不想从工作树中保留的文件,并完成rebase:

git reset --hard
git rebase --continue

当rebase完成后,您的存储库将同时进行两次提交,但没有file2.*个文件的痕迹。

答案 2 :(得分:0)

使用以下命令根据您需要还原的提交哈希和文件名回滚具有以前提交的文件的文件

 git reset <commit hash> <filename>

根据您的要求使用

 git reset b743075e81f6fe25fe48ddbef2b5e7cc06623533 dir1/file2.cpp

 git reset b743075e81f6fe25fe48ddbef2b5e7cc06623533 dir1/file2.h