[英]GIT: how to force a merge commit to an ancestor
在GIT中,我有兩個分支和兩個提交:
A(master)---B(branch "topic")
我想在“topic”分支中創建一個合並提交C(它將A和B作為父級)。 (我知道這看起來很奇怪,並且合並提交將為空。)
A(master)---B---C (branch "topic")
\-------------/
我設法以太復雜的方式創建這個合並提交(見下文)。 有沒有更簡單的方法來創建此合並提交?
謝謝你的回答!
初始狀態:
$ git init plop
Initialized empty Git repository in /tmp/plop/.git/
$ cd plop/
$ git commit -m "Initial commit (commit A)" --allow-empty
[master (root-commit) a687d4e] Initial commit (commit A)
$ git checkout -b topic
Switched to a new branch 'topic'
$ git commit -m "Some work on my topic branch (commit B)" --allow-empty
[topic d4d1c71] Some work on my topic branch (commit B)
$ #OK, we now reached the initial state
一些嘗試:
$ git merge master #Does not work
Already up-to-date.
$ git merge --no-ff -s ours master #Does not work
Already up-to-date.
是否有更簡單的方法來實現以下目標?
$ #Let's try another way (too complex!)
$ git checkout master
Switched to branch 'master'
$ git merge --no-ff topic
Already up-to-date!
Merge made by recursive.
$ git checkout topic
Switched to branch 'topic'
$ git merge master
Updating d4d1c71..641e7ae
Fast-forward
$ git checkout master
Switched to branch 'master'
$ git reset --hard HEAD^1
HEAD is now at a687d4e Initial commit
$ git checkout topic
Switched to branch 'topic'
$ git log #This is what I wanted to reach
commit 641e7aeb614d9b49796e8f11abd3a0290ac08b40
Merge: a687d4e d4d1c71
Author: xxx <yyy.zzz>
Date: Sat Jul 23 12:52:41 2011 +0200
Merge branch 'topic'
commit d4d1c71c87b94335c8852ab7675cbb663965ef7d
Author: xxx <yyy.zzz>
Date: Sat Jul 23 12:50:11 2011 +0200
Some work on my topic branch (commit B)
commit a687d4eb88b9f6d661122a5766dd632dd462fbaa
Author: xxx <yyy.zzz>
Date: Sat Jul 23 12:49:52 2011 +0200
Initial commit (commit A)
UPD :更干凈的方式做同樣的事情而不直接搞亂sha1:
$ echo "merge commit" | git commit-tree topic^{tree} -p master -p topic
4201b6abae6bb06f929ea00fbc35019679d55535
$ git merge 4201b6abae6bb06f929ea00fbc35019679d55535
Updating b826a8e..4201b6a
Fast-forward
甚至是單行命令:
$ git merge $(echo "merge commit" | git commit-tree topic^{tree} -p master -p topic)
有關正在做什么的詳細信息 - 請閱讀完整答案:)
我完全同意其他人的意見,因為它對我沒有任何意義,但如果你真的想要它 - 可以使用如下所述的低級管道命令。
首先,您應該知道父提交的sha1。 我想B有評論'從主題改變',A有評論'從主人改變',我們現在在B(主題分支)。
$ git log --format=oneline -2
b826a8e93ac8da0de5bfb5b70d5f4e7c352a01fa change from topic
8b7653a529fb3ce964fda79bfd57e645441ad893 change from master
然后你應該知道提交B的具體樹對象的sha1:
$ git cat-file -p topic
tree 867f31c455a371756ec353b54d755f51d98d62c4
parent 8b7653a529fb3ce964fda79bfd57e645441ad893
author ivan-danilov <email@gmail.com> 1311518908 +0300
committer ivan-danilov <email@gmail.com> 1311518908 +0300
change from topic
所以它是867f31c455a371756ec353b54d755f51d98d62c4
。 最后你應該執行git-commit-tree
命令:
$ echo "merge commit" | git commit-tree 867f31c455a371756ec353b54d755f51d98d62c4 -p b826a8e93ac8da0de5bfb5b70d5f4e7c352a01fa -p 8b7653a529fb3ce964fda79bfd57e645441ad893
4201b6abae6bb06f929ea00fbc35019679d55535
請注意,我使用了管道重定向,因為git-commit-tree
從stdin
流中獲取提交注釋。 第一個參數是我們用git cat-file
得到的樹的sha1,另外兩個是我們用git log
得到的sha1。
命令輸出是新創建的合並提交的sha1。 現在你想快速轉發主題分支:
$ git merge 4201b6abae6bb06f929ea00fbc35019679d55535
Updating b826a8e..4201b6a
Fast-forward
就這樣。 你有你想要的。
合並相反的方法應該有效:
git branch tmp master # tmp points to A
git checkout tmp
git merge --no-ff -m 'odd merge' topic # merge B+A ==> C
git checkout topic
git reset --hard tmp # topic now points to C
git branch -d tmp
只有在master
和topic
之間存在差異時才進行合並提交才有意義 - 如果它們有分歧的話。 在你的情況下,沒有什么可以合並 - topic
已經擁有所有master
的提交,所以git將不允許你創建一個什么都不做的合並。
如果你在master
中的提交不在topic
,它可以正常工作:
$ git init plop
Initialized empty Git repository in C:/Temp/plop/.git/
$ cd plop
$ git commit -m "Initial commit (commit A)" --allow-empty
[master (root-commit) b6e2e91] Initial commit (commit A)
$ git commit -m "master-only commit (commit C)" --allow-empty
[master 67b491e] master-only commit (commit C)
$ git checkout HEAD~ -b topic
Switched to a new branch 'topic'
$ git commit -m "Some work on my topic branch (commit B)" --allow-empty
[topic 2251f13] Some work on my topic branch (commit B)
$ git merge master
Already up-to-date!
Merge made by recursive.
導致...
* 592ad46 Merge branch 'master' into topic
|\
| * 67b491e master-only commit (commit C)
* | 2251f13 Some work on my topic branch (commit B)
|/
* b6e2e91 Initial commit (commit A)
這個問題沒有正式的解決方案,有一個解決方法。 檢查master
所在的提交,以便您處於分離的HEAD狀態。 然后提交一個空提交。 然后檢查您的topic
分支並合並該空提交。
$ git checkout 9123456 # (the latest commit on master)
Note: checking out '9123456'.
You are in 'detached HEAD' state...
$ git commit --allow-empty -m 'empty commit'
[detached HEAD 9123457] empty commit
$ git checkout topic
Warning: you are leaving 1 commit behind ... 9123457 empty commit
Switched to branch 'topic'
$ git merge 9123457
現在你在主題分支上,因為它是master的直接后代,與master合並沒有任何意義,因為topic包含master擁有的所有更改。 但是,master沒有任何更改主題。
如果您簽出master然后將主題合並到 master,master應該快進並更新其HEAD。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.