Skip to content

Commit a112091

Browse files
authored
Merge pull request #153 from usadamasa/refactor-bare
refactor: extract test helpers in e2e/bare_test.go
2 parents 09539fd + 357c092 commit a112091

3 files changed

Lines changed: 72 additions & 125 deletions

File tree

e2e/bare_test.go

Lines changed: 24 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
package e2e
88

99
import (
10-
"bytes"
1110
"encoding/json"
1211
"os"
1312
"path/filepath"
@@ -97,11 +96,7 @@ func TestE2E_BareRepository(t *testing.T) {
9796

9897
// Create a worktree from the bare repo using raw git command
9998
wtPath := filepath.Join(bareRepo.ParentDir(), "wt-main")
100-
cmd := exec.Command("git", "-C", bareRepo.Root, "worktree", "add", wtPath, "main")
101-
if out, err := cmd.CombinedOutput(); err != nil {
102-
t.Fatalf("git worktree add failed: %v\noutput: %s", err, out)
103-
}
104-
t.Cleanup(func() { os.RemoveAll(wtPath) })
99+
addRawWorktreeFromBare(t, bareRepo.Root, wtPath, "main")
105100

106101
// Run git-wt with no arguments (list mode) inside the worktree
107102
out, err := runGitWt(t, binPath, wtPath)
@@ -123,11 +118,7 @@ func TestE2E_BareRepository(t *testing.T) {
123118

124119
// Create a worktree from the bare repo
125120
wtPath := filepath.Join(bareRepo.ParentDir(), "wt-main")
126-
cmd := exec.Command("git", "-C", bareRepo.Root, "worktree", "add", wtPath, "main")
127-
if out, err := cmd.CombinedOutput(); err != nil {
128-
t.Fatalf("git worktree add failed: %v\noutput: %s", err, out)
129-
}
130-
t.Cleanup(func() { os.RemoveAll(wtPath) })
121+
addRawWorktreeFromBare(t, bareRepo.Root, wtPath, "main")
131122

132123
// Run git-wt from the worktree - worktree entry should have * marker, bare entry should not
133124
out, err := runGitWt(t, binPath, wtPath)
@@ -204,13 +195,7 @@ func TestE2E_BareRepository(t *testing.T) {
204195
t.Fatalf("expected success for bare repository add, but got error: %v\nstdout: %s", err, stdout)
205196
}
206197
wtPath := worktreePath(stdout)
207-
if wtPath == "" {
208-
t.Fatal("expected worktree path in stdout, got empty")
209-
}
210-
// Verify the worktree directory exists
211-
if _, err := os.Stat(wtPath); os.IsNotExist(err) {
212-
t.Fatalf("worktree directory should exist at %s", wtPath)
213-
}
198+
assertWorktreeExists(t, wtPath)
214199
})
215200

216201
t.Run("direct_bare_add_existing_branch", func(t *testing.T) {
@@ -229,12 +214,7 @@ func TestE2E_BareRepository(t *testing.T) {
229214
t.Fatalf("expected success for bare repository add with existing branch, but got error: %v\nstdout: %s", err, stdout)
230215
}
231216
wtPath := worktreePath(stdout)
232-
if wtPath == "" {
233-
t.Fatal("expected worktree path in stdout, got empty")
234-
}
235-
if _, err := os.Stat(wtPath); os.IsNotExist(err) {
236-
t.Fatalf("worktree directory should exist at %s", wtPath)
237-
}
217+
assertWorktreeExists(t, wtPath)
238218
})
239219

240220
t.Run("direct_bare_add_with_start_point", func(t *testing.T) {
@@ -247,12 +227,7 @@ func TestE2E_BareRepository(t *testing.T) {
247227
t.Fatalf("expected success for bare repository add with start-point, but got error: %v\nstdout: %s", err, stdout)
248228
}
249229
wtPath := worktreePath(stdout)
250-
if wtPath == "" {
251-
t.Fatal("expected worktree path in stdout, got empty")
252-
}
253-
if _, err := os.Stat(wtPath); os.IsNotExist(err) {
254-
t.Fatalf("worktree directory should exist at %s", wtPath)
255-
}
230+
assertWorktreeExists(t, wtPath)
256231
})
257232

258233
t.Run("direct_bare_switch_existing", func(t *testing.T) {
@@ -287,12 +262,7 @@ func TestE2E_BareRepository(t *testing.T) {
287262
t.Fatalf("expected success for dotgit bare repository add, but got error: %v\nstdout: %s", err, stdout)
288263
}
289264
wtPath := worktreePath(stdout)
290-
if wtPath == "" {
291-
t.Fatal("expected worktree path in stdout, got empty")
292-
}
293-
if _, err := os.Stat(wtPath); os.IsNotExist(err) {
294-
t.Fatalf("worktree directory should exist at %s", wtPath)
295-
}
265+
assertWorktreeExists(t, wtPath)
296266
})
297267

298268
// --- Tests running inside a worktree created from a bare repository ---
@@ -303,11 +273,7 @@ func TestE2E_BareRepository(t *testing.T) {
303273

304274
// Create a worktree from the bare repo
305275
wtPath := filepath.Join(bareRepo.ParentDir(), "wt-main")
306-
cmd := exec.Command("git", "-C", bareRepo.Root, "worktree", "add", wtPath, "main")
307-
if out, err := cmd.CombinedOutput(); err != nil {
308-
t.Fatalf("git worktree add failed: %v\noutput: %s", err, out)
309-
}
310-
t.Cleanup(func() { os.RemoveAll(wtPath) })
276+
addRawWorktreeFromBare(t, bareRepo.Root, wtPath, "main")
311277

312278
// Run git-wt with a branch name (add mode) inside the worktree
313279
// Should succeed: bare-derived worktrees support add
@@ -316,12 +282,7 @@ func TestE2E_BareRepository(t *testing.T) {
316282
t.Fatalf("expected success for worktree from bare repo add, but got error: %v\nstdout: %s", err, stdout)
317283
}
318284
newWtPath := worktreePath(stdout)
319-
if newWtPath == "" {
320-
t.Fatal("expected worktree path in stdout, got empty")
321-
}
322-
if _, err := os.Stat(newWtPath); os.IsNotExist(err) {
323-
t.Fatalf("new worktree directory should exist at %s", newWtPath)
324-
}
285+
assertWorktreeExists(t, newWtPath)
325286
})
326287

