Skip to content

fix(gbrain-sync): add .gbrain-source to consumer repo .gitignore#1521

Open
genisis0x wants to merge 1 commit into
garrytan:mainfrom
genisis0x:fix/1384-gbrain-source-gitignore
Open

fix(gbrain-sync): add .gbrain-source to consumer repo .gitignore#1521
genisis0x wants to merge 1 commit into
garrytan:mainfrom
genisis0x:fix/1384-gbrain-source-gitignore

Conversation

@genisis0x
Copy link
Copy Markdown

Summary

Closes #1384.

The v1.29.0.0 changelog claimed .gbrain-source was added to .gitignore so per-worktree pin doesn't leak across branches. The change actually shipped only added .gbrain-source to gstack's own .gitignore, not the consuming repo's. Conductor sibling worktrees of the same repo + branch end up clobbering each other's pin every time anyone commits the file.

Add the missing append in bin/gstack-gbrain-sync.ts::runCodeImport, right after gbrain sources attach <id> succeeds. The new ensureGbrainSourceGitignored helper is:

  • Idempotent — line-trim match so leading/trailing whitespace, duplicate runs, or pre-existing entries don't add a second copy.
  • Tolerant — missing .gitignore is created; unwritable file logs a warning and lets the rest of the sync continue. The pin failure mode is "noisy commits", not "broken sync", so we don't want to fail the whole stage.
  • Scoped — only fires after a successful attach. Failed attach already short-circuits.

Why this matters more for Conductor users

Single-worktree users mostly don't notice — the pin tracks the only checkout, so even if committed it points at the right source. Conductor users running /sync-gbrain in two sibling worktrees of the same repo + branch get different path-hash source IDs (correct, per v1.29.0.0). If either pin gets committed, git pull in the sibling overwrites the local pin and routes queries to the wrong worktree's source. The v1.29.0.0 changelog claimed to prevent exactly this.

Verification

$ bun test test/gbrain-source-gitignore.test.ts
6 pass
0 fail
8 expect() calls

Six covered scenarios:

  • creates .gitignore with the pin entry when none exists
  • appends to existing .gitignore without trailing newline (preserves \n discipline)
  • appends to existing .gitignore with trailing newline (no double newline)
  • idempotent on repeat call
  • recognizes the entry even when surrounded by whitespace (no duplicate add)
  • does not throw when the .gitignore is read-only

Existing test/gstack-gbrain-sync.test.ts was already failing in 10/20 cases on machines without a local gbrain CLI on PATH (unrelated to this PR). Pre-change baseline = post-change baseline for those.

Non-changes

  • The import.meta.main gate on the top-level main().catch(...) call is a small piggyback so the test file can import { ensureGbrainSourceGitignored } without triggering a full sync run on module load. Behaviorally a no-op for the CLI path — bun bin/gstack-gbrain-sync.ts still runs main() because the module IS the entry there.
  • runMemoryIngest, runBrainSync, and the dry-run path are untouched.
  • No change to the detach path — issue notes the gitignore entry is harmless to leave behind.

No newsfragment added per CLAUDE.md ("Contributor PR authors should not edit CHANGELOG.md; maintainer/AI adds entries during landing/merge").

…rytan#1384)

The v1.29.0.0 changelog promised .gbrain-source would be added to the
consuming repo's .gitignore so the per-worktree pin stays local, but the
change actually only added it to gstack's own .gitignore. Without the
consumer-side entry, the pin gets committed and Conductor sibling
worktrees of the same repo + branch step on each other's pin every time
anyone commits.

Add ensureGbrainSourceGitignored after a successful gbrain sources
attach in runCodeImport. Idempotent on repeat runs (line-trim match),
creates .gitignore if missing, logs a warning and continues on
permission errors so a read-only checkout doesn't fail the sync.

Gate the top-level main() call behind import.meta.main so tests can
import the helper without triggering a full sync run on module load.

Tests in test/gbrain-source-gitignore.test.ts cover: create-when-missing,
append-without-trailing-newline, append-with-trailing-newline,
idempotent on repeat, recognize whitespace-surrounded entry, no-throw
on read-only file. 6 pass.
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.

/sync-gbrain doesn't add .gbrain-source to consumer repo's .gitignore (v1.29.0.0 changelog promised it)

1 participant