Find HEAD is implemented

This commit is contained in:
Quentin 2021-04-21 22:29:17 +02:00
parent dfcc8993ca
commit 9fd13f759a
Signed by: quentin
GPG key ID: A98E9B769E4FF428

132
commit.go
View file

@ -2,41 +2,58 @@ package main
import ( import (
"encoding/json" "encoding/json"
"fmt"
"log" "log"
"time"
"io/ioutil" "io/ioutil"
"path/filepath" "path/filepath"
) )
type Empty struct{}
var empty Empty
type RepoCommits struct { type RepoCommits struct {
Config configCollect Config configCollect
CommitDesc map[string]string CommitDesc map[string]string
CommitContent map[string]Commit CommitContent map[string]*CommitNode
Head *CommitNode Head *CommitNode
Root *CommitNode
} }
type CommitNode struct { type CommitNode struct {
Parents []*CommitNode Parents map[*CommitNode]Empty
Children []*CommitNode Children map[*CommitNode]Empty
Content Commit Content Commit
} }
type Commit struct { type Commit struct {
CommitId string `json:"commit_id"` CommitId *string `json:"commit_id"`
RootId string `json:"root_id"` RootId *string `json:"root_id"`
RepoId string `json:"repo_id"` RepoId *string `json:"repo_id"`
CreatorName string `json:"creator_name"` CreatorName *string `json:"creator_name"`
Creator string `json:"creator"` Creator *string `json:"creator"`
Description string `json:"description"` Description *string `json:"description"`
Ctime uint64 `json:"ctime"` Ctime int64 `json:"ctime"`
ParentId string `json:"parent_id"` ParentId *string `json:"parent_id"`
SecondParentId string `json:"second_parent_id"` SecondParentId *string `json:"second_parent_id"`
RepoName string `json:"repo_name"` RepoName *string `json:"repo_name"`
RepoDesc string `json:"repo_desc"` RepoDesc *string `json:"repo_desc"`
RepoCategory string `json:"repo_category"` RepoCategory *string `json:"repo_category"`
NoLocalHistory int `json:"no_local_history"` NoLocalHistory int `json:"no_local_history"`
Version int `json:"version"` Version int `json:"version"`
} }
func (c* Commit) String() string {
return fmt.Sprintf(`RootId: %s
CreatorName: %s
Creator: %s
Description: %s
Ctime: %s
RepoName: %s
RepoDesc: %s
`, *c.RootId, *c.CreatorName, *c.Creator, *c.Description, time.Unix(c.Ctime, 0), *c.RepoName, *c.RepoDesc)
}
func cmdCommit(config configCollect) { func cmdCommit(config configCollect) {
rc := NewRepoCommits(config) rc := NewRepoCommits(config)
@ -44,20 +61,21 @@ func cmdCommit(config configCollect) {
rc.PrintDescs() rc.PrintDescs()
rc.CollectContent() rc.CollectContent()
//rc.BuildGraph() rc.BuildGraph()
rc.FindHead()
rc.PrintHead()
} }
func NewRepoCommits (config configCollect) *RepoCommits { func NewRepoCommits (config configCollect) *RepoCommits {
rc := new(RepoCommits) rc := new(RepoCommits)
rc.Config = config rc.Config = config
rc.CommitDesc = make(map[string]string) rc.CommitDesc = make(map[string]string)
rc.CommitContent = make(map[string]Commit) rc.CommitContent = make(map[string]*CommitNode)
return rc return rc
} }
func (rc* RepoCommits) CollectDescs() { func (rc* RepoCommits) CollectDescs() {
baseFolder := filepath.Join(rc.Config.Storage, "commits", rc.Config.RepoId) baseFolder := filepath.Join(rc.Config.Storage, "commits", rc.Config.RepoId)
log.Println(baseFolder)
layer1, err := ioutil.ReadDir(baseFolder) layer1, err := ioutil.ReadDir(baseFolder)
if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) }
for _, l1 := range layer1 { for _, l1 := range layer1 {
@ -73,7 +91,7 @@ func (rc* RepoCommits) CollectDescs() {
} }
func (rc* RepoCommits) PrintDescs() { func (rc* RepoCommits) PrintDescs() {
limit := 10 /*limit := 10
for id, path := range rc.CommitDesc { for id, path := range rc.CommitDesc {
log.Println(id, path) log.Println(id, path)
limit = limit - 1 limit = limit - 1
@ -81,18 +99,86 @@ func (rc* RepoCommits) PrintDescs() {
log.Println("Too many commits, output has been truncated") log.Println("Too many commits, output has been truncated")
break break
} }
} }*/
log.Println("Repo", rc.Config.RepoId, "contains", len(rc.CommitDesc), "commits") log.Println("Repo", rc.Config.RepoId, "contains", len(rc.CommitDesc), "commits")
} }
func NewCommitNode(c Commit) *CommitNode {
cn := new(CommitNode)
cn.Content = c
cn.Parents = make(map[*CommitNode]Empty)
cn.Children = make(map[*CommitNode]Empty)
return cn
}
func (rc* RepoCommits) CollectContent() { func (rc* RepoCommits) CollectContent() {
for id, path := range rc.CommitDesc { for id, path := range rc.CommitDesc {
data, err := ioutil.ReadFile(path) data, err := ioutil.ReadFile(path)
if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) }
var c Commit var c Commit;
json.Unmarshal(data, &c) json.Unmarshal(data, &c)
rc.CommitContent[id] = c rc.CommitContent[id] = NewCommitNode(c)
log.Println(rc.CommitContent[id])
} }
} }
func (rc* RepoCommits) BuildGraph() *CommitNode {
for _, cn := range rc.CommitContent {
if cn.Content.ParentId == nil && cn.Content.SecondParentId == nil {
if rc.Root == nil {
rc.Root = cn
} else {
log.Fatal("More than one root commit has been found")
}
}
if cn.Content.ParentId != nil {
parentCn := rc.CommitContent[*cn.Content.ParentId]
cn.Parents[parentCn] = empty
parentCn.Children[cn] = empty
}
if cn.Content.SecondParentId != nil {
parentCn := rc.CommitContent[*cn.Content.SecondParentId]
cn.Parents[parentCn] = empty
parentCn.Children[cn] = empty
}
}
if rc.Root == nil {
log.Fatal("Root commit has not been found")
}
return rc.Root
}
func (rc* RepoCommits) FindHead() *CommitNode {
toProcess := make(map[*CommitNode]Empty)
toProcess[rc.Root] = empty
for i := 0; i < len(rc.CommitContent) && len(toProcess) > 0; i++ {
nextToProcess := make(map[*CommitNode]Empty)
for cn, _ := range toProcess {
for ccn, _ := range cn.Children {
nextToProcess[ccn] = empty
}
if len(cn.Children) == 0 {
if rc.Head == nil {
rc.Head = cn
} else {
log.Fatal("More than one HEAD has been found")
}
}
}
toProcess = nextToProcess
}
if rc.Head == nil { log.Fatal("No HEAD has been found") }
return rc.Head
}
func (rc* RepoCommits) PrintHead() {
log.Println(rc.Head.Content.String())
}