0

我有一个包含许多文件的提交。

提交中的文件之一有几个更改,我想撤消其中一个。

所以,我想我可以重置那个特定的文件,HEAD~让我在工作目录中所做的未完成的更改。然后,我可以使用git add -p并且只暂存所需的更改,然后是git commit --amend.

首先,我确保我的工作目录或阶段没有明显的变化。

然后,我运行了这个命令:

git reset HEAD~ -- path/to/file

但是,令我惊讶的是,git status现在显示了我的工作目录和阶段的更改。进一步检查使用gitk表明我的工作目录和阶段中的更改是相同的。

我在哪里错了?

4

1 回答 1

1

这种重置:

  • 影响自身或当前分支(因此它与、或中的任何HEAD一个都不相同);git reset --hardgit reset --mixedgit reset --soft
  • 确实影响索引的内容;
  • 影响工作树的内容。

因此:

所以,我想我可以重置那个特定的文件,HEAD~让我在工作目录中所做的未完成的更改。然后,我可以使用git add -p并且只暂存所需的更改,然后是git commit --amend.

...是一个很好的计划!但正如您所看到的, 的输出git status变得有点令人惊讶:

git status现在显示对我的工作目录和阶段的更改。

原因是git statusdo 包括运行两个git diffs。如果您可以将索引和工作树命名为git diff(您不能)的参数,则可能是:

  • git diff --name-status HEAD <index>:这是“要提交的更改”。
  • git diff --name-status <index> <work-tree>:这是“未上演提交的更改”。

由于now的索引版本与 的版本匹配,与版本不同,第一个表明存在“阶段性更改”。path/to/fileHEAD~1path/to/fileHEADgit diff

同样,工作树版本与索引版本不匹配,因此git status表示还存在未暂存的更改。

您实际上现在可以运行git add -p. Git 会将索引版本提取到一个临时文件中,将索引版本与工作树版本进行比较,并让您添加对索引版本的更改(来自工作树版本)。

你本可以走一条不同的路线

但是,如果您希望能够看到自己在做什么,最好在一开始就做一个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并开始指向@,并且根本不更改任何其他内容。

于 2017-10-17T20:34:02.167 回答