Skip to content

Commit

Permalink
Merge pull request #97 from JunNishimura/#96
Browse files Browse the repository at this point in the history
add commit to Head
  • Loading branch information
JunNishimura committed Jun 4, 2023
2 parents acb3317 + 73156ee commit 7d315da
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 57 deletions.
31 changes: 1 addition & 30 deletions cmd/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"path/filepath"

"github.com/JunNishimura/Goit/internal/object"
"github.com/JunNishimura/Goit/internal/sha"
"github.com/JunNishimura/Goit/internal/store"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -150,29 +149,6 @@ func isCommitNecessary(commitObj *object.Commit) (bool, error) {
return isDiff, nil
}

// get HEAD commit
func getHeadCommit() (*object.Commit, error) {
branchPath := filepath.Join(client.RootGoitPath, "refs", "heads", string(client.Head))
hashBytes, err := os.ReadFile(branchPath)
if err != nil {
return nil, fmt.Errorf("%w: %s", ErrIOHandling, branchPath)
}
hashString := string(hashBytes)
hash, err := sha.ReadHash(hashString)
if err != nil {
return nil, fmt.Errorf("fail to decode hash string: %w", err)
}
commitObject, err := object.GetObject(client.RootGoitPath, hash)
if err != nil {
return nil, fmt.Errorf("fail to get last commit object: %w", err)
}
commit, err := object.NewCommit(commitObject)
if err != nil {
return nil, fmt.Errorf("fail to get last commit: %w", err)
}
return commit, nil
}

