git 重置导致工作目录和阶段发生变化
git reset resulting in changes to both working directory and stage
我有一个包含很多文件的提交。
提交中的一个文件有几个更改,我想撤消其中一个。
所以,我想我可以将该特定文件重置回 HEAD~
,留下我在工作目录中所做的未完成的更改。然后,我可以使用 git add -p
并只进行所需的更改,然后是 git commit --amend
.
首先,我确保我的工作目录或阶段没有明显的变化。
然后,我运行这个命令:
git reset HEAD~ -- path/to/file
但是,令我惊讶的是,git status
现在显示了我的工作目录和阶段的更改。使用 gitk
进一步检查表明我的工作目录和阶段中的更改是相同的。
我哪里错了?
这种重置:
- 不影响
HEAD
本身或当前分支(因此它与[=13的any不同=], git reset --mixed
, 或 git reset --soft
);
- 是否影响索引的内容;
- 不影响工作树的内容。
因此:
So, I was thinking I could reset that particular file back to HEAD~
leaving the outstanding changes I had made in the working-directory. Then, I could use git add -p
and only stage the desired changes, followed by git commit --amend
.
...真是个好计划!但是正如您所见,git status
的输出变得有点令人惊讶:
git status
now shows changes to both my working-directory and stage.
原因是git status
所做的包括运行宁两个git diff
。如果您可以将索引和工作树命名为 git diff
的参数(您不能),那可能是:
git diff --name-status HEAD <index>
: 这是"changes to be committed".
git diff --name-status <index> <work-tree>
: 这是"changes not staged for commit".
由于 path/to/file
的 index 版本现在匹配 path/to/file
的 HEAD~1
版本,这与 HEAD
版本,第一个git diff
表示存在"staged changes"。
同样,工作树版本与索引版本不匹配,因此git status
表示还存在未暂存的更改。
事实上你现在可以 运行 git add -p
。 Git 将索引版本提取到一个临时文件,将索引版本与工作树版本进行比较,并让您向索引版本添加更改(从工作树版本)。
你可以走另一条路
如果您希望能够看到您在做什么,不过,最好在开始时做一个git reset --soft HEAD~1
。这种复位:
- 是否影响当前分支,使用
HEAD
找出那个分支是什么并调整它;
- 不影响索引的内容;和
- 不影响工作树的内容。
您现在的处境与以前类似,但现在您需要:
git reset HEAD path/to/file
使索引版本与 HEAD
版本匹配,现在 HEAD
命名了所需的提交。您不想要的提交(您打算 --amend
)现在是分支提示的 "one past the end":
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
并开始指向 @
,并且什么都不改变。
我有一个包含很多文件的提交。
提交中的一个文件有几个更改,我想撤消其中一个。
所以,我想我可以将该特定文件重置回 HEAD~
,留下我在工作目录中所做的未完成的更改。然后,我可以使用 git add -p
并只进行所需的更改,然后是 git commit --amend
.
首先,我确保我的工作目录或阶段没有明显的变化。
然后,我运行这个命令:
git reset HEAD~ -- path/to/file
但是,令我惊讶的是,git status
现在显示了我的工作目录和阶段的更改。使用 gitk
进一步检查表明我的工作目录和阶段中的更改是相同的。
我哪里错了?
这种重置:
- 不影响
HEAD
本身或当前分支(因此它与[=13的any不同=],git reset --mixed
, 或git reset --soft
); - 是否影响索引的内容;
- 不影响工作树的内容。
因此:
So, I was thinking I could reset that particular file back to
HEAD~
leaving the outstanding changes I had made in the working-directory. Then, I could usegit add -p
and only stage the desired changes, followed bygit commit --amend
.
...真是个好计划!但是正如您所见,git status
的输出变得有点令人惊讶:
git status
now shows changes to both my working-directory and stage.
原因是git status
所做的包括运行宁两个git diff
。如果您可以将索引和工作树命名为 git diff
的参数(您不能),那可能是:
git diff --name-status HEAD <index>
: 这是"changes to be committed".git diff --name-status <index> <work-tree>
: 这是"changes not staged for commit".
由于 path/to/file
的 index 版本现在匹配 path/to/file
的 HEAD~1
版本,这与 HEAD
版本,第一个git diff
表示存在"staged changes"。
同样,工作树版本与索引版本不匹配,因此git status
表示还存在未暂存的更改。
事实上你现在可以 运行 git add -p
。 Git 将索引版本提取到一个临时文件,将索引版本与工作树版本进行比较,并让您向索引版本添加更改(从工作树版本)。
你可以走另一条路
如果您希望能够看到您在做什么,不过,最好在开始时做一个git reset --soft HEAD~1
。这种复位:
- 是否影响当前分支,使用
HEAD
找出那个分支是什么并调整它; - 不影响索引的内容;和
- 不影响工作树的内容。
您现在的处境与以前类似,但现在您需要:
git reset HEAD path/to/file
使索引版本与 HEAD
版本匹配,现在 HEAD
命名了所需的提交。您不想要的提交(您打算 --amend
)现在是分支提示的 "one past the end":
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
并开始指向 @
,并且什么都不改变。