我提交了许多文件。
提交中的一个文件有几处更改,其中一个我要撤消。
所以,我想我可以将该特定文件重置回HEAD~
,留下我在工作目录中所做的未完成的更改。然后,我可以使用git add -p
并仅进行所需的更改,然后是git commit --amend
。
首先,我确保我的工作目录或阶段没有未完成的更改。
然后,我运行了这个命令:
git reset HEAD~ -- path/to/file
但是,令我惊讶的是,git status
现在显示了我的工作目录和阶段的变化。使用gitk
进一步检查表明我的工作目录和阶段的变化是相同的。
我在哪里错了?
答案 0 :(得分:1)
这种重置:
HEAD
本身或当前分支(因此它与git reset --hard
的{em>任何不同,git reset --mixed
,或git reset --soft
); 因此:
所以,我想我可以将该特定文件重置回
HEAD~
,留下我在工作目录中所做的未完成的更改。然后,我可以使用git add -p
并仅进行所需的更改,然后是git commit --amend
。
...是一个很好的计划!但正如您所看到的,git status
的输出有点令人惊讶:
git status
现在显示对我的工作目录和阶段的更改。
原因是git status
的作用包括运行两个git diff
。如果你可以将索引和工作树命名为git diff
的参数(你不能),那可能是:
git diff --name-status HEAD <index>
:这是“要提交的更改”。git diff --name-status <index> <work-tree>
:这是“未提交的更改”。由于path/to/file
的索引版本现在与HEAD~1
的{{1}}版本匹配,这与path/to/file
版本不同, HEAD
表示存在“分阶段更改”。
同样,工作树版本与索引版本不匹配,因此git diff
表示还存在未分阶段的更改。
您实际上现在可以运行git status
。 Git会将索引版本提取到临时文件,将索引版本与工作树版本区分开来,并允许您更改索引版本(来自工作树版本)。
如果您希望能够看到您在做什么,那么一开始做git add -p
可能会更好。这种重置:
git reset --soft HEAD~1
找出该分支是什么并进行调整; 现在你将处于和以前类似的位置,但现在你需要:
HEAD
使索引版本与git reset HEAD path/to/file
版本匹配,现在HEAD
命名所需的提交。你提出的那个你不想要的提交 - 你想要HEAD
- 现在已经“超过了分支提示”:
--amend
现在 X [bad commit, now shoved out of the way]
/
...--o--o--@ <-- branch
有意义,因为它将git status
与索引进行比较而不是@
进行索引。 (和以前一样,X
也会将索引与工作树进行比较。)现在,您可以按预期git status
,然后git add -p
,而不需要git commit
部分。
你不必这样做;你可以继续当前的计划。不过,如果您更喜欢此处的--amend
结果,则可以通过执行git status
将当前计划转换为此其他计划。这将更改当前分支名称,使其停止指向git reset --soft HEAD~1
并开始指向X
,并且根本不更改任何其他内容。