fix: resolve 'lstat : no such file or directory' error and add Git worktree support
what
- Fixed the cryptic "lstat : no such file or directory" error in
atmos describe affectedcommand - Added proper Git worktree support to prevent detached HEAD state
- Improved error messages to be more helpful and actionable
why
- Users were getting unhelpful error messages when
depends_onconfiguration had entries with empty file/folder fields - The command was failing in Git worktrees with "refs/remotes/origin/HEAD does not exist" errors
- Running the command in a worktree would leave the repository in a detached HEAD state, which was disruptive to workflow
references
- Fixes issues with
atmos describe affectednot working correctly with Git worktrees - Resolves cryptic error messages that don't help users understand what went wrong
Details
Issue 1: Empty File/Folder Dependencies
The isComponentDependentFolderOrFileChanged function had variables declared outside a loop that weren't being reset between iterations. When depends_on had mixed entries (some with file/folder fields, others with only component fields), it would try to process empty strings with filepath.Abs(""), causing the unhelpful error.
Solution: Fixed variable scoping - variables are now properly reset for each dependency iteration.
Issue 2: Git Worktree Support
When copying a worktree to a temp directory, the .git file points to the original repository. With EnableDotGitCommonDir: false, go-git couldn't access the Git data, and checkout operations would modify the original repository.
Solution:
- Added
isGitWorktree()function to detect worktrees - When in a worktree, clone from the main repository instead of copying
- Set up
refs/remotes/origin/HEADreference after cloning - This prevents the detached HEAD state issue
Testing
- Added comprehensive unit tests for empty dependency handling
- Added tests for Git worktree detection
- All existing tests continue to pass
- Manually tested in Git worktrees and regular repositories
🤖 Generated with Claude Code
Summary by CodeRabbit
-
New Features
- Worktree-aware repository handling for cloning, fetching and checkout.
- Automatic base-path adjustment when running from subdirectories.
- Improved remote origin resolution and safer HEAD handling.
-
Bug Fixes
- Reliable detection of changes across mixed dependencies (file/folder/component).
- Prevented lstat errors and panics with empty or partial dependency entries.
- More accurate diffing and path resolution in “describe affected”.
-
Tests
- Extensive worktree, subdirectory and mixed/empty-dependency test coverage.
-
Chores
- Added an explicit exported error for invalid Git file format.
[!WARNING]
Rate limit exceeded
@osterman has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 14 minutes and 51 seconds before requesting another review.
⌛ How to resolve this issue?
After the wait time has elapsed, a review can be triggered using the
@coderabbitai reviewcommand as a PR comment. Alternatively, push new commits to this PR.We recommend that you space out your commits to avoid hitting the rate limit.
🚦 How do rate limits work?
CodeRabbit enforces hourly rate limits for each developer per organization.
Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.
Please see our FAQ for further information.
📥 Commits
Reviewing files that changed from the base of the PR and between fa65b3b954fb772da324ec1f1bd62a0af4815e92 and 656c1b5fa4b085fcafddfe13021abde66005b52e.
â›” Files ignored due to path filters (1)
test-output.logis excluded by!**/*.logđź“’ Files selected for processing (3)
internal/exec/describe_affected_helpers.go(6 hunks)internal/exec/describe_affected_test.go(5 hunks)internal/exec/describe_affected_utils_2.go(2 hunks)
📝 Walkthrough
Walkthrough
Adds a new exported error and implements Git worktree-aware repository handling, adjusts basePath computation when running from subdirectories, refactors dependency-change detection, and adds comprehensive tests and fixtures for worktree and dependency scenarios.
Changes
| Cohort / File(s) | Summary |
|---|---|
Errors: new exported errorerrors/errors.go |
Adds ErrInvalidGitFileFormat = errors.New("invalid .git file format"). |
Describe Affected: worktree-aware clone & checkoutinternal/exec/describe_affected_helpers.go |
Detects Git worktrees via .git file, resolves main repo path, clones main repo into a temp repo, updates origin to the real remote URL, fetches refs, and ensures refs/remotes/origin/HEAD; retains fallback non-worktree copy logic and adds logging. |
Describe Affected: cwd/basePath adjustments & logginginternal/exec/describe_affected_utils.go |
Adds CWD and repo-root relative path computation, adjusts basePath when running from subdirectories, propagates os.Getwd/filepath.Rel errors, and adds diagnostic logging for heads, paths, stacks, and changed files. |
Dependency detection refactorinternal/exec/describe_affected_utils_2.go |
Rewrites isEqual guards and isComponentDependentFolderOrFileChanged to use explicit checks, absolute path resolution, single-match early return, and richer error wrapping. |
Unit tests: dependency detectioninternal/exec/describe_affected_utils_2_test.go |
Adds tests covering mixed/empty depends_on entries, folder vs file detection, and no-change cases. |
Unit tests: Git worktree & subdirectory scenariosinternal/exec/describe_affected_worktree_test.go, internal/exec/describe_affected_subdirectory_test.go |
Adds tests for worktree detection, repo copy/open behavior, path calculation from subdirectories, and describe-affected flows using worktrees. |
Test fixtures: empty deps scenariotests/test-cases/describe-affected-with-empty-deps/atmos.yaml, tests/test-cases/describe-affected-with-empty-deps/components/terraform/mixins/common.tf, tests/test-cases/describe-affected-with-empty-deps/stacks/test-stack.yaml |
Adds Atmos config, a common mixin file, and a stack manifest containing mixed depends_on entries to reproduce edge cases. |
Test updates: describe affected scenariosinternal/exec/describe_affected_test.go |
Expands and reassigns test scenarios, stacks, and dependency expectations to match new detection/templating behavior. |
Sequence Diagram(s)
sequenceDiagram
autonumber
actor User
participant CLI as DescribeAffected
participant FS as Local FS
participant Git as go-git
participant Remote as Remote Origin
User->>CLI: run describe-affected
CLI->>FS: stat target path
alt .git is a file (worktree)
CLI->>FS: read .git file -> resolve main repo path
CLI->>Git: clone main repo into temp
CLI->>Git: read remote URL from main repo
CLI->>Git: set origin to remote URL
CLI->>Remote: fetch refs
CLI->>Git: ensure refs/remotes/origin/HEAD (symref to main/master)
else regular repo
CLI->>FS: use existing copy/clone logic
end
CLI->>FS: getcwd & compute path relative to repo root
CLI->>CLI: adjust basePath if running from subdir
CLI->>Git: resolve HEAD/BASE hashes
CLI->>CLI: diff trees -> list changed files
CLI->>CLI: evaluate component depends_on (folder/file/component)
CLI-->>User: return affected stacks/components
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~60 minutes
Possibly related PRs
- cloudposse/atmos#1267 — overlaps describe-affected internals and worktree/checkout logic.
- cloudposse/atmos#1494 — adds exported error variables in
errors/errors.go(similar public API changes). - cloudposse/atmos#1440 — also introduces new exported error sentinels in
errors/errors.go.
Suggested reviewers
- aknysh
Pre-merge checks and finishing touches
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | ⚠️ Warning | Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
âś… Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title Check | ✅ Passed | The title succinctly captures the two primary objectives of the pull request—fixing the “lstat : no such file or directory” error and adding Git worktree support—and accurately reflects the scope of the changes described in the PR objectives and code summaries. |
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
[!WARNING]
This PR exceeds the recommended limit of 1,000 lines.
Large PRs are difficult to review and may be rejected due to their size.
Please verify that this PR does not address multiple issues. Consider refactoring it into smaller, more focused PRs to facilitate a smoother review process.
💥 This pull request now has conflicts. Could you fix it @osterman? 🙏