package main import ( "crypto/sha512" "fmt" "os" "time" ) type FileModify struct { Blob int Path string } func (f FileModify) write() { fmt.Printf("M 644 :%d %s\n", f.Blob, f.Path) } type Commit struct { Mark int Branch string Committer string Timestamp time.Time Message string From int DeleteAll bool Modifications []FileModify } func (c Commit) write() { fmt.Println("commit refs/heads/" + c.Branch) if c.Mark != 0 { fmt.Printf("mark :%d\n", c.Mark) } fmt.Println("committer", c.Committer, formatTime(c.Timestamp)) fmt.Println("data", len(c.Message)) fmt.Println(c.Message) if c.From != 0 { fmt.Printf("from :%d\n", c.From) } if c.DeleteAll { fmt.Println("deleteall") } for _, m := range c.Modifications { m.write() } fmt.Println() } type Blob struct { Mark int Data []byte } func (b Blob) write() { fmt.Println("blob") if b.Mark != 0 { fmt.Printf("mark :%d\n", b.Mark) } fmt.Println("data", len(b.Data)) os.Stdout.Write(b.Data) fmt.Println() } // A FastExportStream is a representation of a fast-export stream. type FastExportStream struct { marks Marks blobIndex map[[64]byte]int } func (f *FastExportStream) AddCommit(c Commit) { if c.Mark == 0 { c.Mark = f.marks.Next() } c.write() } // AddBlob adds a blob to the stream and returns its mark. func (f *FastExportStream) AddBlob(data []byte) int { hash := sha512.Sum512(data) if mark, ok := f.blobIndex[hash]; ok { return mark } b := Blob{ Mark: f.marks.Next(), Data: data, } if f.blobIndex == nil { f.blobIndex = make(map[[64]byte]int) } f.blobIndex[hash] = b.Mark b.write() return b.Mark }