如何使用Git命令生成变更文件列表并关联对应提交消息
问题
我的提交历史如下:
commit id "1234ab" with commit message "commit-msg-1" include |_________A_file |_________B_file commit id "7890cd" with commit message "commit-msg-2" |_________C_file |_________D_file
我用以下命令获取1234ab与7890cd之间的变更文件列表:
git diff --name-status 1234ab 7890cd
输出结果为:
M A_file M B_file M C_file M D_file
需要生成如下格式的内容,让每个文件对应其所属提交的消息:
M A_file commit-msg-1 M B_file commit-msg-1 M C_file commit-msg-2 M D_file commit-msg-2
解决方案
方法1:一行命令直接生成
用git log结合awk脚本可以直接输出目标格式:
git log --name-status --format="%s" 1234ab..7890cd | awk ' /^[A-Z]/ { print $0, msg } !/^[A-Z]/ { msg = $0 } '
原理很直白:
git log会先输出提交消息,再列出该提交下所有变更文件的状态和文件名awk会先把提交消息存起来,遇到以大写字母开头的文件行时,就把消息追加到该行后面输出
方法2:先建映射再合并(更直观)
如果觉得一行命令不好理解,可以分两步来:
- 先生成文件与提交消息的对应关系:
git log --name-only --format="=== %s ===" 1234ab..7890cd
输出会是类似这样的结构:
=== commit-msg-1 === A_file B_file === commit-msg-2 === C_file D_file
- 用bash脚本读取这个映射,再结合
git diff的结果输出:
#!/bin/bash # 构建文件到提交消息的映射字典 declare -A file_msg_map current_msg="" while read line; do if [[ $line == ===*=== ]]; then # 提取提交消息 current_msg=${line:4:-4} else # 给文件绑定对应的提交消息 file_msg_map["$line"]=$current_msg fi done < <(git log --name-only --format="=== %s ===" 1234ab..7890cd) # 遍历git diff结果,拼接输出 git diff --name-status 1234ab 7890cd | while read status file; do echo "$status $file ${file_msg_map[$file]}" done
把这段脚本保存为map-file-msg.sh,赋予执行权限后运行即可得到目标格式。
内容的提问来源于stack exchange,提问作者peter168
相关产品推荐
相关产品推荐

