想象一下您已经上演并提交了许多更改,但是随后决定应该将更改分成两次提交。对于新创建的文件,您可以分阶段从提交中删除它们,而不必从磁盘中删除它们(使用git rm --cached filename
)。修改文件有类似的命令吗?
从本质上讲,我希望能够从上一次提交中暂存文件的版本,然后在以后重新运行git add -p filename
以选择哪个更改属于第一个新提交而不是第二个新提交。我不想更改磁盘上的任何内容;我唯一的目标是用最少的工作将一次提交分成两部分。
git checkout HEAD~1 -- filename
分阶段执行我想要的操作,但是从磁盘中删除更改。我需要它们保留在磁盘上,以便可以将它们添加到下一个提交中。 (注意:您可以使用git reset filename && git checkout filename
撤消此命令)
git add HEAD~1 -- filename
感觉像它应该做我想要的,但是命令无法在fatal: pathspec 'HEAD~1' did not match any files
中运行
答案 0 :(得分:2)
phd noted一样,git reset
可以做到这一点,因为git reset
的许多潜在工作之一是将文件从提交复制到索引,而无需触摸工作,树。
这有点令人惊讶,因为git reset
的 default 作业通过将当前分支(如HEAD
所示)移动到某个新分支而开始用户指定的提交,并且可能只有 then (取决于--soft
与--mixed
与--hard
的关系),还将文件从用户指定的提交复制到索引,然后也许进入工作树。但是,将git reset
与路径名一起使用时,它会更改策略,从而完全放弃移动当前分支作业。这就是为什么git reset
不允许--hard
,--soft
或--mixed
带有路径名的原因。
当git reset
移动当前分支时,如果您(用户)未指定某些特定的提交,则git reset
选择的提交就是当前分支命名的提交。因此,从提交$old
到提交$new
的“移动”是$old
是 $new
的地方,根本没有动静。这就是为什么不带参数的git reset --soft
是不操作的原因,并且不带参数的git reset --mixed
或git reset --hard
不会更改哪个提交是当前提交,但是会重置索引并且可能也是工作树。
最终我总是认为git reset
将太多的动作打包到一个面向用户的命令中:它应该至少是两个,并且可能是更多的独立的面向用户的命令,所有这些都可能 run < / em> git reset
作为其我们如何完成此面向用户目标的操作的管道版本。 git checkout
命令也可以执行此操作,因为它有多个不同的用户目标(切换到新分支,从一个特定的提交中获取一个特定的文件而无需切换分支,等等。