跳过(完整的)暂存区并直接提交文件或补丁?

Skip past (full) staging area and commit file or patch directly?

想象一下这种情况:您正在开发一项需要接触大量文件的功能,并且您已经准备好很多东西,还有很多东西没有准备好(比如调试代码、给自己的临时注释)记住 do/undo 某些事情并且不要忘记添加你还没有时间添加的位),然后你会看到一个简单的单行更改,你必须进行,但属于它自己的提交.

有没有什么方法可以简单地提交它,而不会将所有内容都从您精心添加的暂存区域中拉出来,而无需隐藏(并冒着失去您对暂存内容和不暂存内容的仔细选择的风险)和只提交那一行?

我意识到摆弄 可能会使这成为可能,但我希望有比这更简单的解决方案。一些让我跳过暂存区的开关比使用 GIT_INDEX_FILE 来拥有其中的 2 个更方便。

我理想的解决方案是这样的:

git commit --skip-stage --patch ./app/models/whatever.rb

如果这是不可能,那么我将简单地存储并在弹出时使用--index,希望我没有在存储和存储之间不小心做些什么弹出会破坏干净地恢复索引的能力。

因为我知道有人会想知道“如果你知道 --indexgit stash pop,你为什么要问这个问题?因为它同样是在挑战我能做的事情的极限Git因为它是关于解决一个实际问题。仅仅因为存在一种解决问题的方法并不意味着它是最好的解决方案或者应该停止寻找替代方案。这适用于所有生活,而不仅仅是 Git.

-a标志,git commit -a--only--include标志(可以缩短为-o-i) 允许你做:

git commit --only file1 file2

或:

git commit --include file3

但是这些工作 通过 创建一个新的临时索引,正如我在对您的链接问题的回答中概述的那样。

这些功能有点神奇,可能是也可能不是您想要的。特别是,这些创建的临时索引文件包括 .git/index.lock,这是 Git 的内部临时 new 索引,如果提交成功—之后将成为 the(常规)索引。这会产生一些非常强大(并且有些特殊)的后果。让我们看看每种操作模式。 --only 变体接近您想要的,有时可能 是您想要的 ,但有时可能会破坏一些有价值的东西。

git commit --only file1 file2

首先创建一个从 HEAD 复制的新临时索引。在这个新的临时索引中,Git 从工作树中复制 file1file2,就像 git add file1 file2 一样。所以现在这个临时索引匹配 HEAD 除了两个命名文件。

Git 还通过复制当前索引内容(即暂存文件)来创建 .git/index.lock。在this临时索引中,Git像以前一样复制file1file2。所以 this 临时索引——与第一个不同——有你所有的暂存文件,除了 file1file2 被工作树覆盖。

现在 Git 使用 第一个 临时索引进行新提交——除了两个文件外,最匹配 HEAD 的临时索引。如果这次提交成功,Git 像往常一样更新当前分支,然后删除第一个临时索引,并通过重命名 second 临时索引来解锁和更新真实/常规索引, .git/index.lock,至 .git/index。所以现在正常的索引是之前的样子,除了里面的file1file2被替换了,好像被git add file1 file2.

如果您精心设计了 file1 and/or file2 不同 版本,那(当然)不在您的作品中-tree 现在——因为工作树版本是你用 --only 提交的版本——那个特殊版本 消失了 ,被 git add 消灭了步。如果没有,这可能就是您想要的!

git commit --include file3

在这里,我们假设您之前 git add 编辑了 file1file1 版本 可能与现在略有不同在您的工作树中,因此真实/常规索引中的 file1 不同于 HEAD.

中的 file1

Git 首先创建一个名为 .git/index.lock 的新临时索引,该索引是从真实/常规索引复制而来的。然后,Git 将 file3 复制到这个临时索引中,就像 git add file3.

现在 Git 使用临时 .git/index.lock 索引进行新提交。如果提交成功,Git 照常更新当前分支,然后将临时索引从 .git/index.lock 重命名为 .git/index。所以现在真实/常规索引仍然具有您之前添加的 file1 (可能与工作树中的 file1 不匹配,但与旧提交的 file1 不同),加上您通过 git commit --include 添加的 file3

(此模式永远不会破坏任何精心准备的文件,但也不会执行您在问题中描述的内容。)