Skip to content

Instantly share code, notes, and snippets.

@rc1021
Last active November 21, 2025 03:07
Show Gist options
  • Select an option

  • Save rc1021/3b2aafe50f76e5f7309ab0b162668860 to your computer and use it in GitHub Desktop.

Select an option

Save rc1021/3b2aafe50f76e5f7309ab0b162668860 to your computer and use it in GitHub Desktop.
這是用來查看哪些分支的 commit 還沒合併到 (target) 分支的功能
#!/bin/bash
# 默認格式
FORMAT="original"
TARGETS=("uat" "sit")
WIDTH_TARGET=10
WIDTH_BRANCH=25
WIDTH_COMMIT=10
WIDTH_DATE=10
WIDTH_AUTHOR=15
WIDTH_MESSAGE=80
# 解析參數
for arg in "$@"; do
case $arg in
--format=*) FORMAT="${arg#*=}" ;;
--target=*) TARGETS=("${arg#*=}") ;; # 只處理指定 target
*) ;;
esac
done
branches() {
git branch -r --no-merged origin/$1 --format='%(refname:short)' | grep -v '^origin/HEAD$'
}
to_array() {
local str="$1"
local width="$2"
ARR=()
while IFS= read -r line; do
ARR+=("$line")
done < <(echo "$str" | fold -w "$width")
}
# table 格式表頭
if [[ "$FORMAT" == "table" ]]; then
printf "%-${WIDTH_TARGET}s | %-${WIDTH_BRANCH}s | %-${WIDTH_COMMIT}s | %-${WIDTH_DATE}s | %-${WIDTH_AUTHOR}s | %s\n" \
"Target" "Branch" "Commit" "Date" "Author" "Message"
fi
for target in "${TARGETS[@]}"; do
[[ "$FORMAT" == "table" ]] && printf -- "-----------|---------------------------|------------|------------|-----------------|----------------------------\n"
case $FORMAT in
markdown) echo "### 尚未合併到 $target";;
json) echo "\"$target\": {";;
original) echo "尚未合併到 $target";;
list|table) ;;
*) echo "Unknown format: $FORMAT"; exit 1;;
esac
first_branch=true
for branch in $(branches $target); do
target_name=$target
branch_name=${branch#origin/}
[[ "$branch_name" =~ ^(HEAD|master|main|develop|release|uat|sit|origin)$ ]] && continue
case $FORMAT in
original)
echo " $branch"
git log origin/$target..$branch \
--pretty=format:" %h %s @%an [%ad]" --date=short | sed 's/^/ /'
echo
;;
markdown|table|list|json)
while IFS='|' read -r hash date author msg || [[ -n "$hash" ]]; do
case $FORMAT in
markdown)
[[ -n "$branch_name" ]] && echo "- **$branch_name**"
echo " - \`$hash\` $msg -- **@$author** ($date)";;
table)
# 將欄位硬性換行
to_array "$target_name" $WIDTH_TARGET; arr_target=("${ARR[@]}")
to_array "$branch_name" $WIDTH_BRANCH; arr_branch=("${ARR[@]}")
to_array "$hash" $WIDTH_COMMIT; arr_commit=("${ARR[@]}")
to_array "$date" $WIDTH_DATE; arr_date=("${ARR[@]}")
to_array "$author" $WIDTH_AUTHOR; arr_author=("${ARR[@]}")
to_array "$msg" $WIDTH_MESSAGE; arr_msg=("${ARR[@]}")
# 計算最大行數
max_lines=0
for arr in arr_target arr_branch arr_commit arr_date arr_author arr_msg; do
eval len=\${#$arr[@]}
(( len > max_lines )) && max_lines=$len
done
for ((i=0;i<max_lines;i++)); do
printf "%-${WIDTH_TARGET}s | %-${WIDTH_BRANCH}s | %-${WIDTH_COMMIT}s | %-${WIDTH_DATE}s | %-${WIDTH_AUTHOR}s | %s\n" \
"${arr_target[i]:-}" \
"${arr_branch[i]:-}" \
"${arr_commit[i]:-}" \
"${arr_date[i]:-}" \
"${arr_author[i]:-}" \
"${arr_msg[i]:-}"
done
;;
list)
echo "$target / $branch_name / $hash / $author / $date / $msg";;
json)
if [ "$first_branch" = true ]; then
echo " \"$branch_name\": ["
first_branch=false
else
echo " ,\"$branch_name\": ["
fi
echo " {\"hash\":\"$hash\",\"message\":\"$msg\",\"author\":\"$author\",\"date\":\"$date\"}";;
esac
target_name=""
branch_name=""
done < <(git log origin/$target..$branch --pretty=format:"%h|%ad|%an|%s" --date=short)
esac
done
[[ "$FORMAT" == "json" ]] && echo "}"
done
@rc1021
Copy link
Author

rc1021 commented Nov 20, 2025

用法
./unmerged.sh --format=table --target=release,develop

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment