![](/img/trans.png)
[英]How to Git rebase interractively squash few commits before merge commit
[英]How to squash two commits which are actually before a merge commit?
假定以下歷史記錄:
X - Y - M - Z <- feature
/ /
A - B - C - D <- master
我想重寫歷史記錄以將X和Y修改為單個提交。 所以我希望歷史看起來像這樣:
X' - M'- Z' <- feature
/ /
A - B - C - D <- master
到目前為止,我所有的嘗試都失敗了。 在大多數情況下,重新設置基准時存在沖突。 也許重新設置基准不是實現此目標的正確方法?
我知道(不知道合並之前的實際情況並沒有真正改變)將重新從主對象合並到特征(M)會導致我在第一位置解決的相同沖突。 可以使用命令“ rerere”來解決此問題,但據目前所知,只有首先也已激活“ rerere”,才有可能。
但是在這種情況下,X-Y與X'具有相同的變更集。 為什么git不夠聰明以至於不能重新應用M? 如果我只在一次提交X'中壓縮X和Y,則原始解析的更改(存儲在M中)應該再次是M'的正確內容。 我怎樣才能告訴git只使用M的舊內容來構建M'?
echo `git rev-parse Y A` >.git/info/grafts
git filter-branch -- --all
rm .git/info/grafts
嫁接是回購本地祖先。 git中任何能夠看到祖先的事物都可以看到嫁接的祖先,特別是重寫提交的事物可以看到它,並將其烘烤到重寫的提交中。
過濾器是shell腳本片段,如果您想提供新的提交消息,則可以例如
git filter-branch --msg-filter="
[ \$commit = `git rev-parse Y` ] && cat <&3 || cat" -- --all 3<<EOD
your new commit message subject
your new commit message body here
...
EOD
git checkout feature
git checkout HEAD~2
git rebase -i HEAD~2
壁球最后兩次提交。 然后使用git cherry-pick
用M
和Z
重寫歷史記錄。
希望能有所幫助。
當我發現黑客入侵時回答我的問題。 我希望git可以做得更好/更輕松,所以我仍在尋求更好的解決方案...
黑客是在沒有提交的情況下再次開始合並。 然后將所有更改從原始合並(M)讀入索引並完成合並。 必須進行重置才能從工作目錄中清除沖突文件。 之后,繼續挑選Z ...
git checkout -b featureRewritten A
git cherry-pick X
git cherry-pick -n Y
git commit --amend #this will actually fixup Y into X
git merge -n C #start the merge without commit
git read-tree M #throw away the staged merge results by
#replacing them with the original solution
git commit #finish commit. need to change the automsg?
git reset --hard HEAD #throw away any left overs
git cherry-pick Z #continue
長期的努力下……更好的解決方案?
另一個解決方案(基於jthill的想法):
git checkout Y
git rebase -i A
#i-rebase: reword X
#i-rebase: fixup Y
git replace Y HEAD
git filter-branch -- --all --ancestry-path Y^!
git replace -d Y
第一次簽出到分離的Y(以Y結尾的未命名分支)。 交互式rebase將Y合並到X中,並重述X的消息。結果是一個新的提交N。HEAD當前指向它。 現在,Y(仍是分支功能的一部分)被N(HEAD)代替。 通過過濾器分支使其永久化。 刪除Y的替換項以擺脫N。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.