diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2017-11-15 15:38:05 -0500 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2017-11-15 15:38:05 -0500 |
commit | 902bb1cc2a0a8644e160f303be1a2e0ad354bfd5 (patch) | |
tree | e6ddce8d0bc8664a99ffc346ef38c65d39a76dae /git-fast-import.go |
initial commit
Diffstat (limited to 'git-fast-import.go')
-rw-r--r-- | git-fast-import.go | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/git-fast-import.go b/git-fast-import.go new file mode 100644 index 0000000..d9c7795 --- /dev/null +++ b/git-fast-import.go @@ -0,0 +1,118 @@ +package libfastimport + +import ( + "time" +) + +type FastImport struct { + w *FIWriter + r *CatBlobReader + err error +} + +func (fi *FastImport) GetMark(mark int) (string, error) { + if fi.printf("get-mark :%d\n", mark) != nil { + return "", fi.ioErr + } + var dat [41]byte + var n int + _, fi.ioErr = io.ReadFull(fi.r, dat[:]) + if fi.ioErr != nil { + return "", fi.ioErr + } + if dat[40] != '\n' { + fi.ioErr = fmt.Errorf("get-mark: malformed <sha1>\\n: %q", string(dat)) + return "", fi.ioErr + } + for _, b := range dat[:40] { + if !(('0' <= b && b <= '9') || ('a' <= b && b <= 'f')) { + fi.ioErr = fmt.Errorf("get-mark: malformed <sha1>: %q", string(dat[:40])) + return "", fi.ioErr + } + } + return string(dat[:40]) +} + +func (fi *FastImport) CatBlob(dataref string) (sha1 string, data []byte, err error) { + if fi.println("cat-blob %s\n", dataref) != nil { + return "", nil, fi.ioErr + } + // <sha1> SP 'blob' SP <size> LF + // + // That comes out to be 47+len(itoa(size)). Assuming that + // size is at most a 64-bit integer (a safe assumption), then + // its limit is 20 digits. + var head [67]byte + i := 0 + for { + _, fi.ioErr = io.ReadFull(fi.r, head[i:i+1]) + if fi.ioErr != nil { + return "", nil, fi.ioErr + } + if head[i] == '\n' { + break + } + i++ + if i == len(head) { + fi.ioErr = fmt.Errorf("cat-blob: overly-long header line: %q", string(head)) + return "", nil, fi.ioErr + } + } + i-- + if head[i] != '\n' { + panic("wut") + } + for _, b := range head[:40] { + if !(('0' <= b && b <= '9') || ('a' <= b && b <= 'f')) { + fi.ioErr = fmt.Errorf("cat-blob: malformed <sha1>: %q", string(head[:40])) + return "", nil, fi.ioErr + } + } + if string(head[40:46]) != " blob " { + fi.ioErr = fmt.Errorf("cat-blob: malformed header: %q", string(head[:i])) + return "", nil, fi.ioErr + } + size, err := strconv.Atoi(string(head[46:i])) + if err != nil { + fi.ioErr = fmt.Errorf("cat-blob: malformed blob size: %v", err) + return "", nil, fi.ioErr + } + dat := make([]byte, size+1) + _, fi.ioErr = io.ReadFull(fi.r, dat) + if dat[size] != '\n' { + fi.ioErr = fmt.Errorf("cat-blob: expected newline after data") + return "", nil, fi.ioErr + } + return string(head[:40]), dat[:size], nil +} + +func (fi *FastImport) Ls(dataref string, path string) error { + if dataref == "" { + fi.printf("ls %s\n", quotePath(path)) + } else { + fi.printf("ls %s %s\n", dataref, quotePath(path)) + } + if fi.ioErr != nil { + return fi.ioErr + } + k +} +func (fi *FastImport) Feature() error +func (fi *FastImport) Option() error + +func (fi *FastImport) Done() error { + fi.printf("done\n") + if fi.ioErr == nil { + fi.ioErr = w.Close() + } + return fi.ioErr +} + +func init() { + x := exec.Cmd{ + Path: prog["git"], + Args: {"git", "fast-import", + "--done", + "--cat-blob-fd=" + strconv.Itoa(TODO)}, + } +} |