我记录了我的历史,并想对它做一些改变。问题是,我提交了两个不相关的更改,并且此提交被我的本地(非推送)历史记录中的其他一些更改所包围。
我想在推送之前拆分此提交,但我看到的大多数指南都与拆分最近的提交或未提交的本地更改有关。是否可以对历史记录中的提交执行此操作,而不必在此后“重新执行”我的提交?
答案 0 :(得分:440)
有一个拆分提交in the rebase manpage的指南。快速摘要是:
执行包含目标提交(例如git rebase -i <commit-to-split>^ branch
)的交互式rebase,并将其标记为要编辑。
当rebase到达该提交时,使用git reset HEAD^
在提交之前重置为,但保持工作树完整。
逐步添加更改并提交它们,根据需要进行尽可能多的提交。 add -p
对于仅添加给定文件中的某些更改非常有用。如果要为特定提交重新使用原始提交消息,请使用commit -c ORIG_HEAD
。
如果你想测试你提交的内容(好主意!)使用git stash
隐藏你尚未提交的部分(或stash --keep-index
,然后再提交它) ,测试,然后git stash pop
将其余部分返回工作树。继续提交,直到你完成所有修改,即有一个干净的工作树。
运行git rebase --continue
以在现在拆分提交后继续应用提交。
答案 1 :(得分:2)
这是使用Magit的方法。
说提交ed417ae是您要更改的那个;它包含两个不相关的更改,并被隐藏在一个或多个提交中。点击ll
以显示日志,然后导航到ed417ae:
然后按r
打开重新设置弹出窗口
和m
来修改提交。
请注意,@
现在要拆分的提交有多大,这意味着HEAD现在位于该提交:
我们想将HEAD移到父级,因此导航到父级(47e18b3),然后按x
(magit-reset-quickly
,如果您使用的是{{1} }),然后说“是的,我的意思是在点上提交”。您的日志现在应如下所示:
现在,点击o
进入常规Magit状态,然后使用常规unstage evil-magit
命令取消对第一次提交中未执行的操作的处理,其余q
提交像往常一样,然后u
阶段和c
忽略第二次提交中的操作,完成后:按下s
以打开重新设置弹出窗口
和另一个c
继续,您就完成了! r
现在显示:
答案 2 :(得分:1)
要拆分提交<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
答案 3 :(得分:0)
如果您只想从一个文件中提取内容,则有一个更快的版本。之所以更快,是因为交互式变基实际上不再是交互式的(而且,如果您想从上一次提交中提取内容,那么它甚至更快,那么根本就不需要变基)
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步是单个操作:提交即时Fixup
答案 4 :(得分:0)
在某些情况下,通过摘樱桃手动更正历史记录也可以。
我倾向于使用git GUI(而不是命令行),我有问题的提交仅下降了3个提交,我还没有推送任何内容,以下两个也不是很整洁,所以我选择了完全可以通过挑选来完全重建它们,并且比通过命令行使用交互式资源库编辑要快,但是方法相似。
这是我在最喜欢的git GUI(我个人使用SourceTree)中所做的事情:
答案 5 :(得分:-2)
如果您尚未推送,请使用git rebase
。更好的是,使用git rebase -i
以交互方式移动提交。您可以将违规提交移到前面,然后根据需要将其拆分并移回补丁(如果需要)。