// commitCmd represents the commit command
var commitCmd = &cobra.Command{
Use: "commit",
Expand Down Expand Up @@ -211,13 +187,8 @@ var commitCmd = &cobra.Command{
return fmt.Errorf("fail to delete untracked files: %w", err)
}

headCommit, err := getHeadCommit()
if err != nil {
return fmt.Errorf("fail to get HEAD commit: %w", err)
}

// compare last commit with index
isCommitNecessary, err := isCommitNecessary(headCommit)
isCommitNecessary, err := isCommitNecessary(client.Head.Commit)
if err != nil {
return fmt.Errorf("fail to compare last commit with index: %w", err)
}
Expand Down
10 changes: 2 additions & 8 deletions cmd/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,13 @@ var restoreCmd = &cobra.Command{
if isStaged {
// restore --stage is comparing index with commit object pointed by HEAD
// so, at lease one commit is needed
branchPath := filepath.Join(client.RootGoitPath, "refs", "heads", string(client.Head))
branchPath := filepath.Join(client.RootGoitPath, "refs", "heads", client.Head.Reference)
if _, err := os.Stat(branchPath); os.IsNotExist(err) {
return errors.New("fatal: could not resolve HEAD")
}

// get HEAD commit
headCommit, err := getHeadCommit()
if err != nil {
return fmt.Errorf("fail to get HEAD commit: %w", err)
}

// get tree from HEAD commit
treeObject, err := object.GetObject(client.RootGoitPath, headCommit.Tree)
treeObject, err := object.GetObject(client.RootGoitPath, client.Head.Commit.Tree)
if err != nil {
return fmt.Errorf("fail to get tree object from commit HEAD: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/revParse.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func revParse(refNames ...string) error {
for _, refName := range refNames {
var refPath string
if strings.ToLower(refName) == "head" {
refPath = filepath.Join(client.RootGoitPath, "refs", "heads", string(client.Head))
refPath = filepath.Join(client.RootGoitPath, "refs", "heads", client.Head.Reference)
} else {
refPath = filepath.Join(client.RootGoitPath, "refs", "heads", refName)
}
Expand Down
8 changes: 4 additions & 4 deletions internal/store/client.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package store

type Client struct {
Conf *Config
Idx *Index
Head
Conf *Config
Idx *Index
Head *Head
RootGoitPath string
}

func NewClient(config *Config, index *Index, head Head, rootGoitPath string) *Client {
func NewClient(config *Config, index *Index, head *Head, rootGoitPath string) *Client {
return &Client{
Conf: config,
Idx: index,
Expand Down
61 changes: 55 additions & 6 deletions internal/store/head.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,80 @@ import (
"path/filepath"
"regexp"
"strings"

"github.com/JunNishimura/Goit/internal/object"
"github.com/JunNishimura/Goit/internal/sha"
)

type Head string
type Head struct {
Reference string
Commit *object.Commit
}

var (
headRegexp = regexp.MustCompile("ref: refs/heads/.+")
ErrInvalidHead = errors.New("error: invalid HEAD format")
ErrIOHandling = errors.New("IO handling error")
)

func NewHead(rootGoitPath string) (Head, error) {
func getHeadCommit(branch, rootGoitPath string) (*object.Commit, error) {
branchPath := filepath.Join(rootGoitPath, "refs", "heads", branch)
hashBytes, err := os.ReadFile(branchPath)
if err != nil {
return nil, fmt.Errorf("%w: %s", ErrIOHandling, branchPath)
}
hashString := string(hashBytes)
hash, err := sha.ReadHash(hashString)
if err != nil {
return nil, fmt.Errorf("fail to decode hash string: %w", err)
}
commitObject, err := object.GetObject(rootGoitPath, hash)
if err != nil {
return nil, fmt.Errorf("fail to get last commit object: %w", err)
}
commit, err := object.NewCommit(commitObject)
if err != nil {
return nil, fmt.Errorf("fail to get last commit: %w", err)
}
return commit, nil
}

func NewHead(rootGoitPath string) (*Head, error) {
head := newHead()

headPath := filepath.Join(rootGoitPath, "HEAD")
if _, err := os.Stat(headPath); !os.IsNotExist(err) {
// get branch
headByte, err := os.ReadFile(headPath)
if err != nil {
return "", fmt.Errorf("fail to read file: %s", headPath)
return nil, fmt.Errorf("fail to read file: %s", headPath)
}
headString := string(headByte)
if ok := headRegexp.MatchString(headString); !ok {
return "", ErrInvalidHead
return nil, ErrInvalidHead
}
headSplit := strings.Split(headString, ": ")
slashSplit := strings.Split(headSplit[1], "/")
branch := slashSplit[len(slashSplit)-1]
return Head(branch), nil
head.Reference = branch

// get commit from branch
branchPath := filepath.Join(rootGoitPath, "refs", "heads", branch)
if _, err := os.Stat(branchPath); os.IsNotExist(err) {
return head, nil
}
commit, err := getHeadCommit(branch, rootGoitPath)
if err != nil {
return nil, ErrInvalidHead
}
head.Commit = commit

return head, nil
}

return "", nil
return head, nil
}

func newHead() *Head {
return &Head{}
}
23 changes: 15 additions & 8 deletions internal/store/head_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"os"
"path/filepath"
"reflect"
"testing"
)

Expand All @@ -12,27 +13,33 @@ func TestNewHead(t *testing.T) {
name string
content string
isCreated bool
want Head
want *Head
wantErr error
}{
{
name: "success",
content: "ref: refs/heads/main",
isCreated: true,
want: "main",
wantErr: nil,
want: &Head{
Reference: "main",
Commit: nil,
},
wantErr: nil,
}, {
name: "invalid HEAD format",
content: "ref: ***",
isCreated: true,
want: "",
want: nil,
wantErr: ErrInvalidHead,
}, {
name: "no HEAD file",
content: "ref: refs/heads/main",
isCreated: false,
want: "",
wantErr: nil,
want: &Head{
Reference: "",
Commit: nil,
},
wantErr: nil,
},
}
for _, tt := range tests {
Expand Down Expand Up @@ -88,8 +95,8 @@ func TestNewHead(t *testing.T) {
if !errors.Is(err, tt.wantErr) {
t.Errorf("got = %v, want = %v", err, tt.wantErr)
}
if head != tt.want {
t.Errorf("got = %s, want = %s", head, tt.want)
if !reflect.DeepEqual(head, tt.want) {
t.Errorf("got = %v, want = %v", head, tt.want)
}
})
}
Expand Down

0 comments on commit 7d315da

Please sign in to comment.