1. 项目概述:为什么我们需要从Git Commit中“榨取”日报?
如果你是一名开发者,或者是一名需要管理技术团队的项目经理,那么下面这个场景你一定不陌生:每到下班前或者周报日,你都得停下手中的代码,努力回忆“我今天到底干了啥?”。大脑一片空白,只能勉强拼凑出“修复了几个bug”、“优化了某个功能”这样模糊的句子。日报、周报成了负担,不仅浪费时间,而且往往无法真实、细致地反映工作成果。
这就是“QClaw应用 – 从Git Commit Message提取日报”这个项目要解决的核心痛点。它的思路非常直接:你每天的工作痕迹,其实已经以代码提交(Git Commit)的形式,忠实地记录在了版本控制系统里。每一次提交的注释信息(Commit Message),就是你当时工作意图和成果最原始的“快照”。这个工具的目的,就是自动化地收集、解析、归类这些提交记录,并将其转换为你个人或团队可直接使用的、结构清晰的工作日报或周报。
我最初想到做这个,是因为自己深受“日报焦虑”之苦,同时也观察到团队里的小伙伴们都有类似的困扰。手动整理既低效又容易遗漏。而市面上的一些时间追踪或项目管理工具,要么需要手动打点记录(增加了额外负担),要么集成复杂,对于轻量级团队或个人开发者来说过于笨重。Git作为开发者的“第二大脑”,其提交历史本身就是一座金矿,我们只是需要一个好用的“矿机”来开采它。
这个工具适合所有使用Git进行版本控制的开发者、技术负责人以及项目经理。无论你是独立开发者想梳理自己的工作流,还是团队管理者需要快速了解项目进展和成员贡献,它都能提供一个数据驱动、客观透明的视角。接下来,我会详细拆解这个工具从设计思路到具体实现的每一个环节,分享我在开发过程中趟过的坑和总结的经验。
2. 核心设计思路与方案选型
一个工具好不好用,往往在设计之初就决定了。对于从Git Commit提取日报这个需求,我们首先要明确几个关键问题:数据从哪里来?怎么处理?最终呈现为什么样子?基于这些问题的思考,我形成了以下核心设计思路。
2.1 数据源的确定与Git命令剖析
数据源毫无疑问是本地或远程的Git仓库。我们需要获取指定时间范围内(例如今天、本周)的所有提交记录。这里就涉及到Git命令的选择。
最直接的想法是使用git log。但git log的输出信息非常丰富,我们需要进行过滤和格式化。核心命令结构如下:
git log --since="2024-01-01" --until="2024-01-02" --author="yourname" --pretty=format:"%H|%an|%ad|%s" --date=short让我解释一下这几个关键参数:
--since和--until: 定义时间范围,这是提取日报/周报的基石。--author: 过滤特定作者的提交,这对于生成个人日报或统计个人贡献至关重要。如果不指定,则获取仓库内所有提交。--pretty=format:: 这是输出的核心。它允许我们自定义输出的格式,只提取我们关心的字段。上面例子中:%H: 提交的完整哈希值,作为唯一标识。%an: 作者名字。%ad: 作者日期,配合--date=short输出为YYYY-MM-DD格式。%s: 提交主题(即第一行注释)。
- 除了这些,常用的还有
%b(提交正文)、%h(短哈希)等。
为什么选择这种格式?因为管道符|分隔的格式易于后续程序解析。我们可以将其看作一种简单的CSV或TSV格式,用特定分隔符切割后就能得到结构化的数据。相比默认的多行文本输出,这种格式对程序友好得多。
注意:这里有一个常见的坑。
git log默认按照时间倒序排列(最新的在最前面)。对于日报,我们可能更希望按照时间正序(从早到晚)来展示一天的工作流。这时可以加上--reverse参数。但需要注意的是,如果同时使用了--since和--until,--reverse可能会影响性能,因为Git需要先找出所有提交再反转。对于单日数据量不大的情况,可以忽略。
2.2 提交信息的解析与分类策略
拿到原始的提交记录只是第一步。提交信息(Commit Message)是自由文本,质量参差不齐。有的团队遵循类似Angular的规范(feat:,fix:,docs:等),有的则比较随意。我们的工具需要有一定的智能来处理这些情况。
我的策略是“规则优先,正则兜底,关键词匹配”。
规则优先:如果团队使用了规范的提交前缀(如
feat:,fix:,refactor:,chore:等),那么解析就非常简单。我们可以直接根据冒号前的单词对提交进行分类。例如,所有以feat:开头的提交归为“新功能”,fix:开头的归为“问题修复”。正则兜底:对于没有规范前缀的提交,我们可以编写一组正则表达式来捕获常见模式。例如:
修复了.*[Bb]ug-> 归类到“问题修复”增加了.*功能或实现了.*-> 归类到“功能开发”优化了.*性能或重构了.*-> 归类到“代码优化”更新了.*文档-> 归类到“文档维护”
关键词匹配:作为最后的手段,可以维护一个关键词词典。将提交信息与词典中的关键词进行匹配,根据匹配到的关键词类型进行分类。例如,词典中“修复”、“解决”、“bug”、“error”等词映射到“问题修复”类。
在实际开发中,我建议将分类规则设计成可配置的。你可以提供一个配置文件(如YAML或JSON),让用户自定义前缀、正则表达式和关键词的映射关系。这样工具就能适配不同团队的习惯,而不是一个僵硬的、一刀切的方案。
# 示例规则配置 (categories.yaml) categories: - name: "功能开发" prefixes: ["feat:", "feature:"] regexes: ["^增加了.*功能$", "^实现了.*"] keywords: ["新功能", "新增"] - name: "问题修复" prefixes: ["fix:", "bugfix:"] regexes: ["^修复了.*", "^解决了.*[Bb]ug"] keywords: ["修复", "bug", "错误", "issue"] - name: "代码优化" prefixes: ["refactor:", "perf:"] regexes: ["^优化了.*", "^重构了.*"] keywords: ["优化", "重构", "性能"] - name: "其他事务" prefixes: ["chore:", "docs:"] default: true # 未匹配到的默认分类2.3 输出格式的设计:兼顾可读性与自动化
处理后的数据需要输出。输出格式决定了这个工具的最终用途。我主要考虑了三种格式:
Markdown格式:这是最通用、最友好的格式。可以直接粘贴到支持Markdown的日报系统、知识库(如Wiki)、甚至聊天工具(如Slack、飞书)中。结构清晰,支持层级标题、列表和代码块,非常适合人工阅读。
## 2024-01-15 工作日报 (张三) ### 🛠 功能开发 * [项目A] feat: 实现了用户登录模块的短信验证码功能 (abc123f) * [项目B] feature: 新增后台数据导出为CSV格式 (def456g) ### 🐛 问题修复 * [项目A] fix: 修复了首页在iOS Safari浏览器上的布局错位问题 (ghi789h) ### 📝 其他事务 * [项目A] chore: 更新了项目依赖包版本 (jkl012i) * [项目A] docs: 补充了API接口文档关于错误码的说明 (mno345j)纯文本格式:极简风格,适合快速预览或集成到某些命令行工具链中。虽然可读性稍差,但胜在轻量。
结构化数据格式(JSON):这是为了自动化和二次开发准备的。JSON格式的输出可以被其他系统(如项目管理平台、自动化报表系统)轻松解析和消费。你可以基于JSON数据生成更复杂的图表、进行团队效率分析等。
{ "date": "2024-01-15", "author": "张三", "commits": [ { "hash": "abc123f", "project": "项目A", "type": "功能开发", "summary": "实现了用户登录模块的短信验证码功能", "full_message": "feat: 实现了用户登录模块的短信验证码功能\n\n- 集成第三方短信服务SDK\n- 添加发送验证码和验证接口\n- 增加频率限制防止刷短信" } // ... 更多提交 ], "summary": { "功能开发": 2, "问题修复": 1, "其他事务": 2 } }
在QClaw的设计中,我决定同时支持这三种格式,并通过命令行参数让用户选择。例如-f markdown或--format json。默认输出Markdown,因为这是最常用的场景。
3. 技术实现与核心模块拆解
有了清晰的设计思路,我们就可以开始动手构建了。我将整个工具拆解为几个核心模块,这样结构清晰,也便于维护和扩展。我选择使用Python来实现,因为它有丰富的库支持和强大的文本处理能力,非常适合这类工具。
3.1 环境准备与依赖管理
首先,你需要一个Python环境(建议3.7以上)。项目依赖并不多,主要是用来解析命令行参数、处理日期和操作Git。
我使用pip和requirements.txt来管理依赖。核心依赖库如下:
# requirements.txt argparse # Python标准库,用于解析命令行参数 python-dateutil # 强大的日期时间解析库,处理`--since yesterday`这类自然语言日期 gitpython # 一个操作Git仓库的Python库,比直接调用命令行更优雅、更安全 pyyaml # 用于读取YAML格式的配置文件(分类规则)为什么选择gitpython而不是直接调用subprocess执行git log?虽然subprocess更直接,但gitpython提供了面向对象的API,能更好地处理Git仓库的复杂情况,比如非标准路径、仓库状态判断等。它封装了底层命令,代码更简洁,错误处理也更方便。例如,使用gitpython获取提交历史:
import git repo = git.Repo('/path/to/your/repo') # 打开仓库 commits = list(repo.iter_commits(since='2024-01-01', until='2024-01-02', author='yourname')) for commit in commits: print(commit.hexsha, commit.author.name, commit.authored_datetime, commit.message.split('\n')[0])安装依赖只需一行命令:pip install -r requirements.txt。
3.2 核心模块一:Git提交获取器
这个模块负责与Git仓库交互,获取原始提交数据。它的核心函数需要接收以下参数:仓库路径、起始时间、结束时间、作者。然后返回一个结构化的提交列表。
关键实现细节:
- 仓库路径处理:支持传入绝对路径或相对路径。如果没有传入,可以默认使用当前目录(
os.getcwd())。需要检查该路径是否是一个有效的Git仓库(gitpython的Repo类初始化时会进行验证)。 - 时间参数解析:用户可能输入“today”、“yesterday”、“last week”、“2024-01-01”等多种格式。这里
python-dateutil库的parser.parse函数就派上了大用场,它能智能解析大部分常见日期字符串。 - 作者过滤:除了直接匹配作者名,有时还需要处理邮箱。Git提交中的作者信息通常是
Name <email@example.com>格式。我们的过滤逻辑应该同时考虑这两种情况。一种简单的做法是,如果用户输入的是纯名字,就匹配名字部分;如果输入包含@,则尝试匹配邮箱。 - 分页与性能:对于历史非常悠久的大仓库,获取所有提交可能很慢。
gitpython的iter_commits本身是一个生成器,惰性加载,通常性能足够。但如果需要处理超大量数据,可以考虑引入max_count参数进行限制。
实操心得:在处理时间范围时,要特别注意时区问题。Git提交时间戳是带时区的。
gitpython返回的authored_datetime是感知型(aware)的datetime对象。为了统一,我通常在获取后立即将其转换为UTC时间或本地时间,并格式化为YYYY-MM-DD字符串再进行比对和输出,避免因时区不一致导致“今天”的提交被漏掉或算到“明天”。
3.3 核心模块二:提交信息解析与分类器
这是工具的“大脑”。它接收原始的提交对象列表,应用我们在设计阶段制定的分类策略,为每个提交打上类型标签。
实现步骤:
- 加载分类规则:从配置文件(如
categories.yaml)中读取分类规则,存储在内存中。如果没有配置文件,则使用内置的默认规则。 - 遍历提交:对每个提交,首先提取其提交信息的第一行(主题行),这是分类的主要依据。
- 应用分类规则: a.前缀匹配:检查主题行是否以某个分类定义的
prefixes列表中的任一前缀开头。这是最快、最准确的匹配方式。 b.正则匹配:如果前缀未匹配,则遍历该分类的regexes列表,用正则表达式去匹配主题行。 c.关键词匹配:如果正则也未匹配,则将主题行分词(简单的中文分词可以用jieba库,英文按空格分割),检查是否包含该分类keywords列表中的关键词。 - 确定分类:一个提交可能匹配多个分类的规则(比如既有关键词“优化”又有前缀“fix:”)。这里需要定义优先级。我的规则是:前缀匹配 > 正则匹配 > 关键词匹配,并且一旦被高优先级规则匹配,就不再继续用低优先级规则判断。如果最终没有匹配任何规则,则将其归入“其他事务”或配置中标记为
default: true的分类。 - 提取额外信息:除了分类,我们还可以尝试从提交信息中提取更多结构化信息,例如关联的项目/模块名。一个常见的做法是,如果提交信息开头有类似
[项目A]的方括号标签,则将其提取出来作为“项目”字段。这可以通过一个简单的正则表达式^\[(.*?)\]来实现。
代码结构示例:
class CommitClassifier: def __init__(self, rules_config): self.categories = self._load_rules(rules_config) def classify(self, commit_subject): primary_category = None project_tag = None # 提取项目标签 import re project_match = re.match(r'^\[(.*?)\]', commit_subject) if project_match: project_tag = project_match.group(1) commit_subject = commit_subject[project_match.end():].strip() # 按优先级分类 for category in self.categories: # 1. 检查前缀 for prefix in category.get('prefixes', []): if commit_subject.startswith(prefix): return category['name'], project_tag, commit_subject[len(prefix):].strip() # 2. 检查正则 for regex in category.get('regexes', []): if re.search(regex, commit_subject): return category['name'], project_tag, commit_subject # 3. 检查关键词 for keyword in category.get('keywords', []): if keyword in commit_subject: return category['name'], project_tag, commit_subject # 4. 默认分类 for category in self.categories: if category.get('default'): return category['name'], project_tag, commit_subject return '未分类', project_tag, commit_subject3.4 核心模块三:报告生成器与输出模块
分类好的数据需要被渲染成最终的报告。这个模块根据用户选择的格式(Markdown、Text、JSON),调用不同的渲染函数。
Markdown渲染器:这是最复杂的部分,因为要生成美观易读的文档。
- 按日期和作者分组:通常日报是按人按天组织的。我们需要先将提交数据按
author和date进行分组。 - 按分类排序:在每个分组内,将提交按分类(如功能开发、问题修复等)进行归类排序,使报告更有条理。
- 生成Markdown元素:
- 使用
##作为日报标题(日期 + 作者)。 - 使用
###作为分类标题。 - 使用无序列表
*列出每个提交。每个提交项应包含:项目标签(如果有)、清理后的提交信息、提交短哈希(方便快速定位)。 - 可以在分类标题前加个Emoji图标(如 🛠、🐛、📝),增加视觉友好度(注意:最终输出应避免Emoji,这里仅为说明思路)。
- 使用
- 统计信息:可以在日报末尾添加一个简单的统计,如“今日共提交X次,其中功能开发Y次,问题修复Z次”。
JSON渲染器:这个相对简单,直接将分组、分类后的数据结构用Python的json.dumps方法序列化即可。关键是设计好JSON的schema,确保包含所有必要信息且结构清晰。
纯文本渲染器:可以看作是Markdown的简化版,去掉Markdown语法,用缩进和简单的分隔线来组织内容。
一个重要的功能点是:支持多仓库扫描。开发者可能同时在多个项目上工作。我们的工具应该支持传入一个包含多个仓库路径的列表或一个配置文件,然后依次对每个仓库执行上述操作,最后将结果合并输出到同一份日报中。这需要在Git提交获取器外层再套一个循环。
4. 命令行接口设计与用户体验优化
一个优秀的命令行工具,其接口设计必须直观、易用、具有自解释性。我们使用Python标准库argparse来构建命令行参数解析。
4.1 参数设计
我们需要定义一组核心参数:
-r, --repo: Git仓库的路径。可以指定多个(-r ./proj1 -r ./proj2),或者支持一个配置文件。如果不指定,默认为当前目录。-a, --author: 提交作者过滤。支持传入姓名或邮箱。如果不指定,则处理所有作者的提交。-s, --since: 起始时间。支持绝对日期(2024-01-01)和相对日期(yesterday,last monday,7 days ago)。-u, --until: 结束时间(不包含)。默认为“现在”。同样支持多种格式。-f, --format: 输出格式。可选markdown(默认)、json、text。-o, --output: 输出文件路径。如果不指定,则直接打印到标准输出(屏幕)。指定后则写入文件。-c, --config: 自定义分类规则配置文件的路径。
此外,还可以添加一些便利参数:
--today: 相当于--since today --until tomorrow。生成今日日报。--week: 生成本周(例如从周一到今天)的周报。--last-week: 生成上周的周报。-v, --verbose: 详细模式,输出更多处理日志,便于调试。
示例命令:
# 生成张三今天的Markdown日报,从默认仓库(当前目录) qclaw --author "张三" --today # 生成李四上周的JSON格式周报,扫描指定仓库,并保存到文件 qclaw --author "lisi@company.com" --last-week --format json --repo /path/to/projectA --repo /path/to/projectB -o weekly_report.json # 使用自定义分类规则,生成所有成员本周的详细日报 qclaw --week --config ./my_rules.yaml -o team_daily.md4.2 错误处理与友好提示
健壮的工具必须能妥善处理各种异常情况,并给出清晰的指引。
- 仓库路径无效:如果提供的路径不是Git仓库,应明确提示“提供的路径 ‘xxx’ 不是一个有效的Git仓库目录”,并停止执行。
- 时间参数解析失败:如果
--since或--until的参数无法被解析,应提示“无法识别的时间格式 ‘xxx’,请使用类似 ‘2024-01-01’ 或 ‘yesterday’ 的格式”。 - 未找到提交:在指定时间范围和作者下没有找到任何提交时,不要静默退出或报错。最好输出一条友好的提示信息,如“在指定条件(时间:xxx, 作者:xxx)下未找到任何提交记录。”,并返回一个空的报告或特定的退出码。
- 配置文件错误:如果用户提供了自定义配置文件但格式错误(如YAML语法错误),应捕获解析异常,提示“配置文件 ‘xxx’ 格式错误,请检查YAML语法”,并回退到使用内置默认规则。
- 网络问题(远程仓库):如果工具未来扩展支持远程仓库URL,需要处理网络超时、认证失败等情况。
良好的错误处理不仅能提升工具的专业度,更能节省用户大量的排查时间。
5. 高级功能探讨与扩展方向
基础功能实现后,我们可以思考一些能显著提升工具价值的进阶功能。
5.1 多仓库聚合与项目标签自动识别
对于同时在多个项目上工作的开发者,手动指定每个仓库路径很麻烦。我们可以扩展--repo参数,使其支持一个“工作空间目录”。工具自动扫描该目录下所有子文件夹,识别出哪些是Git仓库(通过检查是否存在.git文件夹),然后一并处理。
更进一步的,可以尝试自动识别项目标签。与其让用户在提交信息里手动写[项目A],不如让工具自动判断这个提交属于哪个项目(仓库)。当扫描多仓库时,工具可以记录每个提交来自哪个仓库路径,并将仓库名(通常是文件夹名)作为默认的“项目”标签。用户也可以通过一个映射配置文件,将仓库路径映射为更友好的项目名称(如/home/user/code/frontend->“前端项目”)。
5.2 与项目管理工具的集成(如Jira, Trello)
许多团队使用Jira、Trello、Asana等项目管理工具。一个强大的扩展点是让QClaw能够关联提交与这些工具中的任务(Issue/Ticket)。
实现思路:
- 提交信息约定:要求团队成员在提交信息中包含任务ID,例如
feat: [PROJ-123] 实现用户登录功能。 - 解析与关联:工具在解析提交信息时,用正则表达式提取出任务ID(如
PROJ-123)。 - API调用:工具集成这些项目管理工具的API(需要用户配置API Token和服务器地址)。在生成报告时,对于包含任务ID的提交,工具可以调用API去获取该任务的详细信息,如任务标题、状态、优先级等。
- 丰富报告:将获取到的任务信息填充到报告中。例如,在Markdown日报里,不仅显示提交信息,还可以显示“关联任务:PROJ-123 - 【高优先级】实现用户登录功能(状态:进行中)”。
这样生成的日报就不再是孤立的代码提交记录,而是与团队整体工作流紧密结合的、有上下文的工作成果汇总,价值大大提升。
5.3 数据统计与可视化趋势
日报是点状信息,而长期的数据统计能呈现面状趋势。工具可以增加一个“统计模式”(例如qclaw --stats --since 2024-01-01 --until 2024-03-01)。
在这个模式下,工具不再输出详细的提交列表,而是输出统计信息:
- 提交频率趋势:每日/每周的提交数量变化。
- 分类占比:一段时间内,各类工作(功能、修复、重构等)的比例。
- 活跃度分析:不同作者或不同项目的提交活跃度。
- 代码量估算(进阶):通过
git log --numstat可以获取每次提交增删的行数,从而粗略估算工作量。
这些统计数据可以输出为表格,或者更进一步,集成简单的图表库(如matplotlib)生成趋势图,让团队负责人对项目节奏和成员工作模式有更直观的了解。
6. 实际部署、使用与团队推广心得
工具开发完了,怎么用起来?特别是如何在团队中推广,让它真正产生价值?
6.1 安装与便捷化使用
对于个人用户,最直接的方式是通过源码运行:python qclaw.py --today。但更好的方式是将其打包为可执行文件或安装为全局命令。
- 使用
pip安装:通过setuptools打包项目,上传到内部PyPI或直接pip install .安装。安装后,就可以在任何地方直接使用qclaw命令了。 - 封装为Shell脚本/Alias:对于不想安装Python环境的同事,可以将常用的命令封装成一个简单的Shell脚本。例如,创建一个名为
myday的脚本:
然后给这个脚本加上执行权限,放到#!/bin/bash cd /path/to/your/main/code/directory python /path/to/qclaw.py --author "$(git config user.name)" --todayPATH路径下。每天下班前,只需在终端输入myday,就能自动生成并显示今日日报。
6.2 团队协作与规范制定
要让工具在团队中发挥作用,光有工具不够,还需要一点“软性”的规范。
- 推行规范的Commit Message:这是工具能高效工作的前提。向团队介绍类似 Conventional Commits 的规范,强调写清晰提交信息的好处(不仅是为了日报,更是为了可读的Git历史)。可以将其纳入团队的代码审查(Code Review) checklist中。
- 共享分类配置:在团队仓库中维护一个统一的
categories.yaml配置文件。确保大家对“feat”、“fix”等类型的理解是一致的。 - 集成到CI/CD或定时任务:可以设置一个每日定时任务(如Cron Job),在每天下午5点自动为每个团队成员生成日报,并通过邮件或团队聊天工具(如企业微信、钉钉机器人)发送到群里。这形成了一种温和的“仪式感”和透明的同步机制。
- 作为周会材料:在每周站会或复盘会上,直接使用工具生成的周报(
qclaw --week)作为讨论基础,回顾上周完成的工作,比大家凭记忆发言要准确高效得多。
6.3 遇到的典型问题与排查记录
在开发和推广过程中,我遇到并解决了一些典型问题:
问题一:提交时间与系统时间不一致,导致“今天”的提交没被抓到。
- 现象:用户明明今天有提交,但运行
qclaw --today却输出空结果。 - 排查:首先检查
git log --since="today"命令本身是否有结果。发现Git的--since参数使用的是作者日期(author date),而作者日期可能因为时区设置、机器时间不同步等原因与系统当前日期不符。 - 解决:在工具内部,将所有时间处理都统一为UTC时间,并在与用户输入的“今天”等概念比较时,进行正确的时区转换。同时,在文档中说明工具使用的是提交的作者日期,而非提交日期(commit date),建议团队成员保持开发环境的时区设置一致。
问题二:多仓库扫描时,某个仓库因权限或网络问题失败,导致整个任务中断。
- 现象:配置了多个远程仓库路径,运行时报错“无法访问仓库xxx”,工具停止。
- 解决:在遍历仓库的循环中加入异常捕获。对单个仓库的获取操作进行
try...except包装。如果某个仓库失败,则记录错误日志(print(f"[警告] 跳过仓库 {repo_path},原因:{e}")),然后继续处理下一个仓库。最终报告的开头可以汇总哪些仓库处理成功,哪些被跳过。
问题三:提交信息分类不准,很多提交被归到“其他事务”。
- 现象:生成的日报中“其他事务”类别条目非常多,失去了分类的意义。
- 排查:检查这些被误分类的提交信息内容。发现团队成员的提交习惯多样,有的用中文“修复”,有的用英文“fix”,有的甚至没有动词。
- 解决:这是一个持续优化的过程。我没有修改工具代码去迎合所有情况,而是做了两件事:
- 将内置的默认分类规则做得更宽松,增加更多常见的中英文关键词和正则模式。
- 鼓励并指导团队使用更规范的提交前缀。同时,将分类规则配置文件
categories.yaml的维护权交给团队,让他们可以根据自己团队的习惯共同维护和更新这个文件。工具只是执行分类规则的引擎。
问题四:生成的Markdown报告在某些平台渲染样式不佳。
- 现象:报告复制到公司的Confluence Wiki或飞书文档后,标题层级、列表缩进显示混乱。
- 解决:不同平台对Markdown的解析有细微差异。我增加了一个
--strict-markdown参数。当开启时,工具会使用最保守、兼容性最强的Markdown语法(比如标题前后加空行,列表使用4空格缩进)。同时,在文档中给出最佳实践建议,比如推荐先将报告粘贴到纯文本编辑器,再复制到目标平台,以避免富文本编辑器自动添加的格式干扰。
开发这样一个工具,最大的收获不是工具本身,而是它促使团队去思考和实践更规范、更透明的工作方式。它把日报从一个主观的、回忆式的总结,变成了一个客观的、基于事实的副产品。当你不再需要为写日报而绞尽脑汁,当你和团队的协作因为清晰的历史记录而更加顺畅时,你会觉得这一切的投入都是值得的。