如果不创建一个分支并在一个新分支上做一堆奇怪的工作,那么在将一个提交提交到本地存储库之后,是否有可能将其分解为几个不同的提交?


当前回答

我是用rebase做的。编辑提交对我来说不起作用,因为它已经选择了提交文件并允许您对其进行修改,但我想将所有文件添加为未跟踪的文件,这样我就可以选择其中的一些文件。步骤如下:

git rebase-i HEAD~5(我想拆分我历史上第五次提交)复制目标提交ID(稍后需要)用d标记提交以删除它;在提交之后立即添加一行b,以停止重定基础过程,稍后继续。即使这是最后一次提交,这也为您提供了一些空间,让您只需git rebase——在发生错误时中止并重置所有内容。当重新定基达到断点时,使用gitcherry-pick-n<COMMIT ID>。这将在不选择提交本身的情况下选择提交更改,从而使其未被跟踪。在第一次提交时添加所需的文件(或使用gitadd-i和补丁,以便添加特定的块)提交您的更改。决定如何处理剩余的更改。在我的情况下,我希望他们在历史结束时,没有冲突,所以我做了git stash,但你也可以直接提交。gitrebase—继续选择其他更改

作为一个交互式数据库的超级粉丝,这是我能想到的最简单、最直接的一套步骤。我希望这对任何人都有帮助!

其他回答

使用最新提交

如果您只想从现有提交中提取一些内容并保留原始提交,可以使用

git reset --patch HEAD^

而不是git reset HEAD^。此命令允许您重置所需的块。

选择要重置的块后,您将拥有将重置上一次提交中更改的分段块。现在,您更改最后一次提交,从中删除这些更改

git commit --amend --no-edit

您可以通过以下方式将未堆叠的块添加到单独的提交中

git add .
git commit -m "new commit"

不使用最新提交

当然,按照上面的建议,使用gitrebase——interactive来执行之前的一些提交。

离题事实:

在mercurial中,他们有hgsplit——我希望在git中看到hg吸收之后的第二个特性。

如果您的更改主要是添加新内容,则此方法非常有用。

有时您不希望丢失与正在拆分的提交相关联的提交消息。如果您提交了一些要拆分的更改,可以:

编辑要从文件中删除的更改(即删除行或适当更改文件以适合首次提交)。您可以使用所选编辑器和gitcheckout-p HEAD^--path/to/file的组合将一些更改还原到当前树中。将此编辑作为新提交提交,使用类似gitadd的方式;gitcommit-m“删除以后应该更改的内容”,因此您将在历史中进行原始提交,并且还将进行另一次提交,其中包含您所做的更改,因此当前HEAD上的文件看起来就像您希望在拆分后的第一次提交中一样。

000aaa Original commit
000bbb removal of things that should be changed later

使用git-restore HEAD还原编辑,这将创建还原提交。文件将看起来像原始提交时一样,您的历史记录现在看起来像

000aaa Original commit
000bbb removal of things that should be changed later
000ccc Revert "removal of things that should be changed later" (assuming you didn't edit commit message immediately)

现在,您可以使用gitrebase-i将前两个提交压缩/修复为一个,如果您之前没有向其提供有意义的提交消息,则可以选择修改还原提交。你应该留下来

000ddd Original commit, but without some content that is changed later
000eee Things that should be changed later

git rebase-我会做的。

首先,从一个干净的工作目录开始:git状态应该显示没有挂起的修改、删除或添加。

现在,您必须决定要拆分哪些提交。

A) 拆分最近的提交

要拆分最近的提交,首先:

$ git reset HEAD~

现在,以通常的方式单独提交这些片段,根据需要生成任意数量的提交。

B) 将提交拆分到更远的位置

这需要重新定基,即重写历史。要指定正确的提交,您有几个选项:

如果是三次提交,那么$git rebase-i头~3其中3是返回的提交数。如果它在树上比你想数的更远,那么$git rebase-i 123abcd~其中123abcd是要拆分的提交的SHA1。如果您位于要合并到主节点的其他分支(例如,要素分支)上:$git rebase-i主

当您获得rebase编辑屏幕时,找到您想要拆分的提交。在该行的开头,用edit(简称e)替换pick。保存缓冲区并退出。在您要编辑的提交之后,回扣将立即停止。然后:

$ git reset HEAD~

以通常的方式单独提交各个部分,根据需要生成多个提交。

最后

$ git rebase --continue

gitrebase——交互式可用于将提交拆分为较小的提交。关于rebase的Git文档对这个过程进行了简要的演练-拆分提交:

在交互模式下,您可以使用“编辑”操作标记提交。然而,这并不一定意味着gitrebase希望这次编辑的结果正好是一次提交。实际上,您可以撤消提交,也可以添加其他提交。这可用于将提交分为两部分:使用gitrebase-i<commit>^启动交互式rebase,其中<commit’是要拆分的提交。事实上,任何提交范围都可以,只要它包含该提交。使用“编辑”操作标记要拆分的提交。在编辑提交时,执行git-resetHEAD^。结果是HEAD被重绕了一圈,索引也随之改变。然而,工作树保持不变。现在,将更改添加到第一次提交时所需的索引中。您可以使用gitadd(可能以交互方式)或gitgui(或两者都使用)来实现这一点。使用现在合适的提交消息提交当前索引。重复最后两个步骤,直到工作树干净。使用git-rebase继续rebase--Continue。如果您不能绝对确定中间版本是否一致(编译、通过测试套件等),则应在每次提交、测试和修改提交后使用git stash来隐藏尚未提交的更改。

现在,在Windows上的最新TortoiseGit中,您可以非常轻松地完成此操作。

打开rebase对话框,对其进行配置,然后执行以下步骤。

右键单击要拆分的提交,然后选择“编辑”(在拾取、挤压、删除…中)。单击“开始”开始重新定基。一旦到达提交拆分,请选中“编辑/拆分”按钮,然后直接点击“修正”。提交对话框打开。取消选择要单独提交的文件。编辑提交消息,然后单击“提交”。在有文件要提交之前,提交对话框将一次又一次打开。当没有更多的文件要提交时,它仍然会询问您是否要再添加一个提交。

非常有用,谢谢TortoiseGit!