Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d40ef9a
Add `CmdFromDir()`, but maybe we could just accept another param in `…
jesseleite Nov 3, 2024
d2e2cd2
Add `GitMainWorktree()`. (See `git worktree —help` for `list` command.)
jesseleite Nov 3, 2024
e3f2f5a
This currently gets root sesh name. Should it output path instead for…
jesseleite Nov 3, 2024
ce9eefb
Output home shortened path to match Josh’s current output style for f…
jesseleite Nov 3, 2024
90914c8
Remove `CmdFromDir` func in favor of `git -C`.
jesseleite Nov 5, 2024
bf4b4cc
Update mocks.
jesseleite Nov 5, 2024
a34c6bc
Add git worktree list test coverage.
jesseleite Nov 5, 2024
231f1a7
This was never used/referenced anywhere. (And we’re about to refactor…
jesseleite Nov 6, 2024
996c489
Refactor all `.bare`, `—shot-top-level`, `—git-common-dir`, etc. chec…
jesseleite Nov 7, 2024
b048910
Update mocks.
jesseleite Nov 7, 2024
420f9c0
Update test coverage.
jesseleite Nov 7, 2024
b056333
Simplify. This wrapper func seems redundant now.
jesseleite Nov 7, 2024
d5fed1e
Make test example a bit more realistic.
jesseleite Nov 8, 2024
d73fcb6
Merge branch 'main' of github.com:joshmedeski/sesh into improved-sesh…
jesseleite Mar 8, 2025
ad58dd7
Add coverage for `.bare` directory convention.
jesseleite Mar 9, 2025
0a5c1c0
Pass test for `.bare` support.
jesseleite Mar 9, 2025
c8657c2
Handle err.
jesseleite Apr 18, 2025
b746577
Handle empty fields output.
jesseleite Apr 18, 2025
659aa53
Simplify git package to just run low level git commands.
jesseleite Apr 18, 2025
9306b05
Move worktree name parsing logic into namer, as requested.
jesseleite Apr 18, 2025
077a98c
Revert this stuff.
jesseleite Apr 18, 2025
c8e2aff
Add TODO.
jesseleite Apr 18, 2025
f8cd3c5
Extract function and add test coverage.
jesseleite Apr 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions dir/dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,12 @@ func (d *RealDir) RootDir(path string) (hasRootDir bool, absPath string) {
}

func gitBareRootDir(d *RealDir, path string) (hasRootDir bool, absPath string) {
// TODO: Refactor from here...
isGitBare, commonDir, _ := d.git.GitCommonDir(path)
if isGitBare && strings.HasSuffix(commonDir, "/.bare") {
topLevelDir := strings.TrimSuffix(commonDir, "/.bare")
// ...to here. (We'll want to use the name parsing logic you suggested I move to the namer.)

relativePath := strings.TrimPrefix(path, topLevelDir)
firstDir := strings.Split(relativePath, string("/"))[1]
name, err := d.path.Abs(topLevelDir + "/" + firstDir)
Expand Down
6 changes: 3 additions & 3 deletions git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

type Git interface {
ShowTopLevel(name string) (bool, string, error)
GitCommonDir(name string) (bool, string, error)
WorkTreeList(name string) (bool, string, error)
Clone(url string, cmdDir string, dir string) (string, error)
}

Expand All @@ -26,8 +26,8 @@ func (g *RealGit) ShowTopLevel(path string) (bool, string, error) {
return true, out, nil
}

func (g *RealGit) GitCommonDir(path string) (bool, string, error) {
out, err := g.shell.Cmd("git", "-C", path, "rev-parse", "--git-common-dir")
func (g *RealGit) WorkTreeList(path string) (bool, string, error) {
out, err := g.shell.Cmd("git", "-C", path, "worktree", "list")
if err != nil {
return false, "", err
}
Expand Down
85 changes: 11 additions & 74 deletions git/mock_Git.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions namer/bare.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package namer

import (
"errors"
"strings"
)

func parseBareFromWorkTreeList(worktreeList string) (string, error) {
fields := strings.Fields(worktreeList)
if len(fields) == 0 {
return "", errors.New("error parsing git worktree fields")
}

bareRoot := fields[0]
if strings.HasSuffix(bareRoot, "/.bare") {
bareRoot = strings.TrimSuffix(bareRoot, "/.bare")
}

return bareRoot, nil
}
38 changes: 38 additions & 0 deletions namer/bare_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package namer

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestGitRoot(t *testing.T) {
t.Run("run should find worktree root", func(t *testing.T) {
workTreeList := `
/Users/hansolo/code/project/sesh (bare)
/Users/hansolo/code/project/sesh/main ba04ca494 [5.x]
`
bareRoot, err := parseBareFromWorkTreeList(workTreeList)
assert.Nil(t, err)
assert.Equal(t, "/Users/hansolo/code/project/sesh", bareRoot)
})

t.Run("run should find worktree root with .bare folder convention", func(t *testing.T) {
workTreeList := `
/Users/hansolo/code/project/sesh/.bare (bare)
/Users/hansolo/code/project/sesh/main ba04ca494 [5.x]
`
bareRoot, err := parseBareFromWorkTreeList(workTreeList)
assert.Nil(t, err)
assert.Equal(t, "/Users/hansolo/code/project/sesh", bareRoot)
})

t.Run("run should find non-worktree root", func(t *testing.T) {
workTreeList := `
/Users/hansolo/.dotfiles ba04ca494 [5.x]
`
root, err := parseBareFromWorkTreeList(workTreeList)
assert.Nil(t, err)
assert.Equal(t, "/Users/hansolo/.dotfiles", root)
})
}
27 changes: 16 additions & 11 deletions namer/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import (
)

func gitBareRootName(n *RealNamer, path string) (string, error) {
isGit, commonDir, _ := n.git.GitCommonDir(path)
if isGit && strings.HasSuffix(commonDir, "/.bare") {
topLevelDir := strings.TrimSuffix(commonDir, "/.bare")
name, err := n.home.ShortenHome(topLevelDir)
isGit, worktreeList, _ := n.git.WorkTreeList(path)
if isGit && worktreeList != "" {
bareRoot, err := parseBareFromWorkTreeList(worktreeList)
if err != nil {
return "", err
}
name, err := n.home.ShortenHome(bareRoot)
if err != nil {
return "", fmt.Errorf("couldn't shorten path: %q", err)
}
Expand All @@ -21,13 +24,15 @@ func gitBareRootName(n *RealNamer, path string) (string, error) {

// Gets the name from a git bare repository
func gitBareName(n *RealNamer, path string) (string, error) {
var name string
isGit, commonDir, _ := n.git.GitCommonDir(path)
if isGit && strings.HasSuffix(commonDir, "/.bare") {
topLevelDir := strings.TrimSuffix(commonDir, "/.bare")
relativePath := strings.TrimPrefix(path, topLevelDir)
baseDir := n.pathwrap.Base(topLevelDir)
name = baseDir + relativePath
isGit, worktreeList, _ := n.git.WorkTreeList(path)
if isGit && worktreeList != "" {
bareRoot, err := parseBareFromWorkTreeList(worktreeList)
if err != nil {
return "", err
}
relativePath := strings.TrimPrefix(path, bareRoot)
baseDir := n.pathwrap.Base(bareRoot)
name := baseDir + relativePath
return name, nil
} else {
return "", nil
Expand Down
12 changes: 6 additions & 6 deletions namer/namer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func TestFromPath(t *testing.T) {
t.Run("name for git repo", func(t *testing.T) {
mockPathwrap.On("EvalSymlinks", "/Users/josh/config/dotfiles/.config/neovim").Return("/Users/josh/config/dotfiles/.config/neovim", nil)
mockGit.On("ShowTopLevel", "/Users/josh/config/dotfiles/.config/neovim").Return(true, "/Users/josh/config/dotfiles", nil)
mockGit.On("GitCommonDir", "/Users/josh/config/dotfiles/.config/neovim").Return(true, "", nil)
// mockGit.On("GitCommonDir", "/Users/josh/config/dotfiles/.config/neovim").Return(true, "", nil)
mockPathwrap.On("Base", "/Users/josh/config/dotfiles").Return("dotfiles")
name, _ := n.Name("/Users/josh/config/dotfiles/.config/neovim")
assert.Equal(t, "dotfiles/_config/neovim", name)
Expand All @@ -29,7 +29,7 @@ func TestFromPath(t *testing.T) {
t.Run("name for git worktree", func(t *testing.T) {
mockPathwrap.On("EvalSymlinks", "/Users/josh/config/sesh/main").Return("/Users/josh/config/sesh/main", nil)
mockGit.On("ShowTopLevel", "/Users/josh/config/sesh/main").Return(true, "/Users/josh/config/sesh/main", nil)
mockGit.On("GitCommonDir", "/Users/josh/config/sesh/main").Return(true, "/Users/josh/config/sesh/.bare", nil)
// mockGit.On("GitCommonDir", "/Users/josh/config/sesh/main").Return(true, "/Users/josh/config/sesh/.bare", nil)
mockPathwrap.On("Base", "/Users/josh/config/sesh").Return("sesh")
name, _ := n.Name("/Users/josh/config/sesh/main")
assert.Equal(t, "sesh/main", name)
Expand All @@ -38,7 +38,7 @@ func TestFromPath(t *testing.T) {
t.Run("returns base on non-git dir", func(t *testing.T) {
mockPathwrap.On("EvalSymlinks", "/Users/josh/.config/neovim").Return("/Users/josh/.config/neovim", nil)
mockGit.On("ShowTopLevel", "/Users/josh/.config/neovim").Return(false, "", fmt.Errorf("not a git repository (or any of the parent"))
mockGit.On("GitCommonDir", "/Users/josh/.config/neovim").Return(false, "", fmt.Errorf("not a git repository (or any of the parent"))
// mockGit.On("GitCommonDir", "/Users/josh/.config/neovim").Return(false, "", fmt.Errorf("not a git repository (or any of the parent"))
mockPathwrap.On("Base", "/Users/josh/.config/neovim").Return("neovim")
name, _ := n.Name("/Users/josh/.config/neovim")
assert.Equal(t, "neovim", name)
Expand All @@ -54,7 +54,7 @@ func TestFromPath(t *testing.T) {
t.Run("name for symlinked file in symlinked git repo", func(t *testing.T) {
mockPathwrap.On("EvalSymlinks", "/Users/josh/d/.c/neovim").Return("/Users/josh/dotfiles/.config/neovim", nil)
mockGit.On("ShowTopLevel", "/Users/josh/dotfiles/.config/neovim").Return(true, "/Users/josh/dotfiles", nil)
mockGit.On("GitCommonDir", "/Users/josh/dotfiles/.config/neovim").Return(true, "", nil)
// mockGit.On("GitCommonDir", "/Users/josh/dotfiles/.config/neovim").Return(true, "", nil)
mockPathwrap.On("Base", "/Users/josh/dotfiles").Return("dotfiles")
name, _ := n.Name("/Users/josh/d/.c/neovim")
assert.Equal(t, "dotfiles/_config/neovim", name)
Expand All @@ -63,7 +63,7 @@ func TestFromPath(t *testing.T) {
t.Run("name for git worktree", func(t *testing.T) {
mockPathwrap.On("EvalSymlinks", "/Users/josh/p/sesh/main").Return("/Users/josh/projects/sesh/main", nil)
mockGit.On("ShowTopLevel", "/Users/josh/projects/sesh/main").Return(true, "/Users/josh/projects/sesh/main", nil)
mockGit.On("GitCommonDir", "/Users/josh/projects/sesh/main").Return(true, "/Users/josh/projects/sesh/.bare", nil)
// mockGit.On("GitCommonDir", "/Users/josh/projects/sesh/main").Return(true, "/Users/josh/projects/sesh/.bare", nil)
mockPathwrap.On("Base", "/Users/josh/projects/sesh").Return("sesh")
name, _ := n.Name("/Users/josh/p/sesh/main")
assert.Equal(t, "sesh/main", name)
Expand All @@ -72,7 +72,7 @@ func TestFromPath(t *testing.T) {
t.Run("returns base on non-git dir", func(t *testing.T) {
mockPathwrap.On("EvalSymlinks", "/Users/josh/c/neovim").Return("/Users/josh/.config/neovim", nil)
mockGit.On("ShowTopLevel", "/Users/josh/.config/neovim").Return(false, "", fmt.Errorf("not a git repository (or any of the parent"))
mockGit.On("GitCommonDir", "/Users/josh/.config/neovim").Return(false, "", fmt.Errorf("not a git repository (or any of the parent"))
// mockGit.On("GitCommonDir", "/Users/josh/.config/neovim").Return(false, "", fmt.Errorf("not a git repository (or any of the parent"))
mockPathwrap.On("Base", "/Users/josh/.config/neovim").Return("neovim")
name, _ := n.Name("/Users/josh/c/neovim")
assert.Equal(t, "neovim", name)
Expand Down