git:如何 stage/commit 另一个变更集,同时目前已经有一些东西上演了
git: How to stage/commit another changeset while currently already have something staged
我经常遇到这种情况:
编码一天后,我开始对功能进行相关更改。我这样做主要是通过 "git add -p" 选择性地仅添加相关更改(保留调试内容等)。
但后来我意识到我也做了一些同样值得付出的事情。它与功能无关,但影响相同的代码。因此我想先提交这个。不幸的是,我已经花了很多时间来准备这个功能。你如何处理这种情况?
我目前的解决方案是这样的:
(假设功能 "B" 的部分已经上演,现在您意识到有功能 "A")
cp .git/index .git/index_bak #Save partly staged feature B
git reset #Start again
git add -p #Stage only A
git commit #Commit only A
mv .git/index_bak .git/index #Restore stage. This is now a bit strange
#as it seems to remove feature A. Therefore
#reapply feature A (which is still in the
#working directory) again - only to the stage
git diff -U0 HEAD~1.. | git apply --cached --unidiff-zero
git add -p #Continue stageing B
不要打乱你的演出流程。
完成您的初始提交,然后继续进行具有您注意到的功能的提交。
完成所有暂存并(在本地)进行所有提交后,您仍然可以进行交互式变基并对这些提交进行重新排序。
如您所见,手动修改索引有点困难。因此,我建议您习惯于不涉及使用它的工作流程。
这里可能有几个选项可以让您将工作分成多个提交:
最简单的解决方案可能是 首先 查看您的更改,然后再开始 select 您想要提交的更改。这样一来,您就必须首先考虑要上演什么。因此,当您对其中的多个提交进行更改时,您可以先制定该计划,然后才暂存您想要为第一次提交暂存的那些更改。
如果您已经开始暂存提交,然后想要进行不同的提交,您也可以先重置索引。当然,这会丢弃你已经上演的东西,所以你必须在之后重做,但现在你可能知道你需要上演什么,所以它可能会更快。
减少问题的一种方法是实际上撤消那些您不想包含在任何提交中的更改。因此,如果您准备好提交但仍然有调试代码,您无论如何都想摆脱这些代码,您可以在重置索引之前先撤消这些更改。因此,当您随后进行其他提交时,您可以一次添加所有更改,而不必使用 git add -p
.
完成所有操作
另一种方法,这是我经常做的事情,就是提交 parts 然后稍后以交互方式重新设置它们。因此,当您开始为提交 A 暂存,然后遇到提交 B 的内容时,只需提交您已经为 A 暂存的任何内容。然后为提交 B 执行这些内容,然后再次继续 A。完成所有操作后,使用交互式变基以您希望历史实际看起来的方式重新排序和合并提交。
虽然这是最复杂的方法,涉及交互式变基,这可能更高级一些,但它也使您可以更好地控制所有内容,并且您不需要丢弃(暂存)工作,您有已经完成了。
除了 and 的答案,如果你的Git至少是2.5,考虑使用git worktree add
创建一个新的独立分支,在那里你可以做完全独立的工作。请注意,none 未提交的更改(在索引 and/or work-tree 中)将被复制到新添加的 work-tree。
每个 work-tree 都有自己的私有 HEAD
和索引(当然 是 自己独立的 work-tree)。 Git 形成了一个相当强的约束:每个添加的 work-tree 必须位于与其他 work-tree 不同的 不同的 分支上(包括主 work-tree).不过,可以在新建work-tree的过程中新建一个分支,这样就可以轻松应对这个约束了。
我经常遇到这种情况:
编码一天后,我开始对功能进行相关更改。我这样做主要是通过 "git add -p" 选择性地仅添加相关更改(保留调试内容等)。
但后来我意识到我也做了一些同样值得付出的事情。它与功能无关,但影响相同的代码。因此我想先提交这个。不幸的是,我已经花了很多时间来准备这个功能。你如何处理这种情况?
我目前的解决方案是这样的:
(假设功能 "B" 的部分已经上演,现在您意识到有功能 "A")
cp .git/index .git/index_bak #Save partly staged feature B
git reset #Start again
git add -p #Stage only A
git commit #Commit only A
mv .git/index_bak .git/index #Restore stage. This is now a bit strange
#as it seems to remove feature A. Therefore
#reapply feature A (which is still in the
#working directory) again - only to the stage
git diff -U0 HEAD~1.. | git apply --cached --unidiff-zero
git add -p #Continue stageing B
不要打乱你的演出流程。
完成您的初始提交,然后继续进行具有您注意到的功能的提交。
完成所有暂存并(在本地)进行所有提交后,您仍然可以进行交互式变基并对这些提交进行重新排序。
如您所见,手动修改索引有点困难。因此,我建议您习惯于不涉及使用它的工作流程。
这里可能有几个选项可以让您将工作分成多个提交:
最简单的解决方案可能是 首先 查看您的更改,然后再开始 select 您想要提交的更改。这样一来,您就必须首先考虑要上演什么。因此,当您对其中的多个提交进行更改时,您可以先制定该计划,然后才暂存您想要为第一次提交暂存的那些更改。
如果您已经开始暂存提交,然后想要进行不同的提交,您也可以先重置索引。当然,这会丢弃你已经上演的东西,所以你必须在之后重做,但现在你可能知道你需要上演什么,所以它可能会更快。
减少问题的一种方法是实际上撤消那些您不想包含在任何提交中的更改。因此,如果您准备好提交但仍然有调试代码,您无论如何都想摆脱这些代码,您可以在重置索引之前先撤消这些更改。因此,当您随后进行其他提交时,您可以一次添加所有更改,而不必使用 git add -p
.
另一种方法,这是我经常做的事情,就是提交 parts 然后稍后以交互方式重新设置它们。因此,当您开始为提交 A 暂存,然后遇到提交 B 的内容时,只需提交您已经为 A 暂存的任何内容。然后为提交 B 执行这些内容,然后再次继续 A。完成所有操作后,使用交互式变基以您希望历史实际看起来的方式重新排序和合并提交。
虽然这是最复杂的方法,涉及交互式变基,这可能更高级一些,但它也使您可以更好地控制所有内容,并且您不需要丢弃(暂存)工作,您有已经完成了。
除了git worktree add
创建一个新的独立分支,在那里你可以做完全独立的工作。请注意,none 未提交的更改(在索引 and/or work-tree 中)将被复制到新添加的 work-tree。
每个 work-tree 都有自己的私有 HEAD
和索引(当然 是 自己独立的 work-tree)。 Git 形成了一个相当强的约束:每个添加的 work-tree 必须位于与其他 work-tree 不同的 不同的 分支上(包括主 work-tree).不过,可以在新建work-tree的过程中新建一个分支,这样就可以轻松应对这个约束了。