Git notes 追加提交备注:信息补上了,原提交为什么仍是同一个

10-01 3阅读

代码已经提交并被别人使用,第二天才拿到测试结果。如果为了补一句验证说明而重写提交消息,提交标识也会变化,原有链接和协作记录需要重新核对。Git notes 提供另一条路:把补充说明挂到已有对象上,让原提交继续保持原样。

这里的备注存放在独立引用中。常用默认位置是 refs/notes/commits,还可以按用途建立 review 等命名空间。同一个提交因而能够拥有构建记录和评审记录,两类信息各自维护。它不是工作目录里的注释文件,也不是偷偷改写提交消息。

在一次性仓库里观察标识是否变化

下面保存为 demo.sh,使用 Bash 和 Git 执行 bash demo.sh。脚本新建临时目录,使用演示身份创建一个提交,只写该临时仓库。身份通过当前脚本的环境变量提供,不修改全局配置。实验目录保留在输出路径中,便于事后查看。

Git notes 追加提交备注:信息补上了,原提交为什么仍是同一个

AI概念示意图:以抽象物件说明本文主题,不代表真实界面或运行结果。

#!/usr/bin/env bash
set -eu
work=$(mktemp -d)
export GIT_AUTHOR_NAME='Notes Demo'
export GIT_AUTHOR_EMAIL='notes@example.invalid'
export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"
git init -q -b main "$work/repo"
cd "$work/repo"
printf 'alpha\n' > sample.txt
git add sample.txt
git -c commit.gpgsign=false commit -qm initial
before=$(git rev-parse HEAD)
git notes --ref=commits add -m 'build=ok' HEAD
git notes --ref=review add -m 'review=pending' HEAD
after=$(git rev-parse HEAD)
test "$before" = "$after"
test "$(git log -1 --format=%B)" = initial
test "$(git notes --ref=commits show HEAD)" = 'build=ok'
test "$(git notes --ref=review show HEAD)" = 'review=pending'
test -z "$(git status --porcelain)"
printf 'commit-unchanged=yes\n'
printf 'message=%s\n' "$(git log -1 --format=%B)"
printf 'commit-note=%s\n' "$(git notes --ref=commits show HEAD)"
printf 'review-note=%s\n' "$(git notes --ref=review show HEAD)"
printf 'repo=%s\n' "$work/repo"

四条断言分别证明什么

输出中的 commit-unchanged=yes 对应添加两类备注前后的 HEAD 相等,message=initial 对应原提交说明未改。两条 note 输出来自不同引用,展示同一个目标对象可以拥有彼此独立的备注。最后的 test 确认工作树干净,避免把备注误认为待提交文件。

每次更新通常会在相应 notes 引用上形成新的提交,所以备注本身也有历史。要检查它,查看该引用的日志,而不是只看 main 分支。这里“原提交没有变化”不意味着仓库没有新增对象;新增的是承载补充信息的另一段历史。

找不到备注时先核对命名空间

读取时显式写 --ref=commits 或 --ref=review,能避免本机配置改变默认引用造成困惑。若只用默认命令查看,review 里的内容未必显示。浏览日志时可以选择相应 notes 引用;展示设置与存储位置是两个问题,换一种显示方式不会复制备注。

还要区分 notes add、append 和 edit。add 遇到已有备注通常拒绝覆盖,append 用于追加,edit 用于人工修改;不应为了让脚本继续运行就随手加 force。自动写入前先读现有内容,明确是保留、合并还是替换,才能避免丢掉后来补充的信息。

协作前把同步范围说清楚

普通分支的推送与拉取不能一概视为已经同步 notes,实际取决于引用映射。团队需要单独约定传送哪些 refs/notes 引用,以及多人更新同一备注时如何处理冲突。本文只验证本地行为,没有连接远端,也没有证明托管平台的页面会显示备注。

如果把提交重写成新的对象,原备注仍然关联旧对象。是否在特定重写操作中复制备注,受相关命令和配置影响,不能只看新旧文件内容相同就推定备注跟随。验收时应同时检查目标提交标识、notes 引用和实际读取结果。

备份时也应把备注引用列入清单。只有工作目录文件的压缩包无法保留这些关系;只导出某条分支的提交,也未必包含备注历史。恢复验收要在独立副本里按原提交标识读取两类备注,确认保存的不只是代码,还有约定保留的补充记录。

备注适合记录测试批次、补充解释和追踪编号,但并不天然具有可信证明能力。看到 build=ok 只能说明有人写下这段文字,仍要回到真正的测试记录确认执行环境和结果。把可核对的证据链接附在备注里,比只留一个成功标签更有用。

参考资料

文章版权声明:除非注明,否则均为云鹊BLOG原创文章,转载或复制请以超链接形式并注明出处。