鉴于我有如下提交:
A - B - C - D - G - H
\ /
- E - F -
如何只跟随父母一起获得完美的线性历史记录?
例如,我想得到:
A - B - C - D - G'- H'
如上所述,预计G和H的sha1会发生变化。 (原因很明显)。如果A,B,C和D的sha1也改变了,那么我想知道原因。
目的是避免在做一个天真的git rebase -i时出现的潜在合并提交。
真正的重点是希望获得额外的洞察力,以确定特定分支中的哪些提交,例如,如果我们有以下图表:
I - J - K - L - M
\ / / /
- N - O - P -
其中N合并为K,但O与--strategy =我们合并为L,而P合并为M.
我希望能够将我的历史线性化,以便可以识别和检查这些有问题的提交。我希望有一个树可以识别O没有被放入上游分支,即使我可能通过使用git cherry识别上游分支中可能缺少N和P,但是这里的任何建议都将受到赞赏
答案 0 :(得分:18)
正如您所说,以下命令有效:
git filter-branch --parent-filter 'cut -f 2,3 -d " "'
为什么?
通过简单提交转换每个合并提交,解决了您提出的问题:这将简单地删除合并的功能分支,因为它们将成为孤儿。
每个提交都有一个或多个父提交。合并提交是获得多个提交的提交。 Git将它存储在历史记录的每个提交对象中。
使用git filter-branch
选项的--parent-filter
命令允许重写每个提交的父级,作为-p SHA1
传递给过滤器,如果有多个父级则重复。我们的过滤器会切断父级并强制每次提交都有一个父级。
对于奖金,这里是如何通过重新创建新提交在精确提交上手动完成:
获取提交树和第一个父
tree=`git show -s --format=%T SHA1`
parent=`git show -s --format=%P SHA1 | cut -d " " -f1`
使用相同的树,相同的消息进行新的提交,并仅将第一个父级保留为祖先
git show -s --format=%B SHA1 | git commit-tree $tree -p $parent
答案 1 :(得分:5)
使用以下方法手动执行:
git rebase -i D-sha1
编辑文件以将G设置为“编辑”。保持并选择H.保存并关闭编辑器。
现在Git允许你编辑G commit,让我们将它修改为F commit的squash merge。你想要:
#cancel the merge commit and position HEAD to D
git reset --hard HEAD~
#squash merge and continue
git merge --squash F-sha1
git rebase --continue
请注意,如果必须在第一次合并中,则必须解决相同的冲突......
正如你所说,你只有G和H的新SHA1。