Skip to content

Commit 74014b4

Browse files
lucasmodrichclaude
andcommitted
fix(tests): resolve test failures in CI environment
- Fix branch_test.go to dynamically detect default branch (main/master) instead of hardcoding branch names - Fix worktree.go WorktreeAdd implementation to correctly pass branch argument in both track=true and track=false modes - Fix worktree_test.go to use proper bare repo + worktree setup that matches production workflow - Update .gitignore to exclude build artifacts and coverage files These changes address test failures in GitHub Actions CI where git creates different default branch names depending on version. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 366b340 commit 74014b4

File tree

4 files changed

+94
-65
lines changed

4 files changed

+94
-65
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
node_modules/
1+
node_modules/coverage.txt
2+
git-worktree-manager
3+
gwtm

internal/git/branch_test.go

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ package git
33
import (
44
"os"
55
"path/filepath"
6+
"strings"
67
"testing"
78
)
89

9-
func setupBranchTestRepo(t *testing.T) (*Client, string) {
10+
func setupBranchTestRepo(t *testing.T) (*Client, string, string) {
1011
tmpDir := t.TempDir()
1112

1213
client := NewClient(tmpDir)
@@ -20,11 +21,20 @@ func setupBranchTestRepo(t *testing.T) (*Client, string) {
2021
client.ExecGit("add", "README.md")
2122
client.ExecGit("commit", "-m", "Initial commit")
2223

23-
return client, tmpDir
24+
// Detect which default branch was created (main or master)
25+
output, _, _ := client.ExecGit("branch", "--show-current")
26+
defaultBranch := strings.TrimSpace(output)
27+
if defaultBranch == "" {
28+
// Fallback for older git versions
29+
output, _, _ = client.ExecGit("rev-parse", "--abbrev-ref", "HEAD")
30+
defaultBranch = strings.TrimSpace(output)
31+
}
32+
33+
return client, tmpDir, defaultBranch
2434
}
2535

2636
func TestBranchExists(t *testing.T) {
27-
client, _ := setupBranchTestRepo(t)
37+
client, _, defaultBranch := setupBranchTestRepo(t)
2838

2939
tests := []struct {
3040
name string
@@ -34,15 +44,8 @@ func TestBranchExists(t *testing.T) {
3444
want bool
3545
}{
3646
{
37-
name: "main branch exists locally",
38-
branch: "main",
39-
remote: false,
40-
setup: func() {},
41-
want: true,
42-
},
43-
{
44-
name: "master branch exists locally",
45-
branch: "master",
47+
name: "default branch exists locally",
48+
branch: defaultBranch,
4649
remote: false,
4750
setup: func() {},
4851
want: true,
@@ -78,7 +81,7 @@ func TestBranchExists(t *testing.T) {
7881
}
7982

8083
func TestCreateBranch(t *testing.T) {
81-
client, _ := setupBranchTestRepo(t)
84+
client, _, defaultBranch := setupBranchTestRepo(t)
8285

8386
tests := []struct {
8487
name string
@@ -87,15 +90,9 @@ func TestCreateBranch(t *testing.T) {
8790
wantErr bool
8891
}{
8992
{
90-
name: "create branch from main",
93+
name: "create branch from default",
9194
branchName: "feature/new",
92-
baseBranch: "main",
93-
wantErr: false,
94-
},
95-
{
96-
name: "create branch from master",
97-
branchName: "feature/another",
98-
baseBranch: "master",
95+
baseBranch: defaultBranch,
9996
wantErr: false,
10097
},
10198
{
@@ -124,10 +121,10 @@ func TestCreateBranch(t *testing.T) {
124121
}
125122

126123
func TestDeleteBranch(t *testing.T) {
127-
client, _ := setupBranchTestRepo(t)
124+
client, _, defaultBranch := setupBranchTestRepo(t)
128125

129126
// Create a branch first
130-
client.CreateBranch("feature/to-delete", "main")
127+
client.CreateBranch("feature/to-delete", defaultBranch)
131128

132129
tests := []struct {
133130
name string
@@ -161,7 +158,7 @@ func TestDeleteBranch(t *testing.T) {
161158
}
162159

163160
func TestDeleteRemoteBranch(t *testing.T) {
164-
client, _ := setupBranchTestRepo(t)
161+
client, _, _ := setupBranchTestRepo(t)
165162

166163
tests := []struct {
167164
name string

internal/git/worktree.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,11 @@ func (c *Client) WorktreeAdd(path, branch string, track bool) error {
1010
args := []string{"worktree", "add"}
1111

1212
if track {
13-
args = append(args, "-b", branch)
14-
}
15-
16-
args = append(args, path)
17-
18-
if track {
19-
args = append(args, branch)
13+
// Create new branch: git worktree add -b <branch> <path>
14+
args = append(args, "-b", branch, path)
15+
} else {
16+
// Checkout existing branch: git worktree add <path> <branch>
17+
args = append(args, path, branch)
2018
}
2119

2220
_, stderr, err := c.ExecGit(args...)

internal/git/worktree_test.go

Lines changed: 65 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,51 @@ import (
77
"testing"
88
)
99

10-
func setupTestRepo(t *testing.T) (*Client, string) {
10+
func setupTestRepo(t *testing.T) (*Client, string, string) {
1111
tmpDir := t.TempDir()
1212

13-
// Create a bare repo
14-
bareDir := filepath.Join(tmpDir, ".bare")
15-
os.MkdirAll(bareDir, 0755)
16-
17-
client := NewClient(bareDir)
18-
client.ExecGit("init", "--bare")
13+
// Step 1: Create a temporary normal repo to get initial content
14+
setupDir := filepath.Join(tmpDir, "setup")
15+
os.MkdirAll(setupDir, 0755)
1916

20-
// Set up a main worktree with an initial commit
21-
mainDir := filepath.Join(tmpDir, "main")
22-
os.MkdirAll(mainDir, 0755)
23-
24-
mainClient := NewClient(mainDir)
25-
mainClient.ExecGit("init")
26-
mainClient.ExecGit("config", "user.name", "Test User")
27-
mainClient.ExecGit("config", "user.email", "[email protected]")
17+
setupClient := NewClient(setupDir)
18+
setupClient.ExecGit("init")
19+
setupClient.ExecGit("config", "user.name", "Test User")
20+
setupClient.ExecGit("config", "user.email", "[email protected]")
2821

2922
// Create initial commit
30-
testFile := filepath.Join(mainDir, "README.md")
23+
testFile := filepath.Join(setupDir, "README.md")
3124
os.WriteFile(testFile, []byte("# Test Repo\n"), 0644)
32-
mainClient.ExecGit("add", "README.md")
33-
mainClient.ExecGit("commit", "-m", "Initial commit")
25+
setupClient.ExecGit("add", "README.md")
26+
setupClient.ExecGit("commit", "-m", "Initial commit")
27+
28+
// Detect default branch
29+
output, _, _ := setupClient.ExecGit("branch", "--show-current")
30+
defaultBranch := strings.TrimSpace(output)
31+
if defaultBranch == "" {
32+
output, _, _ = setupClient.ExecGit("rev-parse", "--abbrev-ref", "HEAD")
33+
defaultBranch = strings.TrimSpace(output)
34+
}
3435

35-
return NewClient(tmpDir), tmpDir
36+
// Step 2: Create bare repo from the setup repo
37+
bareDir := filepath.Join(tmpDir, ".bare")
38+
setupClient.ExecGit("clone", "--bare", setupDir, bareDir)
39+
40+
// Step 3: Create first worktree from bare repo
41+
mainDir := filepath.Join(tmpDir, defaultBranch)
42+
bareClient := NewClient(bareDir)
43+
bareClient.ExecGit("worktree", "add", mainDir, defaultBranch)
44+
45+
// Return client pointing to the project root (tmpDir) which contains .bare/
46+
return NewClient(tmpDir), tmpDir, defaultBranch
3647
}
3748

3849
func TestWorktreeAdd(t *testing.T) {
39-
client, tmpDir := setupTestRepo(t)
50+
_, tmpDir, defaultBranch := setupTestRepo(t)
51+
52+
// Use bare repo client for worktree commands
53+
bareDir := filepath.Join(tmpDir, ".bare")
54+
bareClient := NewClient(bareDir)
4055

4156
tests := []struct {
4257
name string
@@ -49,14 +64,17 @@ func TestWorktreeAdd(t *testing.T) {
4964
name: "add new worktree",
5065
path: filepath.Join(tmpDir, "feature"),
5166
branch: "feature/test",
52-
track: true,
67+
track: false, // Match production usage: branch pre-created, track=false
5368
wantErr: false,
5469
},
5570
}
5671

5772
for _, tt := range tests {
5873
t.Run(tt.name, func(t *testing.T) {
59-
err := client.WorktreeAdd(tt.path, tt.branch, tt.track)
74+
// Pre-create the branch (matches production workflow in branch.go)
75+
bareClient.ExecGit("branch", tt.branch, defaultBranch)
76+
77+
err := bareClient.WorktreeAdd(tt.path, tt.branch, tt.track)
6078
if (err != nil) != tt.wantErr {
6179
t.Errorf("WorktreeAdd() error = %v, wantErr %v", err, tt.wantErr)
6280
}
@@ -65,13 +83,18 @@ func TestWorktreeAdd(t *testing.T) {
6583
}
6684

6785
func TestWorktreeList(t *testing.T) {
68-
client, tmpDir := setupTestRepo(t)
86+
_, tmpDir, defaultBranch := setupTestRepo(t)
87+
88+
// Use bare repo client
89+
bareDir := filepath.Join(tmpDir, ".bare")
90+
bareClient := NewClient(bareDir)
6991

70-
// Add a worktree first
92+
// Add a worktree first (match production workflow: create branch, then worktree)
7193
featurePath := filepath.Join(tmpDir, "feature")
72-
client.WorktreeAdd(featurePath, "feature/test", true)
94+
bareClient.ExecGit("branch", "feature/test", defaultBranch)
95+
bareClient.WorktreeAdd(featurePath, "feature/test", false)
7396

74-
worktrees, err := client.WorktreeList()
97+
worktrees, err := bareClient.WorktreeList()
7598
if err != nil {
7699
t.Fatalf("WorktreeList() error = %v", err)
77100
}
@@ -94,20 +117,25 @@ func TestWorktreeList(t *testing.T) {
94117
}
95118

96119
func TestWorktreeRemove(t *testing.T) {
97-
client, tmpDir := setupTestRepo(t)
120+
_, tmpDir, defaultBranch := setupTestRepo(t)
98121

99-
// Add a worktree first
122+
// Use bare repo client
123+
bareDir := filepath.Join(tmpDir, ".bare")
124+
bareClient := NewClient(bareDir)
125+
126+
// Add a worktree first (match production workflow: create branch, then worktree)
100127
featurePath := filepath.Join(tmpDir, "feature")
101-
client.WorktreeAdd(featurePath, "feature/test", true)
128+
bareClient.ExecGit("branch", "feature/test", defaultBranch)
129+
bareClient.WorktreeAdd(featurePath, "feature/test", false)
102130

103131
// Now remove it
104-
err := client.WorktreeRemove(featurePath)
132+
err := bareClient.WorktreeRemove(featurePath)
105133
if err != nil {
106134
t.Errorf("WorktreeRemove() error = %v", err)
107135
}
108136

109137
// Verify it's removed
110-
worktrees, _ := client.WorktreeList()
138+
worktrees, _ := bareClient.WorktreeList()
111139
for _, wt := range worktrees {
112140
if strings.Contains(wt, "feature") {
113141
t.Error("WorktreeRemove() did not remove the worktree")
@@ -116,10 +144,14 @@ func TestWorktreeRemove(t *testing.T) {
116144
}
117145

118146
func TestWorktreePrune(t *testing.T) {
119-
client, _ := setupTestRepo(t)
147+
_, tmpDir, _ := setupTestRepo(t)
148+
149+
// Use bare repo client
150+
bareDir := filepath.Join(tmpDir, ".bare")
151+
bareClient := NewClient(bareDir)
120152

121153
// Prune should not error even if nothing to prune
122-
err := client.WorktreePrune()
154+
err := bareClient.WorktreePrune()
123155
if err != nil {
124156
t.Errorf("WorktreePrune() error = %v", err)
125157
}

0 commit comments

Comments
 (0)