Git Worktree Support#279
Conversation
|
|
📝 WalkthroughWalkthroughThe pull request introduces a new asynchronous function Changes
Possibly related PRs
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (5)
src/core/file/fileSearch.ts (3)
45-58: Consider enhancing the robustness ofisGitWorktreeRef.The function works correctly but could be more robust with these improvements:
- Add input validation for
gitPath- Extract "gitdir:" as a constant
- Trim the file content before checking
+const GIT_WORKTREE_PREFIX = "gitdir:"; + // Check if a path is a git worktree reference file const isGitWorktreeRef = async (gitPath: string): Promise<boolean> => { + if (!gitPath) { + return false; + } + try { const stats = await fs.stat(gitPath); if (!stats.isFile()) { return false; } const content = await fs.readFile(gitPath, "utf8"); - return content.startsWith("gitdir:"); + return content.trim().startsWith(GIT_WORKTREE_PREFIX); } catch { return false; } };
84-97: Extract git-related patterns as constants and add documentation.The git worktree handling logic could be more maintainable with these improvements:
- Extract git-related patterns as constants
- Add comments explaining the pattern adjustment logic
+const GIT_DIR_PATTERN = ".git/**"; +const GIT_FILE_PATTERN = ".git"; + // Check if .git is a worktree reference const gitPath = path.join(rootDir, ".git"); const isWorktree = await isGitWorktreeRef(gitPath); +// For git worktrees, we need to: +// 1. Remove the '.git/**' pattern as it's not a directory +// 2. Add '.git' to ignore the reference file itself const adjustedIgnorePatterns = [...ignorePatterns]; if (isWorktree) { - // Remove '.git/**' pattern and add '.git' to ignore the reference file - const gitIndex = adjustedIgnorePatterns.indexOf(".git/**"); + const gitIndex = adjustedIgnorePatterns.indexOf(GIT_DIR_PATTERN); if (gitIndex !== -1) { adjustedIgnorePatterns.splice(gitIndex, 1); - adjustedIgnorePatterns.push(".git"); + adjustedIgnorePatterns.push(GIT_FILE_PATTERN); } }
101-101: Optimize array spreading in globby options.The spread operator is used twice with
adjustedIgnorePatterns. Consider passing the array directly to avoid unnecessary array copying.const filePaths = await globby(includePatterns, { cwd: rootDir, - ignore: [...adjustedIgnorePatterns], + ignore: adjustedIgnorePatterns, ignoreFiles: [...ignoreFilePatterns], onlyFiles: true, // ... }); const directories = await globby(includePatterns, { cwd: rootDir, - ignore: [...adjustedIgnorePatterns], + ignore: adjustedIgnorePatterns, ignoreFiles: [...ignoreFilePatterns], onlyDirectories: true, // ... });Also applies to: 122-122
tests/core/file/fileSearch.test.ts (2)
276-310: Enhance git worktree test coverage.The test case is good but could be improved:
- Use the same constants as the implementation
- Add test cases for error scenarios (invalid file content, read errors)
+const GIT_DIR_PATTERN = ".git/**"; +const GIT_FILE_PATTERN = ".git"; +const GIT_WORKTREE_PREFIX = "gitdir:"; test('should handle git worktree correctly', async () => { // Mock .git file content for worktree - const gitWorktreeContent = 'gitdir: /path/to/main/repo/.git/worktrees/feature-branch'; + const gitWorktreeContent = `${GIT_WORKTREE_PREFIX} /path/to/main/repo/.git/worktrees/feature-branch`; // ... existing test code ... // Verify .git file (not directory) is in ignore patterns - expect(ignorePatterns).toContain('.git'); + expect(ignorePatterns).toContain(GIT_FILE_PATTERN); // Verify .git/** is not in ignore patterns - expect(ignorePatterns).not.toContain('.git/**'); + expect(ignorePatterns).not.toContain(GIT_DIR_PATTERN); }); +test('should handle invalid git worktree file content', async () => { + vi.mocked(fs.stat).mockResolvedValue({ + isFile: () => true, + } as fs.Stats); + vi.mocked(fs.readFile).mockResolvedValue('invalid content'); + + const mockConfig = createMockConfig({ + ignore: { + useGitignore: true, + useDefaultPatterns: true, + customPatterns: [], + }, + }); + + const result = await searchFiles('/test/dir', mockConfig); + const globbyCall = vi.mocked(globby).mock.calls[0]; + const ignorePatterns = globbyCall[1]?.ignore as string[]; + + // Should treat it as a regular git repository + expect(ignorePatterns).toContain(GIT_DIR_PATTERN); + expect(ignorePatterns).not.toContain(GIT_FILE_PATTERN); +});
312-342: Use consistent constants in regular git repository test.For consistency with the implementation and the worktree test, use the same constants for git patterns.
+const GIT_DIR_PATTERN = ".git/**"; +const GIT_FILE_PATTERN = ".git"; test('should handle regular git repository correctly', async () => { // ... existing test code ... // Verify .git/** is in ignore patterns for regular git repos - expect(ignorePatterns).toContain('.git/**'); + expect(ignorePatterns).toContain(GIT_DIR_PATTERN); // Verify just .git is not in ignore patterns - expect(ignorePatterns).not.toContain('.git'); + expect(ignorePatterns).not.toContain(GIT_FILE_PATTERN); });
Previously repomix failed when processing git worktree directories due to .git being a file rather than directory. Now it correctly adjusts ignore patterns for worktree references.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #279 +/- ##
==========================================
+ Coverage 92.12% 92.20% +0.07%
==========================================
Files 44 44
Lines 2146 2168 +22
Branches 469 474 +5
==========================================
+ Hits 1977 1999 +22
Misses 169 169 ☔ View full report in Codecov by Sentry. |
|
Hi, @slavashvets ! I've reviewed the changes and tested the functionality - everything looks perfect. The implementation and test coverage are solid. I'll merge this right away. Thanks for your contribution! 🙌 |
|
@slavashvets Thank you again for your great contribution! The Git Worktree support makes Repomix more useful for developers using this Git feature. |
Fixes an issue where Repomix fails when processing repositories created using
git worktree. The error occurred because in worktree repositories,.gitis a file containing a reference to the main repository, rather than a directory:Changes
.gitfile instead of.git/**directory for worktreesWhy
When using
git worktree, developers can create multiple working trees from a single repository. This is a common workflow for working on multiple branches simultaneously. The current version of Repomix fails in these cases with an ENOTDIR error because it tries to process.gitas a directory.