[英]How to find all the “active” git commits in a tree?
我想獲取目錄樹的“活動” git 提交的快照,這意味着 git 提交確實是構建的一部分,而不是已被新提交完全取代的提交。
我可以通過在每個文件上運行git blame
並以這種方式提取提交來做到這一點,但是在大型 repo 上它太慢了,不實用。
git blame
所做的幾乎是找到您正在尋找的信息的唯一方法。 但是,您可以稍微簡化操作,這對於您的目的可能已經足夠了,也許也足夠快。
請記住,每個提交都有每個文件的完整快照。 分支名稱標識某個提交鏈中的最后一個提交。 所以當你有:
... <-F <-G <-H <-- branch
名稱branch
包含提交H
的原始 hash ID。 在提交H
中,有很多文件,每個文件都有很多行。 這些文件是它們在提交H
中的形式,僅此而已——除了提交H
包含之前提交G
的 hash ID。
您可以使用 hash ID this 來定位提交G
並提取其所有文件,當G
中的文件與H
中的文件完全匹配時,這意味着——至少在git blame
條款中——文件中G
中的所有行都是歸因於G
,如果不是一些較早的提交。 所以G
和H
不同的文件應該歸於H
。 git blame
命令逐行工作,如果它們不同,則將各個行歸因於提交H
,但也許出於您的目的,將整個文件歸因於H
就足夠了。
如果您決定該文件可能應該歸因於提交G
,現在是時候從提交G
中提取提交F
的 hash ID,並使用它來讀取提交F
中的所有文件。 如果F
中的任何給定文件與G
中的副本匹配,則屬性移回F
; 否則它保持在G
。
您必須重復此過程,直到您完全用完提交:
A <-B <-C ... <-H
由於提交A
沒有父級,因此A
中的任何文件在最后一次提交期間一直未更改,都將歸因於提交A
。 但是,一旦您將H
中存在的所有文件完全歸因於鏈中稍后的某個提交,您就可以停止向后遍歷。 將此與git blame
進行比較,只要至少有一行歸因於某個較早的提交,它就必須繼續向后看:您可能會在git blame
必須之前停止很久。
此外,由於 Git 的內部數據結構,可以非常快速地判斷某個較早提交中的文件是否與稍后提交中的同名文件完全匹配:每次提交中的每個文件都由 hash ID 表示。 如果 hash ID 相同,則文件的內容在兩次提交中逐位相同。 如果不是,他們不是。
沒有方便的 in-Git 命令可以准確地執行您想要的操作, 1如果您確實打算像這樣遍歷歷史記錄,您必須決定如何處理合並。 請記住,合並提交有一個快照,但與非合並不同的是,它有兩個或多個父級:
...--o--K
\
M--o--o--...--o <-- last
/
...--o--L
如果M
中的文件與K
和/或L
中的一個或多個文件匹配,您應該遵循哪個提交? git log
命令有它自己的方法來執行此git log <start-point> -- <path>
將通過跟隨一個父級來簡化歷史,從一組這樣的父級中隨機選擇,該父級具有相同的 Z0800FC577294C434E0B28 AD238給定的文件。
請注意,您可以使用git rev-list
(可能與--parents
一起使用)來生成您可以選擇檢查的 hash ID 集。 rev-list 命令是大多數其他 Git 命令的主力,包括git blame
自己,因為這樣的歷史記錄。 (注意: git log
命令是從與git rev-list
相同的源構建的,具有一些小的命令行選項差異和不同的默認輸出。)
1雖然git log <start-point> -- <path>
在這里很有用,但是對於每個路徑運行一次會太慢,並且在不給出單獨路徑的情況下運行它是無效的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.