向已合并的特性分支添加提交并改写线性提交历史的操作方法咨询
首先先把你当前的项目提交历史贴出来,方便咱们对应操作:
* 3ee3af6 (HEAD -> master) Rename project to Hard Disk Drive Stress Test * 36f6c14 Off-by-one error in blkvec.c * d23cd85 Merge branch 'randomio' |\ | * 61f641f (randomio) Add the random I/O implementation (read&write) | * 27146b6 Changed hash function signature | * d6078c8 Add very ugly timespec manipulation functions | * 88fd131 Add hash routine and test program | * 7c701ee Add feistel test programs | * ccf9d4a Remove randwalk "upper bound" capability | * eee6b9b Add the random walk functions | * 968ce05 Add opt parse support for sequential/random I/O |/ * fc4833c Lower the maximum amount of bad blocks we'll track.
没问题,既然你明确要改写历史来保持提交记录的线性,我给你一步步拆解具体操作,保证你的历史看起来顺顺当当的:
第一步:回到目标提交,建个临时分支干活
咱们得先跳转到randomio分支最后那个提交61f641f的位置,为了安全起见,最好基于它创建一个临时分支,避免不小心弄丢修改:
git checkout -b temp-fix 61f641f
要是你嫌麻烦,直接git checkout 61f641f进入分离头指针状态也能干活,但临时分支更稳妥,毕竟咱们改的是历史,稳点没毛病。
第二步:完成修改并提交
现在你可以放心删掉那个多余的文件,或者完成你要做的其他调整,然后把这个修改提交上去:
# 举个例子,删除多余文件 git rm stray-file.c # 提交的时候写清楚备注,符合你项目的历史风格 git commit -m "Remove stray file related to random I/O implementation"
这时候你的temp-fix分支就多了一个新提交,刚好接在61f641f后面,完美契合你要的逻辑顺序。
第三步:把master的后续提交“挪”到新提交后面
接下来就是关键的一步——把master上原来在合并之后的那些提交(就是d23cd85、36f6c14、3ee3af6这几个),逐个移到咱们刚加的新提交后面,这样整个历史就会变成完全线性的,连合并节点都没了。
先切回master分支:
git checkout master
然后执行变基操作,把master的提交变基到temp-fix分支的最新提交上:
git rebase temp-fix
Git会自动帮你把master上原来的后续提交,依次应用到新提交的后面,等操作完成,你用git log --graph --oneline看一下,历史会变成从fc4833c开始,接着是randomio分支的所有提交,然后是你新加的提交,最后是master原来的那几个后续提交,完完全全一条直线,连个分叉都找不到。
第四步:清理临时分支(可选)
等你确认历史完全符合预期,就可以把那个临时分支删掉了,留着也没用:
git branch -D temp-fix
必须要注意的坑
- 如果仓库已经推到远程了:因为咱们改写了历史,所以推送到远程的时候得用
git push --force-with-lease(这个比直接--force安全,能避免不小心覆盖别人的修改),但一定要提前跟团队里的所有人说清楚你改了历史,让他们把本地分支同步到新的历史版本,不然会搞出大冲突。 - 先做本地备份:要是你怕操作出错,最好在开始前先给master建个备份分支,比如
git branch master-backup,万一搞砸了,直接切回备份分支就能恢复。 - 只在你完全掌控的仓库这么干:要是这个仓库是公共的或者多人协作的,改写历史会给其他开发者带来超大麻烦,除非所有人都同意这么做,否则千万别碰。
这样操作完,你的项目历史就完全是你想要的线性结构,那个新提交也乖乖待在randomio分支的提交后面,逻辑上完全顺理成章啦。
内容来源于stack exchange

