Skip to content

Commit

Permalink
init packed ref parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
richardjennings committed Oct 23, 2024
1 parent aedc6b7 commit 9a42b6a
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 3 deletions.
20 changes: 18 additions & 2 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,26 @@ const (
DefaultRefsHeadsDirectory = "heads"
DefaultBranch = "refs/heads/main"
DefaultEditor = "vim"
DefaultPackedRefsFile = "info/refs"
)

var Config Cnf

type (
Cnf struct {
GitDirectory string
Path string
// GitDirector configures where the name of the git directory
// This is usually .git
GitDirectory string
// Path configures where the Git Directory to interact with is
// relative to the present working directory. This is usually .
Path string

HeadFile string
IndexFile string
ObjectsDirectory string
RefsDirectory string
RefsHeadsDirectory string
PackedRefsFile string
DefaultBranch string
GitIgnore []string
Editor string
Expand Down Expand Up @@ -64,6 +71,7 @@ func Configure(opts ...Opt) error {
ObjectsDirectory: DefaultObjectsDirectory,
RefsDirectory: DefaultRefsDirectory,
RefsHeadsDirectory: DefaultRefsHeadsDirectory,
PackedRefsFile: DefaultPackedRefsFile,
DefaultBranch: DefaultBranch,
Editor: DefaultEditor,
GitIgnore: []string{ //@todo read from .gitignore
Expand Down Expand Up @@ -110,10 +118,18 @@ func RefsDirectory() string {
return filepath.Join(Config.Path, Config.GitDirectory, Config.RefsDirectory)
}

func RefsHeadPrefix() string {
return filepath.Join(Config.RefsDirectory, Config.RefsHeadsDirectory) + string(os.PathSeparator)
}

func RefsHeadsDirectory() string {
return filepath.Join(Config.Path, Config.GitDirectory, Config.RefsDirectory, Config.RefsHeadsDirectory)
}

func PackedRefsFile() string {
return filepath.Join(Config.Path, Config.GitDirectory, Config.PackedRefsFile)
}

func GitHeadPath() string {
return filepath.Join(Config.Path, Config.GitDirectory, Config.HeadFile)
}
Expand Down
1 change: 1 addition & 0 deletions pkg/gfs/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ func (s *Sha) Same(ss *Sha) bool {
func (s Sha) AsHexString() string {
return hex.EncodeToString(s.hash[:])
}

func (s Sha) AsHexBytes() []byte {
b := make([]byte, 40)
hex.Encode(b, s.hash[:])
Expand Down
15 changes: 15 additions & 0 deletions pkg/index/index_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package index

import (
"github.com/richardjennings/mygit/pkg/gfs"
"github.com/stretchr/testify/assert"
"testing"
)

func TestAdd_WDUntracked(t *testing.T) {
idx := NewIndex()
err := idx.Add(&gfs.File{Path: "test_assets/test.file", Sha: &gfs.Sha{}, WdStatus: gfs.WDUntracked})
assert.Nil(t, err)
files := idx.Files()
assert.Equal(t, 1, len(files))
}
1 change: 1 addition & 0 deletions pkg/index/test_assets/test.file
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
content
38 changes: 37 additions & 1 deletion pkg/refs/refs.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"io/fs"
"os"
"path/filepath"
"sort"
"strings"
)

func UpdateHead(branch string) error {
Expand Down Expand Up @@ -78,8 +80,37 @@ func PreviousCommits() ([][]byte, error) {
return nil, nil
}

// ListBranches lists Git branches from refs/heads and info/refs
// It does not currently allow listing remote tracking branches
func ListBranches() ([]string, error) {
var branches []string
branchMap := make(map[string]struct{})

// check for packed refs
fh, err := os.Open(config.PackedRefsFile())
defer func() {
if fh != nil {
_ = fh.Close()
}
}()
if err == nil {
// we have a packed refs file to parse into a list of branches
scanner := bufio.NewScanner(fh)
for scanner.Scan() {
line := scanner.Bytes()
// hash := line[0:40]
path := string(line[41:])
// path can have multiple prefixes
// refs/heads/
// refs (for stash)
// refs/remotes/.../
// for now just use refs/heads/
if path, ok := strings.CutPrefix(path, config.RefsHeadPrefix()); ok {
branchMap[path] = struct{}{}
}
}
}

f, err := os.ReadDir(config.RefsHeadsDirectory())
if err != nil {
return branches, err
Expand All @@ -88,8 +119,13 @@ func ListBranches() ([]string, error) {
if v.IsDir() {
continue
}
branches = append(branches, v.Name())
branchMap[v.Name()] = struct{}{}
}
// return branches sorted alphabetically
for k := range branchMap {
branches = append(branches, k)
}
sort.Sort(sort.StringSlice(branches))

Check failure on line 128 in pkg/refs/refs.go

View workflow job for this annotation

GitHub Actions / lint

S1032: should use sort.Strings(...) instead of sort.Sort(sort.StringSlice(...)) (gosimple)

Check failure on line 128 in pkg/refs/refs.go

View workflow job for this annotation

GitHub Actions / lint

S1032: should use sort.Strings(...) instead of sort.Sort(sort.StringSlice(...)) (gosimple)
return branches, nil
}

Expand Down

0 comments on commit 9a42b6a

Please sign in to comment.