Created
July 29, 2019 07:01
-
-
Save imjasonh/85f48260448ae445facfa6b0fcf42551 to your computer and use it in GitHub Desktop.
hacking on trying to write git objects (https://github.com/ImJasonH/ideas/issues/77)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"compress/zlib" | |
"crypto/sha1" | |
"fmt" | |
"io" | |
"log" | |
"os" | |
) | |
func writeCommit(files map[string]string, message, person string) (string, error) { | |
//TODO: parents | |
treeSHA, err := writeTree(files) | |
if err != nil { | |
return "", err | |
} | |
commit := fmt.Sprintf( | |
`tree %s | |
author %s | |
committer %s | |
%s | |
`, treeSHA, person, person, message) | |
size := len(commit) | |
obj := fmt.Sprintf("commit %d\000%s", size, commit) | |
log.Println("writing commit...") | |
return writeObject(obj) | |
} | |
// TODO: subdirectries/subtrees | |
func writeTree(files map[string]string) (string, error) { | |
var buf bytes.Buffer | |
for fn, c := range files { | |
log.Println("writing blob...") | |
size := len(c) | |
obj := fmt.Sprintf("blob %d\000%s", size, c) | |
sha, err := writeObject(obj) | |
if err != nil { | |
return "", err | |
} | |
fmt.Fprintf(&buf, "100644 blob %s %s\n", sha, fn) | |
} | |
c := buf.String() | |
obj := fmt.Sprintf("tree %d\000%s", len(c), c) | |
log.Println("writing tree...") | |
return writeObject(obj) | |
} | |
func writeObject(obj string) (string, error) { | |
h := sha1.New() | |
io.WriteString(h, obj) | |
sha := fmt.Sprintf("%x", h.Sum(nil)) | |
log.Println("writing object", sha, obj) | |
prefix := sha[0:2] | |
rest := sha[2:] | |
os.MkdirAll(fmt.Sprintf(".git/objects/%s", prefix), 0777) | |
// TODO:O skip if exists | |
f, err := os.Create(fmt.Sprintf(".git/objects/%s/%s", prefix, rest)) | |
if err != nil { | |
return "", err | |
} | |
defer f.Close() | |
zw := zlib.NewWriter(f) | |
defer zw.Close() | |
fmt.Fprint(zw, obj) | |
return sha, nil | |
} | |
func main() { | |
files := map[string]string{ | |
"date": `Sun Jul 28 08:47:45 EDT 2019 | |
`, | |
} | |
message := "the date is" | |
person := "Jason Hall <jasonhall@google.com> 1564318077 -0400" | |
_, err := writeCommit(files, message, person) | |
if err != nil { | |
log.Fatal(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment