在Git中选择性地还原或签出对文件的更改?


88

是否有一条命令可让您部分撤消对工作目录中一个文件(或多个文件)的更改?

假设您已经编辑了很多文件,但是您意识到要撤消某些更改回到已提交状态,而不是其他更改。

我正在预想一个git checkout类似该选项的选项git add -p,即它逐个遍历文件,询问您是否要保留它。

Answers:


85

你可以用

git add -p <path>

暂存要保留在特定文件中的块,然后

git checkout -- <path>

通过检出文件的暂存版本来放弃您不想保留的工作树更改。

最后,您可以使用

git reset -- <path>

将文件的暂存版本还原为文件的最新提交版本,以使您可以撤消更改。


对于这个简单的用例,每隔一个版本控制系统都将其称为“还原”,为什么Git命令如此晦涩?
1

5
@Jan其他版本控制系统的revert命令是否允许您选择还原文件中的哪些更改?真心地询问,因为我只有CVS和Git的经验。在Git中,git checkout -- path/to/file是一个命令,可以还原该文件中的所有更改,但这与上面的命令不同。
michiakig

3
还有git checkout --patchgit reset --patch它类似的工作git add --patch在最新的饭桶。
马特·康诺利

2
@Rudie,--通常指示选项解析的结束,并且其后的所有参数均应按字面解释。这意味着./,如果文件名在后面,则无需在任何以减号开头的文件名之前添加--
zrajm 2014年

当我使用 git checkout --patch差异似乎是倒退。减号是工作副本中的添加文本,加号是工作副本中的删除行。
费利佩·阿尔瓦雷斯

115

使用git version> = 1.7.1我可以

git checkout -p

我不确定何时引入此功能。


11
值得一提的是,您还git reset -p可以选择从登台区域/索引有选择地撤消更改。我也不知道是什么版本的Git引入的。

这是正确的答案,为什么它不被接受。
悟空

1
@wukong,因为此答案已在问题两年后发布。在这一刻(2009年),查尔斯的答案是最好的解决方案
波莫

8

git checkout $file将文件的状态还原为$file最后的提交状态。我认为您可以git checkout SHA-1 -- $file用来将文件还原为SHA-1标识的提交。


1
是的,不完全是我想要的,因为我想保留我在文件中所做的某些更改并还原其他更改
1800 Information,2009年

1

您需要返回多少次提交并选择?如果只是一个,则可能在它之前采取一个分支,签出您提交的文件,然后根据git add -p需要添加它。然后,您可以返回到原来的位置,并从temp分支中检出文件。

那是:

git checkout -b temp troublesome-commit^
git checkout troublesome-commit -- path/to/file
git add -p path/to/file
git commit -c troublesome-commit
git checkout @{-1}
git checkout temp -- path/to/file
git commit path/to/file
git branch -D temp

其他替代方法包括返回并使用来编辑提交git rebase -i(将提交标记为edit,然后执行git reset HEAD^并在将其放回到外壳中时重新提交)。

如果您需要从中进行选择的更改分布在一系列提交中,那么最好将它们提取为补丁(或覆盖所有补丁的补丁)并手动编辑补丁,取出要保留的更改,并将残留物喂入git apply --reverse


我实际上并不想还原已提交的任何内容,我想撤消仅在我的工作副本中所做的更改
1800信息
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.