Python subprocess生成git log无效JSON格式的修复问询
问题描述
尝试将git log格式化为JSON但失败,生成的JSON内容是多个独立对象用逗号分隔且末尾有多余逗号,无法被json.loads()解析。使用的Python函数如下:
def call_git_log(): format: str = '{\n "commit": "%H",%n "abbreviated_commit": "%h",%n "tree": "%T",%n "abbreviated_tree": "%t",%n "parent": "%P",%n "abbreviated_parent": "%p",%n "refs": "%D",%n "encoding": "%e",%n "subject": "%s",%n "sanitized_subject_line": "%f",%n "body": "%b",%n "commit_notes": "%N",%n "verification_flag": "%G?",%n "signer": "%GS",%n "signer_key": "%GK",%n "author": {%n "name": "%aN",%n "email": "%aE",%n "date": "%aD"%n },%n "commiter": {%n "name": "%cN",%n "email": "%cE",%n "date": "%cD"%n }%n},' output = subprocess.Popen(["git", "log", f"--pretty=format:{format}"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = output.communicate() return stdout.decode("utf-8")
output = call_git_log() with open("output/test.json", "w") as file: print(str(output), file=file)
修复方案
要生成合法的JSON文档,需要从结构规范和特殊字符处理两方面修改:
1. 修正JSON结构
- 移除git log格式字符串末尾的逗号:原格式最后一个
}后有多余逗号,会导致最后一个提交对象后多出无效逗号。 - 将所有提交对象包裹为数组:JSON顶层必须是对象或数组,多个独立对象需要用
[]包裹,内部用逗号分隔。
2. 处理干扰性内容
- 添加
--no-color参数:避免git输出的颜色控制字符破坏JSON结构。 - 过滤空行:git log输出的提交之间会有空行,需要分割后过滤无效内容。
3. 修正拼写错误
原代码中commiter是拼写错误,正确应为committer,否则JSON结构的键名不符合常规规范。
修改后的完整代码
import subprocess import json def call_git_log(): # 移除末尾冗余逗号,修正拼写错误,格式化结构更清晰 format_str = '''{ "commit": "%H", "abbreviated_commit": "%h", "tree": "%T", "abbreviated_tree": "%t", "parent": "%P", "abbreviated_parent": "%p", "refs": "%D", "encoding": "%e", "subject": "%s", "sanitized_subject_line": "%f", "body": "%b", "commit_notes": "%N", "verification_flag": "%G?", "signer": "%GS", "signer_key": "%GK", "author": { "name": "%aN", "email": "%aE", "date": "%aD" }, "committer": { "name": "%cN", "email": "%cE", "date": "%cD" } }''' try: # 添加--no-color避免颜色字符干扰,用text=True直接返回字符串 output = subprocess.check_output( ["git", "log", "--no-color", f"--pretty=format:{format_str}"], stderr=subprocess.STDOUT, text=True ) except subprocess.CalledProcessError as e: print(f"Git命令执行失败: {e.output}") return "" # 按空行分割单个提交的JSON,过滤空内容 commits = [c.strip() for c in output.split('\n\n') if c.strip()] # 拼接成合法的JSON数组 return f"[{','.join(commits)}]" # 生成并验证JSON output = call_git_log() if output: with open("output/test.json", "w", encoding="utf-8") as file: file.write(output) # 验证JSON有效性 try: json.loads(output) print("生成的JSON格式合法!") except json.JSONDecodeError as e: print(f"JSON格式错误: {e}")
额外提示
如果提交信息中包含双引号、换行符等特殊字符,会导致JSON解析失败。可以在git格式字符串中添加转义处理,比如将"%s"替换为"%s"的转义版本(git支持%s的转义:%s本身无法直接转义,可通过后续Python代码处理,比如用json.dumps重新序列化字段)。
内容的提问来源于stack exchange,提问作者Lorenz Power
相关产品推荐
相关产品推荐

