Skip to content

fix(writer): skip rewrite when only generated marker timestamp differs#1

Merged
StringKe merged 1 commit into
StringKe:mainfrom
nin39six:fix/sync-stable-timestamp
May 11, 2026
Merged

fix(writer): skip rewrite when only generated marker timestamp differs#1
StringKe merged 1 commit into
StringKe:mainfrom
nin39six:fix/sync-stable-timestamp

Conversation

@nin39six
Copy link
Copy Markdown
Contributor

Problem

每次 stdagent sync 后所有 inject=true 的目标文件 mtime 都被刷新,git diff 充满"无实质变化"的 noise,污染提交历史。期望是只有源文档真的修改时,对应的目标文档才被改动。

Root cause

internal/writer/footer.goHeaderCommenttime.Now() 渲染为 at <RFC3339> 注入 header marker:

<!-- Generated by stdagent v0.1.0 at 2026-05-10T08:32:11Z. Source: ... -->

internal/writer/writer.goApplybytes.Equal(exist, op.Content) 判等,timestamp 差异让等式永远不成立,所有文件都走 atomicWrite 路径,mtime 与 git diff 全部翻新。

Fix

Apply 在精确字节比较失败后再做一次"剥离 <!-- Generated by stdagent ... --> 后比较"。相等则保留旧文件(mtime 不变),不等则照常写入新内容(含新 timestamp)。

  • 源文档未变 → 输出文件 byte-identical,git diff 干净
  • 源文档变了 → 仅对应文件被改写
  • 旧文件无 marker(用户 inject=false)→ 行为与之前一致

Tests

internal/writer/writer_test.go 新增三个 test case:

  • TestApplySkipsWhenOnlyMarkerTimestampDiffers:仅 timestamp 差异时 skipped=1、mtime 保持、文件内容保持旧版。
  • TestApplyWritesWhenBodyChangesEvenIfMarkerSame:body 变更照常写入。
  • TestStripGeneratedMarker:归一化函数本身的行为。

本地验证:go test -race ./... 全绿,go vet ./...gofmt -l clean。

HeaderComment injects time.Now() as 'at <RFC3339>' on every sync, so
bytes.Equal between the existing file and the new content was always
false. Every inject=true output got rewritten by atomicWrite, refreshing
the mtime and producing a noisy git diff even when the underlying source
docs had not changed.

Apply now does a second equality check after stripping the leading
'<!-- Generated by stdagent ... -->' comment from both sides. Files are
left untouched (mtime preserved) when only the header marker differs;
real body changes still write through normally and refresh the timestamp.

Adds tests covering: timestamp-only change is skipped, mtime is
preserved, body change still writes through, and stripGeneratedMarker
itself.
@StringKe StringKe merged commit e5df1a4 into StringKe:main May 11, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants