问题
博客用了 Hugo 的 GitInfo 功能,在文章底部显示最后更新时间和 commit 信息。配置很简单:
1# hugo.toml
2enableGitInfo = true
模板里这样写:
1{{ with .GitInfo }}
2<div class="gitinfo">
3 <span>{{ $.Type | upper }} UPDATED {{ .AuthorDate.Format "2006-01-02" }}</span>
4 <span>#{{ .AbbreviatedHash }} {{ .Subject }}</span>
5</div>
6{{ end }}
大部分文章一切正常。但有几篇页面的 GitInfo 死活不显示——{{ with .GitInfo }} 直接跳过了,说明 .GitInfo 是 nil。
排查
第一步:确认配置和模板没问题
检查了 enableGitInfo = true 在配置中存在,gitinfo.html partial 也在 single.html 中正确引入。没发现问题。
第二步:确认 git 仓库有记录
1git log -1 --format="%H %ai %s" -- "content/posts/2026/05/建造者日报-2026-05-20/index.md"
所有文件都有 git commit 记录,且工作树是 clean 的。问题不在 git 这一层。
第三步:构建后逐页检查
构建站点后,用 grep 扫描所有生成的 HTML:
1find public/posts -name "index.html" | while read f; do
2 if grep -q "gitinfo" "$f"; then echo "HAS: $f"
3 else echo "MISS: $f"; fi
4done
结果很有规律——缺 GitInfo 的全是中文目录名的博文:
| 缺失 GitInfo | 正常显示 |
|---|---|
建造者日报-2026-05-20/ |
hugo-pragmata-theme/ |
建造者日报-2026-05-21/ |
centos-docker-k8s/ |
A股复盘-2026-05-19/ |
docker-penpot/ |
A股复盘-2026-05-20/ |
paperclip-ai/ |
第四步:定位根因
在 gitinfo partial 里加了一行 debug 标记,重新构建:
1<span data-debug="true" data-has-gitinfo="{{ if .GitInfo }}yes{{ else }}no{{ end }}"></span>
确认中文路径的页面 data-has-gitinfo="no",英文路径的 data-has-gitinfo="yes"。
然后注意到 git log 输出中,中文路径被转义了:
"content/posts/2026/05/\345\273\272\351\200\240\350\200\205\346\227\245\346\212\245-2026-05-20/index.md"
这是 git 的 core.quotePath 默认行为——非 ASCII 字符会被编码为八进制转义序列。Hugo 内部调用 git log 获取文件 commit 信息时,用原始中文路径去匹配,但 git 返回的是编码后的路径,匹配失败,导致 .GitInfo 为空。
解决
一行配置:
1git config core.quotePath false
设置后,git log 输出中文路径不再转义,Hugo 能正确匹配文件,GitInfo 恢复正常。
如果服务器上也有构建流程(比如从 Gitee 拉取后 hugo build),服务器上也要配:
1# 项目级(跟随仓库,推荐)
2git config core.quotePath false
3
4# 或全局
5git config --global core.quotePath false
如果不想每次手动配,可以在部署脚本里加上这一行:
1cd /path/to/blog && git config core.quotePath false && git pull && hugo
教训
Hugo 的 GitInfo 功能依赖 git log 的输出格式。当内容文件路径包含中文(或任何非 ASCII 字符)时,git 的 core.quotePath=true 默认值会触发路径编码,导致 Hugo 无法匹配文件与 commit 记录。
这个坑比较隐蔽,因为 Hugo 不会报错——只是静默地让 .GitInfo 为 nil,模板里的 {{ with .GitInfo }} 直接跳过,页面上少了一块内容,不仔细看根本发现不了。