[英]Search git log given a commit hash
我有一個幾個月前的git哈希值(讓我們說xyz
),並且希望查看到今天為止在哈希值之前和之后在master分支上的所有提交。
我知道git checkout xyz~1
在該哈希之前返回1次提交,而git log
顯示了所有先前的提交,但是我不知道如何前進?
在這種情況下,可以使用git的--grep
功能嗎?
考慮以下圖片:
I <-J
/
... <-G <-H
\
K <-L
上面的代碼代表Git的提交H
代表一些丑陋的哈希ID, G
和I
等等。 (注意:從K
到H
以及從I
到H
應該像其他線一樣指向左/向后,但是我沒有在每個人的系統上都可以使用的好的箭頭字符,而是用文本來繪制圖形。)
您可以輕松退后的原因是,提交H
包含提交G
丑陋哈希ID大。 我們說H
指向 G
因此,如果您站在H
並運行git log
,則Git會向您顯示H
,然后是G
,然后是G
之前的任何內容(可能是F
),依此類推。
您想換一種方式。 但是...那是哪種方式? 有兩條前進的道路,Git都不容易為您找到。 一個到I
,然后到J
另一個進入K
,然后進入L
無論如何,您都可以選擇一個較晚的起點(終點)?無論如何,要像L
那樣稍后再提交,並告訴Git向后走,直到到達H
為止。 Git 可以輕松做到這一點,因為每次提交后都嵌入了指向后的箭頭。
當您像這樣向后進行Git工作時,Git最終將執行某些父級為H
提交。 這就是您選擇的端點方向上的“向前”提交。 當然,這不是另一個前向提交。
這里的主要問題是可能有很多端點,其中只有少數端點返回H
:
...--G--H--o <-- master
\
J--o--o <-- develop
\
o--o <-- feature
我們稱這些端點為分支 ,或更確切地說, 稱為分支名稱 。 名稱指向提示提交。 左邊的每個提交(無論它在哪條線上)都在該分支上,這意味着在此圖中,提交G
在每個分支上。 提交J
在develop
和 feature
上都有 。
選擇一個您認為最終會帶您回到現在的位置的分支名稱。 然后要求Git做:
git log --topo-order --ancestry-path HEAD..master
例如,讓Git從master
開始並向后工作。 ( HEAD
是您現在站在該提交及其連接圖中的提交。它是大的紅色“您在這里”點,隨着您的移動它會自動隨您移動。)
如果可以從 master
的尖端訪問到當前提交, 則 從此提交的最后一次提交將是您當前提交之后的一個提交。 如果不是,則最后一次提交是從master
到達的某個提交,該提交不在包含HEAD
的同一分支上。 例如, git log --ancestry-path HEAD..feature
將列出從一個feature
點開始的提交,並向后工作直到它到達J
為止。 從J
, git log
將退回到G
那不是HEAD
/ H
但是可以從 H
到達 ,所以這是git log
停止的地方。 那不是在H
之后的提交。
這意味着如果您不確定不確定哪個分支包含H
,那么您將不知道從哪里開始。 因此使用:
git branch --contains HEAD
獲取分支名稱列表,當Git從它們開始並向后工作時,這些分支確實包含commit H
/ HEAD
。 然后,您可以使用--ancestry-path
技巧向該方向“前進”(您實際上仍在向后前進, 只是在到達H
之前停下來)。
如果您在路上碰到叉子,您會接過的 。 您將按照提供的終點的方向進行操作 。 請注意,在某些情況下,這可能會跳過一些提交:
I--J
/ \
...--o--H M--N <-- branch
\ /
K--L
從H
向N
前進,您將進入IJMN或KLMN。 無論哪種方式,您都可能忘記訪問跳過的兩個。 所以要小心。
git rev-list
通常,您實際上並不是真的希望在這里瀏覽整個git log
輸出。 有一些捷徑,但是請記住,如果/當使用它們時,您可能會迷失內部分支和合並結構,例如上面繪制的圓環。 無論如何, git rev-list
和git log
做相同的事情,除了它只打印哈希ID。 使用--topo-order --reverse | head -1
--topo-order --reverse | head -1
,您可以讓它向后打印列表,然后刪除除第一個列表之外的所有列表; 或不使用--reverse
和| tail -1
| tail -1
的效果相同。 您也可以省略名稱HEAD
。 所以:
git checkout $(git rev-list --ancestry-path --topo-order ..branch | tail -1)
會將分離的HEAD向branch
方向移動一步(如果有的話)。
很難給出一個答案,因為這取決於您的樹的外觀, xyz的位置以及提交或合並到master的方式 。 這個答案假設您只關心xyz到master的提交。
說我們有這棵樹:
* f10abeb (HEAD -> master) Merge branch 'develop' into 'master'
|\
| * 3a7ed63 Merge branch 'feature/A' into 'develop'
| |\
| * | f3972b9 Update in develop 1
| | * f695720 Update in feature/A
| * | 20323a1 Update in develop 2
| * | 3e81e7a Update in develop 3
| * | 1e76a6c Update in develop 4
| * | d3bf88f Update in develop 5
| | * 205fc0e Update in feature/A
假設您只想獲取20323a1
( xyz
)之前的2次提交和您的master
本地副本之間的日志(我假設您的意思是“ 直到今天 ”)。 您不必擔心feature/A
的“內部”提交,但是您確實想查看它何時被合並。 (我在這里假設很多)。
首先,您需要在20323a1
之前檢出2個提交:
git checkout 20323a1~2
那將帶您到1e76a6c
。
然后,您可以執行以下操作:
git log --ancestry-path @^..master
這將為您提供以下日志:
(我刪除了一些信息,例如日期和時間等)
commit f10abebbfa9bce8074e9a4854af4fc1a000b2f6a
Merge: 6011c88 3a7ed63
Merge branch 'develop' into 'master'
commit 3a7ed6334d492ebb7960c97c1c59c88d40c28108
Merge: f3972b9 f695720
Merge branch 'feature/A' into 'develop'
commit f3972b9ca16ff27914120de12105b8203a2682fa
Update in develop 1
commit 20323a1fc4c636b7e12650659ca049c2a1c497c4
Update in develop 2
commit 3e81e7a1624e6914dc152ca315c727e15ebf3300
Update in develop 3
commit 1e76a6cb326ffce64ff22480a71b49de4dbdff73
Update in develop 4
--ancestry-path
選項將“ 僅顯示直接存在於commit1和commit2之間的祖先鏈上的提交 ”(在此示例中,當前提交和主提交)。
r1..r2
是點分范圍符號,表示提交“ 從r2可以到達的提交,但不包括從r1可以到達的提交 ”。 然后,將r1
指定為當前提交( @
),將r2
指定為master
。
要查看“最多xyz”的提交,只需使用:
git log xyz
要查看“在xyz
之后發生的master中的提交”,可以使用:
git log xyz..master
技術上,第二個命令將exlcude xyz
從列表中,根據您的具體需求,你可以使用xyz~1
而不是xyz
:
git log xyz~1..master
git log
還具有大量的選項來格式化其輸出。
用於查看大量提交的一組有用的選項是:
git log --oneline --graph xyz
git log --oneline --graph xyz..master
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.