[英]Using Git, how can I log all commits that are merge commits between two specific branches?
假設我的Git存儲庫具有分支master
BranchA
, BranchB
和BranchC
。
現在所有這些分支都已合並為主分支,可能多次(無論出於何種原因,這是一個假設情景)。 我希望能夠找到BranchA
合並為master
所有合並提交。
這是我在問這個問題之前得到的:
git log master ^BranchA --merges --oneline
這讓我獲得了master
所有提交,而不是BranchA
,它們也是合並提交。 這實際上給了我正在尋找的所有提交,但它也可以給我提交我不想要的提交,例如從BranchB
和BranchC
合並到master。
示例輸出:
10bdc8b Merge branch 'BranchA'
383693a Merge branch 'BranchB'
8af3b5c Merge branch 'master' of 192.168.0.0:/path/to/repo.git
aa0f22c Merge branch 'master' into BranchC
72bbf3a Merge branch 'BranchA'
fac1157 Merge branch 'BranchB'
我想找到一個只輸出10bdc8b
和72bbf3a
的解決方案。 而且不要僅僅為'BranchA'這個名字而煩惱; 我知道在這種情況下會起作用,但總是可能給合並提交一個自定義消息,所以它可能並不總是有效。
編輯
到目前為止反應良好,但不幸的是,我碰到了一堵我不知道如何過去的牆。 請考慮以下情形:
F <-BranchB
/ \
/ \
A-----B----C-----D--E----K----L <-master
\ / \ /
\ / \ /
G----H--------I---J <-BranchA
現在,我的目標是找到從BranchA到master的所有合並提交。 通過查看圖表,我可以看到我正在尋找L
和D
然而,阻止我以編程方式解決這個問題的曲線球是合並提交I
,其中master被合並到BranchA中。
在這種情況下,如果我們在master中的所有提交中使用branch --contains
方法,我們得到L
, D
和B
但是,如果我們在master中的所有提交中進行分支 - 包含而不是在BranchA中,我們只獲得L
兩種方法都沒有獲得所需的輸出。
同樣,如果我們使用git merge-base
來查找父節點,我們只得到L
據我所知,似乎沒有一個很好的方法來分離B
和D
,因為這兩個提交都在BranchA的歷史中。 我可以通過看他們說他們是不同的,但Git似乎沒有一個很好的方法來區分他們。
git中沒有單個命令可以從特定分支獲取所有合並,但是您可以將branch --contains
和merge parent walk結合起來。 忽略章魚提交,在主分支上我們對第二個合並父代感興趣:
bash$ for commit in \
$(git log --format=%h --merges --max-parents=2 master ^topic); do \
[[ $(git branch --contains ${commit}^2) =~ topic ]] && \
echo $commit; done
當然你必須確保不合並快進,也就是說,你必須在合並時指定--no-ff
開關,否則你將失去上面的scriplet所依賴的必要的雙父分支。上。
還有一個額外的考慮因素,它是否是一個復雜因素取決於您的具體用例。 在以下示例中,
I--A--M---N---O---F ← master \ / / / `-B-------D ← / ← topicA \ / `--C----E ← topicB
提交B
是合並提交M
的父級,也是E
和D
的祖先。 當您在master
上查詢合並提交時,您將獲得提交F,O,M
,然后當您查詢哪個是topicA
分支合並時,您將獲得M,O
但是當您詢問哪些時,您也將得到M
是一個topicB
分支合並,這是因為B
是兩個分支的祖先。
我認為在Git中沒有直接的方法可以解決這個問題,但我知道如何解決這個問題。 如果是我,我會用Python做這件事。 其他人可能會在Bash中這樣做。
首先,我將獲得A中的合並提交列表以及他們合並的父母:
git log --merges --format="%H %P" A
我將迭代結果中的每一行,查看第三個哈希值(假設所有合並只有兩個父項)。 該行的第一個哈希是合並提交本身的哈希 - 如果這個合並結果是在A和B之間,那就是我們想要的答案。第二個哈希是A分支中的父。 第三個哈希是另一個父,我們想要測試B中的成員資格。因此,對於每個(第三個)哈希,我會調用
git merge-base B <hash>
...如果結果與我輸入的哈希相同,那個提交(行上的第一個哈希)是合並到分支B的分支A.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.