2009-07-10 53 views
123

在我的git仓库中,跟踪svn仓库,我对一个文件进行了一些编辑。git选择性恢复文件的本地更改

现在我想恢复这些更改(如svn恢复),但只有部分文件。

我希望能够查看文件上的差异,放弃(恢复)我不想要的更改并保留所需的更改。

git add -i 

命令似乎有一个选项来做到这一点,但我不想尚未阶段这一点。

回答

74

您可以直接使用git checkout -p来做到这一点。请参阅下面的Daniel Stutzbach's answer


老答案(之前被介绍checkout -p):

你可以这样说:

git add -i 

(选择要保留大块)

git commit -m "tmp" 

现在,您只有对您所做的更改提交nt保留,其余的不分配。

git reset --hard HEAD 

在这一点上,提交的修改已经被丢弃,让您拥有一个干净的工作目录,你要保持坚定顶部的变化。

git reset --mixed HEAD^ 

这会删除最后一个提交('tmp'),但会保留您的工作目录中的修改,为非暂存。

编辑:用--mixed替换--soft,清理集结区。

3

你可以对文件运行git diff,保存生成的差异,修改或移除你要保存更改,然后运行它通过​​3210撤消剩余的diff。

git diff file.txt >patch.tmp 
# edit patch.tmp to remove the hunks you want to keep 
patch -R <patch.tmp
+0

我在我的补丁文件中有2个hunk,并删除了一个。不知道是什么原因,但补丁-R一直拒绝与此。 – Pradeep 2009-07-10 12:40:55

+2

您在另一条评论中提到`git diff`显示整个文件已更改。这通常发生在您使用与之前不同的行结尾保存文件时。这也会导致`patch`拒绝补丁文件。这听起来像可能发生的事情吗? – 2009-07-10 12:50:13

+0

你是对的。每当我使用patch命令时,行结束符都会切换。我在窗户上使用cream/vim。首先需要对此进行分类。 – Pradeep 2009-07-10 12:58:23

2

看起来像你想

git revert --no-commit $REVSISON 

然后可以使用

git diff --cached 

,看看会做出怎样的改变commiting之前(如需要恢复的仅仅是在前进方向上的承诺是复制过去的变化)

如果你是一个pur e Git存储库,您可以根据自己的目标利用交互式重定位(git rebase -i)返回到您不喜欢的提交,并追溯编辑提交,以便您不喜欢的更改从未发生过,但通常情况下只适用于如果你知道你永远不会想再看到它。

1

重新阅读这个问题,它听起来像是要恢复工作树中的更改,而不是之前已经提交的更改,但其他一些答案使其听起来像我的阅读可能是错误的。你能澄清吗?

如果变化只是在你的工作拷贝,然后做到这一点的最简单方法是阶段,你要保持与变化:

git add -i <file> 

然后扔掉你不想要的变化通过检查索引版本保持:

git checkout -- <file> 

然后unstage的变化,如果你不想让他们上演尚未:

git reset -- <file> 

此配方只会将选定的更改还原到文件(或您指定的文件),并且不会创建任何需要还原的临时提交。

如果你想选择仅适用于一些在以前提交所做的更改,那么你可以将文件恢复到以前提交状态第一:

git reset <commit_before_first_unwanted_change> -- <file> 

然后你就可以按照git add -i <file>以前的配方阶段您想要保留的那些更改,git checkout -- <file>可以丢弃不需要的更改,git reset -- <file>可以“暂停”更改。

279

我相信你可以做到这一点最简单的:

git checkout -p <optional filename(s)> 

从手册页:

−p, −−patch 
     Interactively select hunks in the difference between the <tree−ish> 
     (or the index, if unspecified) and the working tree. The chosen 
     hunks are then applied in reverse to the working tree (and if a 
     <tree−ish> was specified, the index). 
 This means that you can use git checkout −p to selectively discard 
     edits from your current working tree. 
0

的答案下面介绍的命令行选项是很方便的文件的时候在我通过ssh终端访问的服务器上。 但是,当文件在我的本地机器上时,我更喜欢以下方式:

在netbeans编辑器(它附带有git支持)中打开该文件。 Netbeans在行号处标记红色/绿色/蓝色标记以指示哪些内容被删除/添加/修改(分别)。

右键单击这些标记中的任何一个都可以让您选择撤销该更改。 此外,您可以右键单击红色和蓝色标记以查找弹出窗口中的旧版本。