簡體   English   中英

獲取合並分支分支的提交(中間合並)

[英]Get commit where merged branch forked from (with intermediate merge)

讓我們使用最新的git 2.16.2和tig 2.3.3。

cd /tmp && mkdir fit && cd fit

git init
touch m1 && git add m1 && git commit -m "master 1"
touch m2 && git add m2 && git commit -m "master 2"
git checkout -b develop
touch d1 && git add d1 && git commit -m "develop 1"
git checkout master
touch m3 && git add m3 && git commit -m "master 3"
git checkout develop
git merge master --no-edit
touch d2 && git add d2 && git commit -m "develop 2"
touch d3 && git add d3 && git commit -m "develop 3"
git checkout master
git merge develop --no-edit
touch m4 && git add m4 && git commit -m "master 4"

git reflog expire --expire=now --all && git gc --prune=now --aggressive

TIG 在此處輸入圖片說明

檢索develop分支中的最后一個提交非常容易:

git --no-pager show -s --format=%B $(git rev-parse develop)

發展3

但是我無法在develop分支中檢索到第一次提交 所以我找不到分支從哪里分支的提交。

git merge-base --fork-point develop
git rev-list develop..master
git rev-list develop master
git rev-list master develop
git rev-list ^develop master

結果沒有用。

我找到了一個問題的解決方案, 如何從合並分支分支的地方獲得提交

git oldest-ancestor master develop
git oldest-ancestor develop master

結果也沒有用。

但是, tiggit log --graph仍然能夠看到develop 1是第一個提交的develop分支,這個分支從分叉master 2在提交master

是否可以使用當前的git控制台工具檢索master 2

 git --no-pager show -s --format=%B $(git rev-parse develop) 

更簡單:

git --no-pager show -s --format=%B develop

要么:

git --no-pager log --no-walk --format=%B develop

show -slog --no-walk幾乎是同一件事;這里的關鍵項是刪除不必要的git rev-parse )。

但是我無法在develop分支中檢索到第一次提交

該分支中的第一個提交是master 127ee6b8中的27ee6b8 (哈希ID隨提交時間的不同而不同)。 這也是分支master的第一次提交。

這里的問題是分支沒有“起點”。 從某種意義上說,分支結構(即圖形片段),它是通過從終點開始然后再回到起點而到達的。 這意味着某些提交在許多分支上; 通常, 提交是您在存儲庫中進行的第一次提交,位於每個分支上(盡管在具有多個根的存儲庫中,某些根可能不在某些分支上)。

通常,分支名稱 (有些例外)與該分支上的tip commit同義詞,這就是為什么您不需要顯式的git rev-parse 但是,分支名稱的主要特征是它隨着時間的推移而移動 ,因此它總是命名分支的尖端提交。

另請參見“分支”到底是什么意思?

如果您希望標記某些特定的提交,以便以后記住它,通常的工具是Git標簽。 標簽非常類似於分支名稱,因為它標識一個特定的提交。 但是,與分支名稱不同,永遠不要移動標簽,並且Git不會自動移動標簽。

 git reflog expire --expire=now --all 

專門存在引用日志是為了能夠觀察引用的移動(隨時間變化)。 一個分支名狀的引用日志develop保留,默認情況下為30天或90天,1散列ID的develop 用於識別。 通過使它們過期,您已經失去了回到過去並查看develop@1develop@2等的功能。 如果保留了它們,則可以尋找現有的最古老的develop 可能是它誕生的時候,您通常可以說:

05d0c47 master@{37}: clone: from ...

(表明此刻master已出生)。

不幸的是,刷新日志確實會過期,因此這不是完全可靠的。 標簽是可靠的,但可能會令人討厭,因為git log會用其標簽裝飾提交。 如果有尋找有趣的提交程序 ,你可以使用。 在這種情況下,有一個這樣的過程:您想要的合並曾經是或曾經是合並的提交。

要找到合並基礎,請找到合並本身,然后找到其父級:

m=11c63bc  # this is the merge
p1=$(git rev-parse ${m}^1)
p2=$(git rev-parse ${m}^2)

現在$p1$p2是此合並的兩個父級。 (一個合並可以有兩個以上的父級,但是大多數合並只有兩個。)最后兩個合並這兩個分支的共同點是兩個父級的合並基礎:

git merge-base --all $p1 $p2

由於只有一個合並基礎,因此只打印一個提交哈希。 如果有幾個,它將打印所有的,因為我們使用了--all 省略--all ,我們將(顯然)隨機地選擇一個(實際選擇的一個取決於用於查找合並基礎的算法)。

和以前一樣,不需要很多臨時變量,我們可以這樣做:

mbases=$(git merge-base --all ${m}^1 ${m}^2)

因為git merge-base采用與git rev-parse相同的commit-specifier語法: ^1^2后綴在那里工作相同(並且實際上在大多數Git命令中工作)。


1到期時間是可配置的。 較短的時間(默認為30天)用於從引用的當前值無法訪問的哈希ID。 90天的默認較長時間是從引用的當前值可訪問的哈希ID。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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