簡體   English   中英

給定提交哈希搜索git log

[英]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, GI等等。 (注意:從KH以及從IH應該像其他線一樣指向左/向后,但是我沒有在每個人的系統上都可以使用的好的箭頭字符,而是用文本來繪制圖形。)

您可以輕松退后的原因是,提交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每個分支上。 提交Jdevelop feature都有

選擇一個您認為最終會帶您回到現在的位置的分支名稱。 然后要求Git做:

git log --topo-order --ancestry-path HEAD..master

例如,讓Git從master開始並向后工作。 HEAD是您現在站在該提交及其連接圖中的提交。它是大的紅色“您在這里”點,隨着您的移動它會自動隨您移動。)

如果可以 master的尖端訪問當前提交, 從此提交的最后一次提交將是您當前提交之后的一個提交。 如果不是,則最后一次提交是從master到達的某個提交,該提交不在包含HEAD的同一分支上。 例如, git log --ancestry-path HEAD..feature將列出從一個feature點開始的提交,並向后工作直到它到達J為止。 Jgit 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

HN前進,您將進入IJMN或KLMN。 無論哪種方式,您都可能忘記訪問跳過的兩個。 所以要小心。

使用git rev-list

通常,您實際上並不是真的希望在這里瀏覽整個git log輸出。 有一些捷徑,但是請記住,如果/當使用它們時,您可能會迷失內部分支和合並結構,例如上面繪制的圓環。 無論如何, git rev-listgit 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的方式 這個答案假設您只關心xyzmaster的提交。

說我們有這棵樹:

*   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

假設您只想獲取20323a1xyz )之前的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

  1. 要查看“最多xyz”的提交,只需使用:

     git log xyz 
  2. 要查看“在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.

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