A library for working with Pijul repositories in Go
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
}