327288
t.Run("worktree_from_bare_add_copies_files", func(t *testing.T) {
@@ -330,11 +291,7 @@ func TestE2E_BareRepository(t *testing.T) {
330291

331292
// Create a worktree from the bare repo
332293
wtPath := filepath.Join(bareRepo.ParentDir(), "wt-main")
333-
cmd := exec.Command("git", "-C", bareRepo.Root, "worktree", "add", wtPath, "main")
334-
if out, err := cmd.CombinedOutput(); err != nil {
335-
t.Fatalf("git worktree add failed: %v\noutput: %s", err, out)
336-
}
337-
t.Cleanup(func() { os.RemoveAll(wtPath) })
294+
addRawWorktreeFromBare(t, bareRepo.Root, wtPath, "main")
338295

339296
// Create an untracked file in the source worktree to test copy behavior
340297
if err := os.WriteFile(filepath.Join(wtPath, "untracked.txt"), []byte("test content\n"), 0600); err != nil {
@@ -375,12 +332,7 @@ func TestE2E_BareRepository(t *testing.T) {
375332
t.Fatalf("failed to create worktree B from worktree A: %v\nstdout: %s", err, stdoutB)
376333
}
377334
wtPathB := worktreePath(stdoutB)
378-
if wtPathB == "" {
379-
t.Fatal("expected worktree B path in stdout, got empty")
380-
}
381-
if _, err := os.Stat(wtPathB); os.IsNotExist(err) {
382-
t.Fatalf("worktree B directory should exist at %s", wtPathB)
383-
}
335+
assertWorktreeExists(t, wtPathB)
384336

385337
// Step 3: Switch back to A from bare root (should return existing path)
386338
stdoutSwitch, _, err := runGitWtStdout(t, binPath, bareRepo.Root, "feature-a")
@@ -414,9 +366,7 @@ func TestE2E_BareDelete(t *testing.T) {
414366
}
415367

416368
// Worktree should be deleted
417-
if _, err := os.Stat(wtPath); !os.IsNotExist(err) {
418-
t.Error("worktree should have been deleted")
419-
}
369+
assertWorktreeDeleted(t, wtPath)
420370
if !strings.Contains(out, "Deleted") {
421371
t.Errorf("output should contain 'Deleted', got: %s", out)
422372
}
@@ -435,9 +385,7 @@ func TestE2E_BareDelete(t *testing.T) {
435385
}
436386

437387
// Worktree should be deleted
438-
if _, err := os.Stat(wtPath); !os.IsNotExist(err) {
439-
t.Error("worktree should have been force deleted")
440-
}
388+
assertWorktreeDeleted(t, wtPath)
441389
})
442390

443391
// --- Error: attempting to delete bare entry itself ---
@@ -485,9 +433,7 @@ func TestE2E_BareDelete(t *testing.T) {
485433
}
486434

487435
// Worktree A should be deleted
488-
if _, err := os.Stat(wtPathA); !os.IsNotExist(err) {
489-
t.Error("worktree A should have been deleted")
490-
}
436+
assertWorktreeDeleted(t, wtPathA)
491437
// Worktree B should still exist
492438
if _, err := os.Stat(wtPathB); os.IsNotExist(err) {
493439
t.Error("worktree B should still exist")
@@ -500,23 +446,16 @@ func TestE2E_BareDelete(t *testing.T) {
500446
wtPath := createBareWorktree(t, binPath, bareRepo.Root, "current-del")
501447

502448
// Delete current worktree from inside it (with shell integration)
503-
cmd := exec.Command(binPath, "-D", "current-del")
504-
cmd.Dir = wtPath
505-
cmd.Env = append(os.Environ(), "GIT_WT_SHELL_INTEGRATION=1")
506-
var stdoutBuf, stderrBuf bytes.Buffer
507-
cmd.Stdout = &stdoutBuf
508-
cmd.Stderr = &stderrBuf
509-
if err := cmd.Run(); err != nil {
510-
t.Fatalf("git-wt -D failed: %v\nstderr: %s", err, stderrBuf.String())
449+
stdout, stderr, err := runGitWtWithShellIntegration(t, binPath, wtPath, "-D", "current-del")
450+
if err != nil {
451+
t.Fatalf("git-wt -D failed: %v\nstderr: %s", err, stderr)
511452
}
512453

513454
// Worktree should be deleted
514-
if _, err := os.Stat(wtPath); !os.IsNotExist(err) {
515-
t.Error("worktree should have been deleted")
516-
}
455+
assertWorktreeDeleted(t, wtPath)
517456

518457
// Shell integration should output bare root path
519-
assertLastLine(t, stdoutBuf.String(), bareRepo.Root)
458+
assertLastLine(t, stdout, bareRepo.Root)
520459
})
521460

522461
// --- Delete last worktree, cd back to bare root ---
@@ -527,23 +466,16 @@ func TestE2E_BareDelete(t *testing.T) {
527466
wtPath := createBareWorktree(t, binPath, bareRepo.Root, "only-wt")
528467

529468
// Delete from inside the worktree (with shell integration)
530-
cmd := exec.Command(binPath, "-D", "only-wt")
531-
cmd.Dir = wtPath
532-
cmd.Env = append(os.Environ(), "GIT_WT_SHELL_INTEGRATION=1")
533-
var stdoutBuf, stderrBuf bytes.Buffer
534-
cmd.Stdout = &stdoutBuf
535-
cmd.Stderr = &stderrBuf
536-
if err := cmd.Run(); err != nil {
537-
t.Fatalf("git-wt -D failed: %v\nstderr: %s", err, stderrBuf.String())
469+
stdout, stderr, err := runGitWtWithShellIntegration(t, binPath, wtPath, "-D", "only-wt")
470+
if err != nil {
471+
t.Fatalf("git-wt -D failed: %v\nstderr: %s", err, stderr)
538472
}
539473

540474
// Worktree should be deleted
541-
if _, err := os.Stat(wtPath); !os.IsNotExist(err) {
542-
t.Error("worktree should have been deleted")
543-
}
475+
assertWorktreeDeleted(t, wtPath)
544476

545477
// Shell integration should output bare root path
546-
assertLastLine(t, stdoutBuf.String(), bareRepo.Root)
478+
assertLastLine(t, stdout, bareRepo.Root)
547479
})
548480

549481
// --- Error: modified files ---
@@ -587,8 +519,6 @@ func TestE2E_BareDelete(t *testing.T) {
587519
}
588520

589521
// Worktree should be deleted
590-
if _, err := os.Stat(wtPath); !os.IsNotExist(err) {
591-
t.Error("worktree should have been deleted")
592-
}
522+
assertWorktreeDeleted(t, wtPath)
593523
})
594524
}

