git reset导致工作目录和阶段的更改

时间:2017-10-17 19:56:34

标签: git git-reset working-directory git-stage

我提交了许多文件。

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

所以,我想我可以将该特定文件重置回HEAD~,留下我在工作目录中所做的未完成的更改。然后,我可以使用git add -p并仅进行所需的更改,然后是git commit --amend

首先,我确保我的工作目录或阶段没有未完成的更改。

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

git reset HEAD~ -- path/to/file

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

我在哪里错了?

1 个答案:

答案 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,并且根本不更改任何其他内容。