如果不创建一个分支并在一个新分支上做一堆奇怪的工作,那么在将一个提交提交到本地存储库之后,是否有可能将其分解为几个不同的提交?
当前回答
大多数现有的答案都建议使用交互式rebase-git rebase-i或类似的方法。对于像我这样害怕“互动”的人来说,下楼梯时喜欢抓住扶手,这里有一个选择。
假设您的历史看起来像…->P–>Q–>R–>…–>Z=mybranch,并且您希望将P–>Q分成两个提交,以P–>Q1–>Q'–>R'–>…Z'=mybranch结束,其中Q'、R'等处的代码状态与Q、R等相同。
在开始之前,如果你是偏执狂,请备份我的分支,这样你就不会冒失去历史的风险:
git checkout mybranch
git checkout -b mybranch-backup
首先,签出P(要拆分的地方之前的提交),并创建一个新的分支来处理
git checkout P
git checkout -b mybranch-splitting
现在,从Q中签出您想要的任何文件,并根据需要进行编辑,以创建新的中间提交:
git checkout Q file1.txt file2.txt
[…edit, stage commit with “git add”, etc…]
git commit -m "Refactored the widgets"
请注意此提交的哈希值,如Q1。现在,在Q1的分离HEAD上检查Q的完整状态,提交这个(创建Q'),并将工作分支向上拉:
git checkout Q
git reset --soft Q1
git commit -m "Added unit tests for widgets"
git branch -f mybranch-splitting
您现在在Q'处执行mybranch拆分,它应该具有与Q完全相同的代码状态。现在将原始分支(从Q到Z)重设为:
git rebase --onto HEAD Q mybranch
现在,mybranch应该看起来像…P->Q1–>Q'–>R'–>…Z',正如您所希望的那样。因此,在检查所有工作正常后,可以删除工作分支和备份分支,并(如果合适)将重写的mybranch推到上游。如果它已经被推了,你需要强制推,所有关于强制推的常见警告都适用。
git push --force mybranch
git branch -d mybranch-splitting mybranch-backup
其他回答
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
从git rebase手册(拆分COMMITS部分)
在交互模式下,您可以使用“编辑”操作标记提交。然而,这并不一定意味着gitrebase希望这次编辑的结果正好是一次提交。实际上,您可以撤消提交,也可以添加其他提交。这可用于将提交分为两部分:使用gitrebase-i<commit>^启动交互式rebase,其中<commit’是要拆分的提交。事实上,任何提交范围都可以,只要它包含该提交。使用“编辑”操作标记要拆分的提交。在编辑提交时,执行git-resetHEAD^。结果是HEAD被重绕了一圈,索引也随之改变。然而,工作树保持不变。现在,将更改添加到第一次提交时所需的索引中。您可以使用gitadd(可能以交互方式)或gitgui(或两者都使用)来实现这一点。使用现在合适的提交消息提交当前索引。重复最后两个步骤,直到工作树干净。使用git-rebase继续rebase--Continue。
现在,在Windows上的最新TortoiseGit中,您可以非常轻松地完成此操作。
打开rebase对话框,对其进行配置,然后执行以下步骤。
右键单击要拆分的提交,然后选择“编辑”(在拾取、挤压、删除…中)。单击“开始”开始重新定基。一旦到达提交拆分,请选中“编辑/拆分”按钮,然后直接点击“修正”。提交对话框打开。取消选择要单独提交的文件。编辑提交消息,然后单击“提交”。在有文件要提交之前,提交对话框将一次又一次打开。当没有更多的文件要提交时,它仍然会询问您是否要再添加一个提交。
非常有用,谢谢TortoiseGit!
我认为我使用git rebase-I的最佳方式。我创建了一个视频,展示了拆分提交的步骤:https://www.youtube.com/watch?v=3EzOz7e1ADI
如果你有这个:
A - B <- mybranch
如果您在提交B中提交了一些内容:
/modules/a/file1
/modules/a/file2
/modules/b/file3
/modules/b/file4
但是你想把B分解成C-D,得到这样的结果:
A - C - D <-mybranch
例如,您可以这样划分内容(不同提交中来自不同目录的内容)。。。
将分支重置回要拆分的分支之前的提交:
git checkout mybranch
git reset --hard A
创建第一个提交(C):
git checkout B /modules/a
git add -u
git commit -m "content of /modules/a"
创建第二个提交(D):
git checkout B /modules/b
git add -u
git commit -m "content of /modules/b"
推荐文章
- 为什么我需要显式地推一个新分支?
- 如何撤消最后的git添加?
- Rubymine:如何让Git忽略Rubymine创建的.idea文件
- Gitignore二进制文件,没有扩展名
- Git隐藏错误:Git隐藏弹出并最终与合并冲突
- 了解Git和GitHub的基础知识
- 没有。Git目录的Git克隆
- Git与Mercurial仓库的互操作性
- 忽略git中修改(但未提交)的文件?
- “git restore”命令是什么?“git restore”和“git reset”之间有什么区别?
- Git合并与强制覆盖
- Git拉另一个分支
- 在Bash命令提示符上添加git分支
- 如何更改Git日志日期格式
- git pull -rebase和git pull -ff-only之间的区别