e2e/helper_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
// - runGitWt: executes git-wt and returns combined output
66
// - runGitWtStdout: executes git-wt and returns stdout/stderr separately
77
// - runGitWtWithStderr: executes git-wt with isolated HOME and returns stdout/stderr separately
8+
// - runGitWtWithShellIntegration: executes git-wt with GIT_WT_SHELL_INTEGRATION=1
89
// - worktreePath: extracts worktree path from command output
10+
// - addRawWorktreeFromBare: creates a worktree via raw git command
11+
// - assertWorktreeExists: asserts that a worktree directory exists
12+
// - assertWorktreeDeleted: asserts that a worktree directory has been removed
913
package e2e
1014

1115
import (
@@ -136,6 +140,50 @@ func commitUnmergedChange(t *testing.T, dir string) {
136140
}
137141
}
138142

143+
// addRawWorktreeFromBare creates a worktree from a bare repository using a raw
144+
// git worktree add command and registers cleanup to remove it.
145+
func addRawWorktreeFromBare(t *testing.T, root, wtPath, branch string) {
146+
t.Helper()
147+
cmd := exec.Command("git", "-C", root, "worktree", "add", wtPath, branch)
148+
if out, err := cmd.CombinedOutput(); err != nil {
149+
t.Fatalf("git worktree add failed: %v\noutput: %s", err, out)
150+
}
151+
t.Cleanup(func() { os.RemoveAll(wtPath) })
152+
}
153+
154+
// assertWorktreeExists asserts that path is non-empty and the directory exists.
155+
func assertWorktreeExists(t *testing.T, path string) {
156+
t.Helper()
157+
if path == "" {
158+
t.Fatal("expected worktree path in stdout, got empty")
159+
}
160+
if _, err := os.Stat(path); os.IsNotExist(err) {
161+
t.Fatalf("worktree directory should exist at %s", path)
162+
}
163+
}
164+
165+
// assertWorktreeDeleted asserts that the worktree directory no longer exists.
166+
func assertWorktreeDeleted(t *testing.T, path string) {
167+
t.Helper()
168+
if _, err := os.Stat(path); !os.IsNotExist(err) {
169+
t.Errorf("worktree directory should have been deleted: %s", path)
170+
}
171+
}
172+
173+
// runGitWtWithShellIntegration runs git-wt with GIT_WT_SHELL_INTEGRATION=1
174+
// and returns stdout, stderr, and the error.
175+
func runGitWtWithShellIntegration(t *testing.T, binPath, dir string, args ...string) (string, string, error) {
176+
t.Helper()
177+
cmd := exec.Command(binPath, args...)
178+
cmd.Dir = dir
179+
cmd.Env = append(os.Environ(), "GIT_WT_SHELL_INTEGRATION=1")
180+
var stdoutBuf, stderrBuf bytes.Buffer
181+
cmd.Stdout = &stdoutBuf
182+
cmd.Stderr = &stderrBuf
183+
err := cmd.Run()
184+
return stdoutBuf.String(), stderrBuf.String(), err
185+
}
186+
139187
// assertLastLine checks that the last line of output matches the expected string.
140188
func assertLastLine(t *testing.T, output, expected string) {
141189
t.Helper()

internal/git/repo_context.go

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -102,27 +102,6 @@ func IsBareRepository(ctx context.Context) (bool, error) {
102102
return rc.bare, nil
103103
}
104104

105-
106-
// IsNormalMain reports whether the current directory is the main working tree
107-
// of a normal (non-bare) repository.
108-
func IsNormalMain(ctx context.Context) (bool, error) {
109-
rc, err := DetectRepoContext(ctx)
110-
if err != nil {
111-
return false, err
112-
}
113-
return !rc.bare && !rc.worktree, nil
114-
}
115-
116-
// IsNormalWorktree reports whether the current directory is a linked worktree
117-
// of a normal (non-bare) repository.
118-
func IsNormalWorktree(ctx context.Context) (bool, error) {
119-
rc, err := DetectRepoContext(ctx)
120-
if err != nil {
121-
return false, err
122-
}
123-
return !rc.bare && rc.worktree, nil
124-
}
125-
126105
// IsBareRoot reports whether the current directory is a bare repository root
127106
// (no working tree).
128107
func IsBareRoot(ctx context.Context) (bool, error) {
@@ -133,16 +112,6 @@ func IsBareRoot(ctx context.Context) (bool, error) {
133112
return rc.bare && !rc.worktree, nil
134113
}
135114

136-
// IsBareWorktree reports whether the current directory is a linked worktree
137-
// created from a bare repository.
138-
func IsBareWorktree(ctx context.Context) (bool, error) {
139-
rc, err := DetectRepoContext(ctx)
140-
if err != nil {
141-
return false, err
142-
}
143-
return rc.bare && rc.worktree, nil
144-
}
145-
146115
// gitDirs returns the git-dir and git-common-dir for the current repository.
147116
// Both paths are returned as absolute paths resolved by git.
148117
// git-dir points to the .git directory (or worktrees/X subdirectory for linked worktrees).

0 commit comments

Comments
 (0)