簡體   English   中英

GIT:如何強制合並提交到祖先

[英]GIT: how to force a merge commit to an ancestor

在GIT中,我有兩個分支和兩個提交:

 A(master)---B(branch "topic")
  • 分支'master'的HEAD是提交A.
  • 分支'主題'的HEAD是提交B.
  • commit A是提交B的父級

我想在“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-treestdin流中獲取提交注釋。 第一個參數是我們用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

只有在mastertopic之間存在差異時才進行合並提交才有意義 - 如果它們有分歧的話。 在你的情況下,沒有什么可以合並 - 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM