如何在git中撤消部分未分阶段的更改,但将其余部分保留为未分阶段?我想出的方法是:
git commit --interactive
# Choose the parts I want to delete
# Commit the changes
git stash
git rebase -i master # (I am an ancestor of master)
# Delete the line of the most recent commit
git stash apply
这样可行,但如果只有git commit --interactive
这样的内容仅用于恢复更改,那就太好了。有更好的方法吗?
答案 0 :(得分:239)
您可以使用git checkout -p
,它可以让您从工作副本和索引之间的差异中选择单个帅哥来还原。同样地,git add -p
允许您选择要添加到索引的数据库,git reset -p
允许您从索引和HEAD之间的差异中选择单个数据库以退出索引。
$ git checkout -p file/to/partially/revert
# or ...
$ git checkout -p .
如果您希望在恢复它们之前预先对git存储库进行快照以保留这些更改,我喜欢这样做:
$ git stash; git stash apply
如果您经常使用它,您可能想要别名:
[alias]
checkpoint = !git stash; git stash apply
如果你使用一个好的编辑器模式或插件,可以更容易地恢复个人或线条,这可能会为直接选择线条提供支持,因为-p
有时可能有点笨拙。我使用Magit,这是一种Emacs模式,对于使用Git非常有帮助。在Magit中,您可以运行magit-status
,找到要恢复的更改的差异,选择您想要还原的行(或者只是将光标放在您希望还原的块上,如果您想要还原大块一次而不是一次一行),然后按k
以恢复这些特定行。如果您使用Emacs,我强烈推荐Magit。
答案 1 :(得分:22)
git diff > patchfile
然后编辑补丁文件并删除您不想撤消的部分,然后:
patch -R < patchfile
答案 2 :(得分:5)
你可以做到
git checkout master -- path/to/file
对于您要重置的每个文件。
答案 3 :(得分:1)
怎么样
git add -p
仅将您想要的更改添加回索引。答案 4 :(得分:1)
当我运行'git status'时,它说:
$ git status
# On branch fr/fr.002
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: makefile
#
no changes added to commit (use "git add" and/or "git commit -a")
$
因此,要取消未暂停的编辑,它会告诉我运行:
git checkout -- makefile
答案 5 :(得分:1)
Brian Campbell's answer崩溃了我的git,版本1.9.2.msysgit.0,原因不明,所以我的方法是分析我想要保留的数据,丢弃工作副本中的更改,然后取消暂停。
$ git add -p
... select the hunks to keep
$ git checkout -- .
$ git reset HEAD .
答案 6 :(得分:0)
您可以git checkout
并为其指定要撤消的部分的名称。