Skip to content

Commit

Permalink
add resetIndex (#128)
Browse files Browse the repository at this point in the history
  • Loading branch information
JunNishimura committed Jun 18, 2023
1 parent 1e58d12 commit bcaef8d
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 60 deletions.
37 changes: 1 addition & 36 deletions cmd/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,44 +98,9 @@ func commit() error {
return nil
}

func getEntriesFromTree(rootName string, nodes []*object.Node) ([]*store.Entry, error) {
var entries []*store.Entry

for _, node := range nodes {
if len(node.Children) == 0 {
var entryName string
if rootName == "" {
entryName = node.Name
} else {
entryName = fmt.Sprintf("%s/%s", rootName, node.Name)
}
newEntry := &store.Entry{
Hash: node.Hash,
NameLength: uint16(len(entryName)),
Path: []byte(entryName),
}
entries = append(entries, newEntry)
} else {
var newRootName string
if rootName == "" {
newRootName = node.Name
} else {
newRootName = fmt.Sprintf("%s/%s", rootName, node.Name)
}
childEntries, err := getEntriesFromTree(newRootName, node.Children)
if err != nil {
return nil, err
}
entries = append(entries, childEntries...)
}
}

return entries, nil
}

func isIndexDifferentFromTree(index *store.Index, tree *object.Tree) (bool, error) {
rootName := ""
gotEntries, err := getEntriesFromTree(rootName, tree.Children)
gotEntries, err := store.GetEntriesFromTree(rootName, tree.Children)
if err != nil {
return false, err
}
Expand Down
51 changes: 34 additions & 17 deletions cmd/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,7 @@ var (
resetRegexp = regexp.MustCompile(`HEAD@\{\d\}`)
)

func resetHead(arg, rootGoitPath string, head *store.Head, refs *store.Refs, conf *store.Config) error {
// get log record
reflog, err := store.NewReflog(rootGoitPath, head, refs)
if err != nil {
return fmt.Errorf("fail to initialize reflog: %w", err)
}
sp := strings.Split(arg, "HEAD@")[1]
headNum, err := strconv.Atoi(sp[1 : len(sp)-1])
if err != nil {
return fmt.Errorf("fail to convert number '%s': %w", arg, err)
}
logRecord, err := reflog.GetRecord(headNum)
if err != nil {
return fmt.Errorf("fail to get log record: %w", err)
}

func resetHead(arg, rootGoitPath string, logRecord *store.LogRecord, head *store.Head, refs *store.Refs, conf *store.Config) error {
// reset Head
prevHeadHash := head.Commit.Hash
if err := head.Reset(rootGoitPath, refs, logRecord.Hash); err != nil {
Expand All @@ -57,6 +42,15 @@ func resetHead(arg, rootGoitPath string, head *store.Head, refs *store.Refs, con
return nil
}

func resetIndex(rootGoitPath string, logRecord *store.LogRecord, index *store.Index) error {
// reset index
if err := index.Reset(rootGoitPath, logRecord.Hash); err != nil {
return fmt.Errorf("fail to reset index: %w", err)
}

return nil
}

// resetCmd represents the reset command
var resetCmd = &cobra.Command{
Use: "reset",
Expand Down Expand Up @@ -84,12 +78,35 @@ var resetCmd = &cobra.Command{
return errors.New("only one argument is acceptible. argument format is 'HEAD@{number}'")
}

// get log record
reflog, err := store.NewReflog(client.RootGoitPath, client.Head, client.Refs)
if err != nil {
return fmt.Errorf("fail to initialize reflog: %w", err)
}
sp := strings.Split(args[0], "HEAD@")[1]
headNum, err := strconv.Atoi(sp[1 : len(sp)-1])
if err != nil {
return fmt.Errorf("fail to convert number '%s': %w", args[0], err)
}
logRecord, err := reflog.GetRecord(headNum)
if err != nil {
return fmt.Errorf("fail to get log record: %w", err)
}

// reset HEAD
if isSoft || isMixed || isHard {
if err := resetHead(args[0], client.RootGoitPath, client.Head, client.Refs, client.Conf); err != nil {
if err := resetHead(args[0], client.RootGoitPath, logRecord, client.Head, client.Refs, client.Conf); err != nil {
return fmt.Errorf("fail to reset HEAD: %w", err)
}
}

// reset index
if isMixed || isHard {
if err := resetIndex(client.RootGoitPath, logRecord, client.Idx); err != nil {
return fmt.Errorf("fail to reset index: %w", err)
}
}

return nil
},
}
Expand Down
95 changes: 88 additions & 7 deletions internal/store/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path/filepath"
"sort"

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

Expand Down Expand Up @@ -41,13 +42,7 @@ type Index struct {
}

func NewIndex(rootGoitPath string) (*Index, error) {
index := &Index{
Header: Header{
Signature: [4]byte{'D', 'I', 'R', 'C'},
Version: uint32(1),
EntryNum: uint32(0),
},
}
index := newIndex()
indexPath := filepath.Join(rootGoitPath, "index")
if _, err := os.Stat(indexPath); !os.IsNotExist(err) {
if err := index.read(rootGoitPath); err != nil {
Expand All @@ -57,6 +52,16 @@ func NewIndex(rootGoitPath string) (*Index, error) {
return index, nil
}

func newIndex() *Index {
return &Index{
Header: Header{
Signature: [4]byte{'D', 'I', 'R', 'C'},
Version: uint32(1),
EntryNum: uint32(0),
},
}
}

// return the position of entry, entry, and flag to tell the entry is found or not
func (idx *Index) GetEntry(path []byte) (int, *Entry, bool) {
if idx.EntryNum == 0 {
Expand Down Expand Up @@ -202,3 +207,79 @@ func (idx *Index) write(rootGoitPath string) error {

return nil
}

func GetEntriesFromTree(rootName string, nodes []*object.Node) ([]*Entry, error) {
var entries []*Entry

for _, node := range nodes {
if len(node.Children) == 0 {
var entryName string
if rootName == "" {
entryName = node.Name
} else {
entryName = fmt.Sprintf("%s/%s", rootName, node.Name)
}
newEntry := &Entry{
Hash: node.Hash,
NameLength: uint16(len(entryName)),
Path: []byte(entryName),
}
entries = append(entries, newEntry)
} else {
var newRootName string
if rootName == "" {
newRootName = node.Name
} else {
newRootName = fmt.Sprintf("%s/%s", rootName, node.Name)
}
childEntries, err := GetEntriesFromTree(newRootName, node.Children)
if err != nil {
return nil, err
}
entries = append(entries, childEntries...)
}
}

return entries, nil
}

func (idx *Index) Reset(rootGoitPath string, hash sha.SHA1) error {
// get commit
commitObject, err := object.GetObject(rootGoitPath, hash)
if err != nil {
return fmt.Errorf("fail to get commit object: %w", err)
}

// get commit
commit, err := object.NewCommit(commitObject)
if err != nil {
return fmt.Errorf("fail to get commit: %w", err)
}

// get tree object
treeObject, err := object.GetObject(rootGoitPath, commit.Tree)
if err != nil {
return fmt.Errorf("fail to get tree object: %w", err)
}

// get tree
tree, err := object.NewTree(rootGoitPath, treeObject)
if err != nil {
return fmt.Errorf("fail to get tree: %w", err)
}

// update index from tree
entries, err := GetEntriesFromTree("", tree.Children)
if err != nil {
return fmt.Errorf("fail to get entries from tree: %w", err)
}
idx.Header.EntryNum = uint32(len(entries))
idx.Entries = entries

// write index
if err := idx.write(rootGoitPath); err != nil {
return fmt.Errorf("fail to write index: %w", err)
}

return nil
}

0 comments on commit bcaef8d

Please sign in to comment.