如何将字符串格式的Git Commit记录按作者与日期分组生成结构化字典
commit聚合问题修正方案
问题根源
原有代码的核心逻辑错误:
- 提交人对应的值直接存列表,列表内每个元素是仅含单个日期键的字典,无法直接判断日期是否已存在,导致相同日期会被重复追加
- 取已有日期节点的逻辑错误,
coding_days[author][0][commit_date]只会读取列表第一个元素,永远无法匹配到后续追加的日期节点
修正后完整代码
import re merged_result = [ "43f4cc160;Dan Ab;2021-06-17; 1 file changed, 10 insertions(+), 19 deletions(-)", "6cbf2a8b3;Dan Ab;2021-06-15; 1 file changed, 14303 insertions(+)", "c0a77029c;Dan Ab;2021-06-15; 1 file changed, 1 insertion(+), 1 deletion(-)", "f283d7524;Dan Ab;2021-06-15; 1 file changed, 5260 deletions(-)", "03c5314b4;Dan Ab;2021-06-15; 5 files changed, 5265 insertions(+), 12690 deletions(-)", "daf38ecdf;Dan Ab;2020-12-11; 1 file changed, 8 insertions(+)", "b5eabd543;Dan Ab;2020-10-14; 1 file changed, 17 insertions(+)", "6d50a9d09;Dan Ab;2020-10-14; 43 files changed, 15740 insertions(+), 1 deletion(-)", "7d59n9d09;John;2020-10-14; 4 files changed, 1740 insertions(+), 10 deletion(-)" ] # 临时存储结构,author为键,值为日期字典,方便快速查找日期 temp_coding = {} total_lines = 0 total_lines_added = 0 total_lines_removed = 0 total_files_changed = 0 def getstatsummarycounts(line): """ 1 file changed, 5 insertions(+), 1 deletion(-) - returns ['1', '5', '1'] """ numbers = re.findall("\d+", line) if len(numbers) == 1: # neither insertions nor deletions: may probably only happen # for "0 files changed" numbers.append(0) numbers.append(0) elif len(numbers) == 2 and line.find("(+)") != -1: numbers.append(0) # only insertions were printed on line elif len(numbers) == 2 and line.find("(-)") != -1: numbers.insert(1, 0) # only deletions were printed on line return numbers for result in merged_result: commit_hash, author, commit_date, logs = result.split(";") numbers = getstatsummarycounts(logs) if len(numbers) == 3: files_changed, inserted, deleted = map(int, numbers) # 累计统计 total_lines += inserted total_lines -= deleted total_lines_added += inserted total_lines_removed += deleted total_files_changed += files_changed # 初始化提交人节点 if author not in temp_coding: temp_coding[author] = {} # 初始化日期节点 if commit_date not in temp_coding[author]: temp_coding[author][commit_date] = { "commit_count": 0, "commit": [] } # 追加当前commit temp_coding[author][commit_date]["commit"].append({ commit_hash: { "lines_added": inserted, "lines_removed": deleted } }) # 提交数+1 temp_coding[author][commit_date]["commit_count"] += 1 # 转换为要求的输出结构 coding_days = {} for author, date_map in temp_coding.items(): coding_days[author] = [date_map] # 打印验证结果 import json print(json.dumps(coding_days, indent=2, ensure_ascii=False))
输出效果
运行后输出完全符合要求的结构,相同日期的commit会自动聚合到同一个节点下,不会出现重复日期:
{ "Dan Ab": [ { "2021-06-17": { "commit_count": 1, "commit": [ { "43f4cc160": { "lines_added": 10, "lines_removed": 19 } } ] }, "2021-06-15": { "commit_count": 4, "commit": [ { "6cbf2a8b3": { "lines_added": 14303, "lines_removed": 0 } }, { "c0a77029c": { "lines_added": 1, "lines_removed": 1 } }, { "f283d7524": { "lines_added": 0, "lines_removed": 5260 } }, { "03c5314b4": { "lines_added": 5265, "lines_removed": 12690 } } ] }, "2020-12-11": { "commit_count": 1, "commit": [ { "daf38ecdf": { "lines_added": 8, "lines_removed": 0 } } ] }, "2020-10-14": { "commit_count": 2, "commit": [ { "b5eabd543": { "lines_added": 17, "lines_removed": 0 } }, { "6d50a9d09": { "lines_added": 15740, "lines_removed": 1 } } ] } } ], "John": [ { "2020-10-14": { "commit_count": 1, "commit": [ { "7d59n9d09": { "lines_added": 1740, "lines_removed": 10 } } ] } } ] }
内容的提问来源于stack exchange,提问作者Serenity
相关产品推荐
相关产品推荐

