feat(init): scaffold managed .specify/.gitignore - #35
Closed
mnriem wants to merge 1 commit into
Closed
Conversation
Write a manifest-tracked `.specify/.gitignore` during shared-infra install so machine-local Spec Kit state stays out of version control while everything else under `.specify/` remains shareable: - `feature.json` — the current-feature pointer, rewritten on every feature switch (per-checkout state, not something to share). - `extensions/*/local-config.yml` — per-machine extension config overrides. The file is routed through the same overwrite/skip/preserve policy as shared templates: `--force` refreshes it, user edits are preserved on re-init, and uninstall removes it via the manifest. Addresses github#2304. Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 98faefd1-9fc8-48fc-bd25-d4f3ccbb2ab9
Owner
Author
|
Superseded by the upstream PR github#4000, which targets github/spec-kit:main. Closing this fork-targeted PR. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Answers the recurring "what should I commit under
.specify?" question (discussion #2304) by scaffolding a managed.specify/.gitignoreat init time. It excludes machine-local state while leaving everything shareable tracked, so teams get sensible defaults out of the box instead of having to reverse-engineer which files are session-local.Ignored (machine/session-local):
feature.json— the current-feature pointer, rewritten on every feature switch (per-checkout state, sharing it only causes churn/merge noise).extensions/*/local-config.yml— per-machine extension config overrides (already documented as gitignored inConfigManager).Everything else under
.specify/(constitution, templates, scripts,extensions.yml, project-level extension config) stays tracked so a team shares a consistent setup.Implementation
install_shared_infra(src/specify_cli/shared_infra.py), routed through the same overwrite/skip/preserve policy as shared templates:specify integration uninstallremoves it;specify init --here --forcerestores the managed content..specify/.gitignore(patterns relative to that dir) rather than touching the project-root.gitignore, so the CLI never clobbers a file the user owns.Why a nested
.specify/.gitignoreand not a root-level merge?This was a deliberate design choice over merging entries into the project-root
.gitignore:.gitignoreinside.specify/is a first-class git mechanism —git check-ignorecorrectly ignores.specify/feature.jsonand.specify/extensions/*/local-config.yml. Root placement would only add discoverability, not correctness..gitignorewould require a delimited managed block plus custom idempotent-merge and surgical-removal logic, and any unrelated user edit would change the file hash and break the manifest's preserve/refresh behavior..gitignore(seeinit.py) — it never auto-edits the root file. The only marker-block-in-a-user-file pattern in Spec Kit is theagent-contextextension, which is deliberately opt-in because it owns that complexity.Note (independent of file location): a
.gitignoredoes not untrack files that were already committed — afeature.jsoncommitted before upgrading still needs a manualgit rm --cached.Tests
New
tests/test_shared_infra_gitignore.pycovers: file creation + manifest tracking, realgit check-ignorebehaviour for the target paths (and that a shareable file likeconstitution.mdis not ignored), user-edit preservation, and--forcerestore. Existing shared-infra / init / manifest suites pass (130 passed, 2 skipped locally).Docs
Added a "Version control" note to
docs/reference/core.mdand a CHANGELOG entry.Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous). Opened on behalf of @mnriem.