Don't adopt an enclosing git repo that ignores the config dir#1720
Conversation
When a config dir sits inside an unrelated checkout that gitignores it, version history adopted that parent; git could never track the YAML so no backup was created, and we still wrote our managed block into the unrelated repo's info/exclude. Decline to adopt when the enclosing repo ignores the config dir and create a config-local repo instead, mirroring the existing own-source-checkout decline.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1720 +/- ##
=======================================
Coverage 99.54% 99.54%
=======================================
Files 227 227
Lines 18170 18174 +4
=======================================
+ Hits 18088 18092 +4
Misses 82 82
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
PR Review — Don't adopt an enclosing git repo that ignores the config dirTight, correct bugfix — declines to adopt an enclosing repo that gitignores the config dir, mirroring the existing own-source decline path. Merge-ready. Strengths:
Nitpicks (non-blocking):
Checklist
Automated review by Kōan (Claude) |
esphbot
left a comment
There was a problem hiding this comment.
No blocking issues found.
There was a problem hiding this comment.
Pull request overview
Prevents the version-history feature from adopting an enclosing Git worktree when that enclosing repo ignores the configured config directory, avoiding both “no backups created” and unintended mutation of an unrelated repository’s .git/info/exclude.
Changes:
- Declines adoption of an enclosing repo when
git check-ignoreindicates the config directory is ignored, and initializes a nested repo in the config dir instead. - Improves the info log message to reflect why adoption was declined (own source checkout vs ignored config dir).
- Adds a regression test covering the “enclosing repo ignores config dir” scenario (issue #1718).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| esphome_device_builder/controllers/version_history/git_repo.py | Adds ignore-detection to avoid adopting an enclosing repo that can’t track the config directory. |
| tests/controllers/version_history/test_git_repo.py | Adds a test ensuring an ignored config dir gets its own nested history repo and the parent repo is not modified. |
| """A config dir gitignored by its enclosing repo gets a nested repo, not adoption. | ||
|
|
||
| Adopting an enclosing checkout that ``.gitignore``s the config dir backs up | ||
| nothing (git refuses the ignored YAML) while still writing our managed block | ||
| into that unrelated repo (#1718). | ||
| """ |
| def _enclosing_repo_ignores_config_dir(self) -> bool: | ||
| """Whether the enclosing work tree ignores ``config_dir`` itself. | ||
|
|
||
| A ``/config`` inside an unrelated checkout that ``.gitignore``s it can | ||
| never track our YAML, so adopting would back up nothing while still | ||
| writing into that repo; init a config-local repo instead. | ||
| """ |
| result = self._run( | ||
| ["check-ignore", "-q", str(self.config_dir)], | ||
| cwd=self.config_dir, | ||
| check=False, | ||
| ) |
|
Thanks! |
|
Copilot's review landed just after merge; addressed the three points in #1725: pass |
What does this implement/fix?
When the config dir sits inside an unrelated git checkout that gitignores it (e.g. an esphome/esphome clone with
config/in its.gitignore), version history walked up, found the parent work tree, and adopted it. That repo can never track our YAML (git ignores the dir), so no backup is ever created; meanwhile we still wrote our managed block into the parent's.git/info/exclude, mutating an unrelated repo.This declines to adopt an enclosing repo that ignores the config dir and creates a config-local repo instead, mirroring the existing decline path for the Device Builder source checkout. Detection is a single
git check-ignoreof the config dir; a non-ignored subdir (the normal/configcase) still adopts as before.Related issue or feature (if applicable):
Types of changes
bugfixnew-featureenhancementbreaking-changerefactordocsmaintenancecidependenciesFrontend coordination
Checklist
ruff,codespell, yaml/json/python checks).tests/where applicable.components.index.json/definitions/components/*.jsonhave not been hand-edited (regenerate viascript/sync_components.pyif a sync is needed).docs/ARCHITECTURE.mdand/ordocs/API.md.