【问题标题】:Skip past (full) staging area and commit file or patch directly?跳过(完整)暂存区并直接提交文件或补丁?
【发布时间】:2019-06-16 11:35:28
【问题描述】:

想象一下这样的场景:您正在开发一个需要接触大量文件的功能,并且您有很多东西已经暂存,还有很多东西没有暂存(比如调试代码、临时 cmets 让您自己记住)做/撤消某些事情,不要忘记添加你还没有时间添加的位),然后你会看到一个你必须做的简单的单行更改,但它属于它自己的提交。

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

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

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

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

如果这是不可能,那么当我将其弹出时,我将简单地隐藏并使用--index,并希望我没有意外地在隐藏和弹出之间做了一些破坏干净能力的事情恢复索引。

因为我知道有人会想“如果你知道 --indexgit stash pop,你为什么要问这个问题?因为它既是关于推动我可以用 Git 做的事情,也是为了解决问题一个实际的问题。仅仅因为一个问题的解决方案存在并不意味着它是最好的解决方案,或者人们应该停止寻找替代方案。这适用于所有生活,而不仅仅是 Git。

【问题讨论】:

  • 您不想“跳过”暂存区域 - 本身 - 索引包含 HEAD 的当前状态以及任何暂存阶段。因此,跳过暂存区并创建提交(不更新索引中的这些更改)意味着您实际上会在完成提交后立即分阶段删除刚刚提交的更改。 (但这是对术语的一个小抱怨;我理解你在问什么,这是一个很好的问题。)

标签: git git-commit


【解决方案1】:

-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。因此,这个临时索引(与第一个不同)包含所有暂存文件,除了 file1file2 被工作树覆盖。

现在 Git 使用 first 临时索引进行新的提交,该索引与 HEAD 大部分匹配,但两个文件除外。如果这次提交成功,Git 照常更新当前分支,然后删除第一个临时索引,并通过将 second 临时索引 .git/index.lock 重命名为 @987654344 来解锁和更新真实/常规索引@。所以现在正常的索引是它之前的方式 除了 file1file2 已被替换,就像 git add file1 file2 一样。

如果您小心地制作了一个 不同 版本的 file1 和/或 file2,它们(当然)现在不在您的工作树中 - 因为工作树版本是你用--only 提交的那些——那个特殊版本已经消失了,被git add 步骤消灭了。如果没有,这可能就是你想要的!

git commit --include file3

在这里,我们假设您之前有 git added file1 — 可能与现在在工作树中的 file1版本略有不同,因此 file1在实际/常规索引中与file1 中的HEAD 不同。

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

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

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

【讨论】:

  • 这是一个非常详细的答案!如果我理解正确,关于提交完整文件(任何给定文件中的所有更改),可以总结如下。 --only--include 都忽略未跟踪的文件,但 --include 提交暂存文件加上您在命令行中提到的内容,而 --only 忽略暂存文件并仅提交您在命令行中提到的内容命令行。在我看来,--only 正是我正在寻找的东西,但也许我没有理解您回答中的所有细节。 (稍后我将使用部分文件进行测试并重新阅读您的答案。)
猜你喜欢
  • 2012-09-05
  • 2013-04-10
  • 2018-10-03
  • 2012-02-02
  • 1970-01-01
  • 2017-07-12
  • 2015-09-30
  • 2010-11-12
  • 1970-01-01
相关资源
最近更新 更多