fix: support bare repo worktrees in GitWorktree widget (#138)

* fix: support bare repo worktrees in GitWorktree widget

The GitWorktree widget now correctly detects worktrees from bare
repositories. Previously, it only checked for `.git/worktrees/` in
the path, but bare repos store worktree metadata at
`<bare-repo>/worktrees/<name>` without the `.git` prefix.

This adds an additional check for `/worktrees/` pattern when the
`.git/worktrees/` pattern isn't found.

Fixes detection for setups like:
- Bare repo at: /path/to/repo (contains objects/, refs/, HEAD, etc.)
- Worktree at: /path/to/repo/trees/feature-x
- Git dir: /path/to/repo/worktrees/feature-x

* chore: remove accidental npm lockfile from PR branch

* chore: bump version to 2.1.10 and update recent updates

---------

Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
This commit is contained in:
Gary NortonandMatthew Breedlove authored and GitHub committed 2026-03-04 11:47:59 -05:00
1 parent 59d43589c9
commit 990f2703b1
4 files changed
+37 -10

No files matched your search

+2 -1
View File
@@ -46,7 +46,7 @@
## 🆕 Recent Updates
### v2.1.0 - v2.1.9 - Usage widgets, links, new git insertions / deletions widgets, and reliability fixes
### v2.1.0 - v2.1.10 - Usage widgets, links, new git insertions / deletions widgets, and reliability fixes
- **🧩 New Usage widgets (v2.1.0)** - Added **Session Usage**, **Weekly Usage**, **Block Reset Timer**, and **Context Bar** widgets.
- **📊 More accurate counts (v2.1.0)** - Usage/context widgets now use new statusline JSON metrics when available for more accurate token and context counts.
@@ -58,6 +58,7 @@
- **⏳ Weekly reset timer split (v2.1.7)** - Added a separate `Weekly Reset Timer` widget.
- **⚙️ Custom config file flag (v2.1.8)** - Added `--config <path>` support so ccstatusline can load/save settings from a custom file location.
- **🔣 Unicode separator hex input upgrade (v2.1.9)** - Powerline separator hex input now supports 4-6 digits (full Unicode code points up to `U+10FFFF`).
- **🌳 Bare repo worktree detection fix (v2.1.10)** - `Git Worktree` now correctly detects linked worktrees created from bare repositories.
### v2.0.26 - v2.0.29 - Performance, git internals, and workflow improvements
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ccstatusline",
"version": "2.1.9",
"version": "2.1.10",
"description": "A customizable status line formatter for Claude Code CLI",
"module": "src/ccstatusline.ts",
"type": "module",
+13 -8
View File
@@ -52,25 +52,30 @@ export class GitWorktreeWidget implements Widget {
private getGitWorktree(context: RenderContext): string | null {
const worktreeDir = runGit('rev-parse --git-dir', context);
if (!worktreeDir) {
if (!worktreeDir)
return null;
}
const normalizedGitDir = worktreeDir.replace(/\\/g, '/');
// /some/path/.git or .git
// /some/path/.git or .git (main worktree of regular repo)
if (normalizedGitDir.endsWith('/.git') || normalizedGitDir === '.git')
return 'main';
// /some/path/.git/worktrees/some-worktree or /some/path/.git/worktrees/some-dir/some-worktree
const marker = '.git/worktrees/';
const markerIndex = normalizedGitDir.lastIndexOf(marker);
if (markerIndex === -1) {
return null;
const repoMarker = '.git/worktrees/';
const repoMarkerIndex = normalizedGitDir.lastIndexOf(repoMarker);
if (repoMarkerIndex !== -1) {
const worktree = normalizedGitDir.slice(repoMarkerIndex + repoMarker.length);
return worktree.length > 0 ? worktree : null;
}
const worktree = normalizedGitDir.slice(markerIndex + marker.length);
// /some/path/worktrees/some-worktree or /some/path/worktrees/some-dir/some-worktree
const bareMarker = '/worktrees/';
const bareMarkerIndex = normalizedGitDir.lastIndexOf(bareMarker);
if (bareMarkerIndex === -1)
return null;
const worktree = normalizedGitDir.slice(bareMarkerIndex + bareMarker.length);
return worktree.length > 0 ? worktree : null;
}
+21
View File
@@ -118,4 +118,25 @@ describe('GitWorktreeWidget', () => {
expect(render()).toBe('𖠰 no git');
});
it('should render with bare repo worktree', () => {
mockExecSync.mockReturnValueOnce('true\n');
mockExecSync.mockReturnValueOnce('/some/path/worktrees/some-worktree');
expect(render()).toBe('𖠰 some-worktree');
});
it('should render with nested bare repo worktree', () => {
mockExecSync.mockReturnValueOnce('true\n');
mockExecSync.mockReturnValueOnce('/some/path/worktrees/some-dir/some-worktree');
expect(render()).toBe('𖠰 some-dir/some-worktree');
});
it('should handle windows bare repo git-dir paths', () => {
mockExecSync.mockReturnValueOnce('true\n');
mockExecSync.mockReturnValueOnce('C:\\repo\\worktrees\\some-worktree');
expect(render()).toBe('𖠰 some-worktree');
});
});