我弄乱了我的历史,想对它做一些改变。问题是,我有一个包含两个不相关更改的提交,并且这个提交被我的本地(非推送)历史记录中的一些其他更改所包围。
我想在推出之前拆分此提交,但我看到的大多数指南都与拆分您最近的提交或未提交的本地更改有关。从那以后不必“重做”我的提交,对历史中埋藏的提交执行此操作是否可行?
我弄乱了我的历史,想对它做一些改变。问题是,我有一个包含两个不相关更改的提交,并且这个提交被我的本地(非推送)历史记录中的一些其他更改所包围。
我想在推出之前拆分此提交,但我看到的大多数指南都与拆分您最近的提交或未提交的本地更改有关。从那以后不必“重做”我的提交,对历史中埋藏的提交执行此操作是否可行?
在 rebase 手册页中有拆分提交的指南。快速总结是:
执行包括目标提交(例如)的交互式变基git rebase -i <commit-to-split>^ branch
并将其标记为要编辑。
当变基到达该提交时,使用git reset HEAD^
重置到提交之前,但保持工作树完好无损。
增量添加更改并提交它们,根据需要进行尽可能多的提交。add -p
仅在给定文件中添加一些更改可能很有用。如果commit -c ORIG_HEAD
您想为某个提交重新使用原始提交消息,请使用。
如果您想测试您正在提交的内容(好主意!),请使用git stash
隐藏您尚未提交的部分(或stash --keep-index
在您提交之前),测试,然后git stash pop
将其余部分返回到工作树。继续提交,直到你提交所有修改,即有一个干净的工作树。
运行git rebase --continue
以在现在拆分提交之后继续应用提交。
这是使用Magit的方法。
说 commit ed417ae 是您要更改的那个;它包含两个不相关的更改,并隐藏在一个或多个提交下。点击ll
以显示日志,并导航到 ed417ae:
然后点击r
打开rebase弹出窗口
并m
在此时修改提交。
注意@
你想要拆分的提交现在是如何存在的——这意味着 HEAD 现在在那个提交上:
我们想将 HEAD 移动到父级,因此导航到父级 (47e18b3) 并点击x
( ,如果你正在使用,则magit-reset-quickly
绑定到) 并输入说“是的,我的意思是在点提交”。您的日志现在应该如下所示:o
evil-magit
现在,点击q
进入常规 Magit 状态,然后使用常规 unstageu
命令取消暂存第一次提交中未出现的内容,像往常一样提交c
其余部分,然后标记s
并c
省略第二次提交中的内容,完成后:点击r
打开rebase弹出窗口
另一个r
继续,你就完成了!ll
现在显示:
要拆分提交<commit>
并在此之前添加新提交,并保存作者日期<commit>
,- 步骤如下:
编辑之前的提交 <commit>
git rebase -i <commit>^^
注意:也许它也需要编辑<commit>
。
樱桃采<commit>
入指数
git cherry-pick -n <commit>
以交互方式从索引中重置不需要的更改并重置工作树
git reset -p && git checkout-index -f -a
作为替代方案,只需以交互方式存储不需要的更改:git stash push -p -m "tmp other changes"
进行其他更改(如果有)并创建新的提交
git commit -m "upd something" .
或者,重复项目 2-4 以添加更多中间提交。
继续变基
git rebase --continue
如果您只想从一个文件中提取内容,则有一个更快的版本。它更快,因为交互式 rebase 实际上不再是交互式的(如果你想从最后一次提交中提取它当然更快,那么根本不需要 rebase)
the_file
。关闭the_file
。这是您唯一需要的版本,其余的只是 git 命令。在索引中暂存该删除:
git add the_file
将刚刚删除的行恢复到文件中而不影响索引!
git show HEAD:./the_file > the_file
“SHA1”是您要从中提取行的提交:
git commit -m 'fixup! SHA1'
使用步骤 3 恢复的要提取的内容创建第二个全新的提交:
git commit -m 'second and new commit' the_file
不要编辑,不要停止/继续 - 接受一切:
git rebase --autosquash -i SHA1~1
当然,当要提取的提交是最后一次提交时,速度会更快:
4. git commit -C HEAD --amend
5. git commit -m 'second and new commit' thefile
6. no rebase, nothing
如果您使用magit
,则步骤 4、5 和 6 是单个操作:提交、即时修复
通过樱桃采摘手动更正历史记录也适用于某些情况。
我更喜欢使用我的 git GUI(而不是命令行),我的有问题的提交只有 3 次提交,我还没有推送任何,以下的也不是很整洁,所以我选择完全重建所有通过挑选它们,它比通过命令行使用交互式变基编辑更快,但方法相似。
以下是我在我最喜欢的 git GUI 中的做法(我个人使用 SourceTree):
如果您还没有推送,只需使用git rebase
. 更好的是,用于git rebase -i
交互式地移动提交。您可以将有问题的提交移到前面,然后根据需要将其拆分并将补丁移回(如果需要)。