我正在撰寫一個 Bash 腳本來輸出有關多個 Git 存盤庫中參考的資訊。到目前為止,它看起來像這樣 -
# paths that have Git repos
paths[0]="./playground"
paths[1]="./sandbox"
# reference objects common to all repos
references[0]="main"
references[1]="v1"
references[2]="v2"
references[3]="v3"
echo "Object type of reference in each repository -"
for reference in "${references[@]}"
do
echo "~~~ $reference ~~~"
for path in "${paths[@]}"
do
OBJECT_TYPE=$(git -C "$path" cat-file -t "$reference")
if [ "$OBJECT_TYPE" = "tag" ]; then
prefix="annotated"
#else
#TODO: implement logic for lightweight tags, branches
fi
echo "$prefix $OBJECT_TYPE $path"
done
echo
done
帶注釋的標簽部分作業正常。但是,$OBJECT_TYPEfor 分支和輕量級標簽都是“提交”,這與預期的一樣,但對于識別哪些參考是分支以及哪些是輕量級標簽沒有幫助。如何區分它們?
uj5u.com熱心網友回復:
如果您只處理標簽和分支的常用短名稱(例如:masterand v1,而不是refs/heads/masteror refs/tags/v1),您可以檢查現有 ref if refs/heads/<name>or是否refs/tags/<name>:
#!/bin/bash
is_branch () {
local path=$1
local name=$2
# use git rev-parse to check if 'refs/heads/$name' exists
# * '-q' silences the errors
# * if it finds the reference, 'rev-parse' always prints the resulting sha on stdout
# (no option to silence that), hence the '> /dev/null'
git -C "$path" rev-parse --verify -q refs/heads/"$name" > /dev/null
return $?
}
is_tag () {
local path=$1
local name=$2
git -C "$path" rev-parse --verify -q refs/tags/"$name" > /dev/null
return $?
}
# or the shorter versions :
is_branch () {
git -C "$1" rev-parse --verify -q refs/heads/"$2" > /dev/null
}
is_tag () {
git -C "$1" rev-parse --verify -q refs/tags/"$2" > /dev/null
}
if is_branch "$path" "$reference"; then
echo "'$reference' is a branch in '$path'"
fi
if is_tag "$path" "$reference"; then
echo "'$reference' is a tag in '$path'"
fi
uj5u.com熱心網友回復:
git for-each-ref refs/heads --points-at "${reference}" --format="%(refname)" | grep refs/heads/${reference}
git for-each-ref refs/tags --points-at "${reference}" --format="%(refname)" | grep refs/tags/${reference}
該命令列出了指向參考提交的所有標記和分支。沒有--format="%(refname)",輸出就像
96e195a92048272cdabd2992a21593bb3774e508 commit refs/heads/master
96e195a92048272cdabd2992a21593bb3774e508 commit refs/tags/nice
有了它,就像
refs/heads/master
refs/tags/nice
測驗 grep 結果是否等于參考。
branch=$(git for-each-ref refs/heads --points-at "${reference}" --format="%(refname)" | grep refs/heads/${reference})
tag=$(git for-each-ref refs/tags--points-at "${reference}" --format="%(refname)" | grep refs/tags/${reference})
if [[ "${branch}" = refs/heads/${reference} ]];then
prefix="branch"
elif [[ "${tag}" = refs/tags/${reference} ]];then
prefix="lightweight"
else
prefix="unknown"
fi
多個參考可能指向同一個提交,所以這里grep用于過濾git for-each-ref.
refs/heads/foo如果存盤庫恰好同時具有和,則 if-else 無法正常作業refs/tags/foo。但應始終避免這種命名。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/491535.html
