atmos icon indicating copy to clipboard operation
atmos copied to clipboard

fix: resolve 'lstat : no such file or directory' error and add Git worktree support

Open osterman opened this issue 5 months ago • 3 comments

what

  • Fixed the cryptic "lstat : no such file or directory" error in atmos describe affected command
  • 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_on configuration 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 affected not 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/HEAD reference 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.

osterman avatar Sep 24 '25 17:09 osterman

[!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 review command 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.log is 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 error
errors/errors.go
Adds ErrInvalidGitFileFormat = errors.New("invalid .git file format").
Describe Affected: worktree-aware clone & checkout
internal/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 & logging
internal/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 refactor
internal/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 detection
internal/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 scenarios
internal/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 scenario
tests/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 scenarios
internal/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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Sep 24 '25 17:09 coderabbitai[bot]

[!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.

mergify[bot] avatar Sep 24 '25 19:09 mergify[bot]

💥 This pull request now has conflicts. Could you fix it @osterman? 🙏

mergify[bot] avatar Sep 30 '25 20:09 mergify[bot]