如何批量获取多Git仓库同一分支两标签间的所有提交?
批量获取多Git仓库同一分支的指定标签区间提交记录
针对你需要汇总多个Git仓库中同一分支在两个标签间提交记录的需求,这里提供两个实用的批量处理方案,不用再逐个仓库手动执行命令:
方案一:遍历同一父目录下的所有仓库
如果你的所有仓库(R1、R2、R3...)都存放在同一个父目录下(比如~/git-projects/),可以用这个Shell脚本来批量处理:
步骤1:创建脚本文件
新建一个名为batch_git_log.sh的文件,内容如下:
#!/bin/bash # 配置参数,根据你的需求修改 TARGET_BRANCH="B1" START_TAG="v1.0" END_TAG="v2.0" OUTPUT_FILE="all_repos_commits.csv" # 先写入CSV表头 echo "仓库名称,提交哈希,提交者姓名,提交时间,提交信息" > "$OUTPUT_FILE" # 遍历当前目录下的所有子目录(假设每个子目录对应一个Git仓库) for repo_dir in */; do # 去掉目录末尾的斜杠,得到仓库名 repo_name=${repo_dir%/} echo "正在处理仓库: $repo_name" # 进入仓库目录 cd "$repo_dir" || { echo "无法进入仓库目录 $repo_dir,跳过"; continue; } # 检查当前仓库是否存在目标分支和标签 if ! git rev-parse --verify "$TARGET_BRANCH" >/dev/null 2>&1; then echo "仓库 $repo_name 不存在分支 $TARGET_BRANCH,跳过" cd .. continue fi if ! git rev-parse --verify "$START_TAG" >/dev/null 2>&1 || ! git rev-parse --verify "$END_TAG" >/dev/null 2>&1; then echo "仓库 $repo_name 缺少指定标签,跳过" cd .. continue fi # 执行git log命令,将仓库名作为第一列加入输出,追加到CSV文件 git log "$TARGET_BRANCH" "$START_TAG..$END_TAG" --pretty=format:"$repo_name, %H, %cn, %ci, %s" >> "../$OUTPUT_FILE" # 返回父目录 cd .. done echo "所有仓库处理完成,结果已保存到 $OUTPUT_FILE"
步骤2:配置并运行脚本
- 修改脚本中的
TARGET_BRANCH、START_TAG、END_TAG为你实际需要的分支名和标签 - 将脚本放到仓库的父目录下
- 给脚本添加执行权限:
chmod +x batch_git_log.sh - 运行脚本:
./batch_git_log.sh
运行完成后,你会得到一个包含所有仓库提交记录的CSV文件,每一行都标注了对应的仓库名称。
方案二:基于仓库列表文件的脚本
如果你的仓库分散在不同的路径下,可以先创建一个仓库路径列表文件,再用脚本读取并处理:
步骤1:创建仓库列表文件
新建repo_list.txt,每行写一个仓库的绝对路径,比如:
/home/user/git/R1 /home/user/git/R2 /opt/projects/R3
步骤2:创建脚本文件
新建batch_git_log_from_list.sh,内容如下:
#!/bin/bash # 配置参数 TARGET_BRANCH="B1" START_TAG="v1.0" END_TAG="v2.0" REPO_LIST="repo_list.txt" OUTPUT_FILE="all_repos_commits.csv" # 写入CSV表头 echo "仓库名称,提交哈希,提交者姓名,提交时间,提交信息" > "$OUTPUT_FILE" # 读取仓库列表文件 while IFS= read -r repo_path; do # 跳过空行 [ -z "$repo_path" ] && continue # 从路径中提取仓库名(取最后一个目录名) repo_name=$(basename "$repo_path") echo "正在处理仓库: $repo_name ($repo_path)" # 进入仓库目录 cd "$repo_path" || { echo "无法进入仓库路径 $repo_path,跳过"; continue; } # 检查分支和标签是否存在 if ! git rev-parse --verify "$TARGET_BRANCH" >/dev/null 2>&1; then echo "仓库 $repo_name 不存在分支 $TARGET_BRANCH,跳过" cd - >/dev/null 2>&1 continue fi if ! git rev-parse --verify "$START_TAG" >/dev/null 2>&1 || ! git rev-parse --verify "$END_TAG" >/dev/null 2>&1; then echo "仓库 $repo_name 缺少指定标签,跳过" cd - >/dev/null 2>&1 continue fi # 执行git log并追加结果到CSV git log "$TARGET_BRANCH" "$START_TAG..$END_TAG" --pretty=format:"$repo_name, %H, %cn, %ci, %s" >> "$OUTPUT_FILE" # 返回之前的目录 cd - >/dev/null 2>&1 done < "$REPO_LIST" echo "所有仓库处理完成,结果已保存到 $OUTPUT_FILE"
步骤3:运行脚本
同样修改参数后,给脚本加执行权限并运行即可。
注意事项
- 确保所有仓库都已经拉取了最新代码:可以在脚本中加入
git pull命令(在进入仓库后添加git pull origin "$TARGET_BRANCH" --quiet),避免遗漏远程提交 - 标签范围
START_TAG..END_TAG表示的是在END_TAG中但不在START_TAG中的提交,如果需要包含START_TAG本身,可以改成START_TAG^..END_TAG - 如果提交信息中包含逗号,CSV可能会出现格式问题,可以考虑用其他分隔符(比如
|),修改脚本中的分隔符即可
内容的提问来源于stack exchange,提问作者Saket Kumar
相关产品推荐
相关产品推荐

