在命令行,如果I型包含一個提交
git tag --contains {commit}
以獲得包含給定提交版本的列表的版本的高效檢索,它需要大約11至20秒爲每個提交。由於目標代碼庫存在超過300,000次提交,因此對於所有提交檢索此信息將花費很多。
但是,gitk
顯然設法檢索這些數據做得很好。從我搜索的內容來看,它使用緩存來達到這個目的。
我有兩個問題:
- 我怎麼能解釋該高速緩存格式?
- 有沒有辦法從
git
命令行工具獲取轉儲以生成相同的信息?
在命令行,如果I型包含一個提交
git tag --contains {commit}
以獲得包含給定提交版本的列表的版本的高效檢索,它需要大約11至20秒爲每個提交。由於目標代碼庫存在超過300,000次提交,因此對於所有提交檢索此信息將花費很多。
但是,gitk
顯然設法檢索這些數據做得很好。從我搜索的內容來看,它使用緩存來達到這個目的。
我有兩個問題:
git
命令行工具獲取轉儲以生成相同的信息?你幾乎可以直接從git rev-list
得到這個。
latest.awk
:
BEGIN { thiscommit=""; }
$1 == "commit" {
if (thiscommit != "")
print thiscommit, tags[thiscommit]
thiscommit=$2
line[$2]=NR
latest = 0;
for (i = 3 ; i <= NF ; ++i) if (line[$i] > latest) {
latest = line[$i];
tags[$2] = tags[$i];
}
next;
}
$1 != "commit" { tags[thiscommit] = $0; }
END { if (thiscommit != "") print thiscommit, tags[thiscommit]; }
樣本命令:
git rev-list --date-order --children --format=%d --all | awk -f latest.awk
你也可以使用--topo-order
,你可能不得不在$1!="commit"
邏輯淘汰不需要的裁判。
根據您想要的傳遞性以及清單的明確程度,積累標籤可能需要一個字典。下面是一個得到所有裁判對所有提交明確的上市:
all.awk
:
BEGIN {
thiscommit="";
}
$1 == "commit" {
if (thiscommit != "")
print thiscommit, tags[thiscommit]
thiscommit=$2
line[$2]=NR
split("",seen);
for (i = 3 ; i <= NF ; ++i) {
nnew=split(tags[$i],new);
for (n = 1 ; n <= nnew ; ++n) {
if (!seen[new[n]]) {
tags[$2]= tags[$2]" "new[n]
seen[new[n]] = 1
}
}
}
next;
}
$1 != "commit" {
nnew=split($0,new,", ");
new[1]=substr(new[1],3);
new[nnew]=substr(new[nnew],1,length(new[nnew])-1);
for (n = 1; n <= nnew ; ++n)
tags[thiscommit] = tags[thiscommit]" "new[n]
}
END { if (thiscommit != "") print thiscommit, tags[thiscommit]; }
all.awk
花了幾分鐘做322K Linux內核的回購承諾,約一千第二或類似的東西(大量重複的字符串和冗餘處理),所以如果你真的在完整的交叉產品之後,你可能想用C++重寫它......但我不認爲gitk顯示了這一點,只有最近的鄰居?
因此,爲了澄清我們的非awk用戶:這些腳本與'git tag --contains {commit}'完全相同嗎? –
rev-list的%d顯示所有ref不只是標籤,所以all.awk獲取所有標籤和分支不僅僅是標籤,但除此之外是的,all.awk是一批 - 包含... btw它不會採取兩個學習awk的時間。 – jthill
要實現您自己的cli緩存功能嗎?如果是這樣,我想我可以爲此提出一些想法。 –
是的,那對我很有用。 – leco