diff options
Diffstat (limited to 'internal/gitdiff/format.go')
| -rw-r--r-- | internal/gitdiff/format.go | 281 |
1 files changed, 0 insertions, 281 deletions
diff --git a/internal/gitdiff/format.go b/internal/gitdiff/format.go deleted file mode 100644 index d97aba9..0000000 --- a/internal/gitdiff/format.go +++ /dev/null @@ -1,281 +0,0 @@ -package gitdiff - -import ( - "bytes" - "compress/zlib" - "fmt" - "io" - "strconv" -) - -type formatter struct { - w io.Writer - err error -} - -func newFormatter(w io.Writer) *formatter { - return &formatter{w: w} -} - -func (fm *formatter) Write(p []byte) (int, error) { - if fm.err != nil { - return len(p), nil - } - if _, err := fm.w.Write(p); err != nil { - fm.err = err - } - return len(p), nil -} - -func (fm *formatter) WriteString(s string) (int, error) { - fm.Write([]byte(s)) - return len(s), nil -} - -func (fm *formatter) WriteByte(c byte) error { - fm.Write([]byte{c}) - return nil -} - -func (fm *formatter) WriteQuotedName(s string) { - qpos := 0 - for i := 0; i < len(s); i++ { - ch := s[i] - if q, quoted := quoteByte(ch); quoted { - if qpos == 0 { - fm.WriteByte('"') - } - fm.WriteString(s[qpos:i]) - fm.Write(q) - qpos = i + 1 - } - } - fm.WriteString(s[qpos:]) - if qpos > 0 { - fm.WriteByte('"') - } -} - -var quoteEscapeTable = map[byte]byte{ - '\a': 'a', - '\b': 'b', - '\t': 't', - '\n': 'n', - '\v': 'v', - '\f': 'f', - '\r': 'r', - '"': '"', - '\\': '\\', -} - -func quoteByte(b byte) ([]byte, bool) { - if q, ok := quoteEscapeTable[b]; ok { - return []byte{'\\', q}, true - } - if b < 0x20 || b >= 0x7F { - return []byte{ - '\\', - '0' + (b>>6)&0o3, - '0' + (b>>3)&0o7, - '0' + (b>>0)&0o7, - }, true - } - return nil, false -} - -func (fm *formatter) FormatFile(f *File) { - fm.WriteString("diff --git ") - - var aName, bName string - switch { - case f.OldName == "": - aName = f.NewName - bName = f.NewName - - case f.NewName == "": - aName = f.OldName - bName = f.OldName - - default: - aName = f.OldName - bName = f.NewName - } - - fm.WriteQuotedName("a/" + aName) - fm.WriteByte(' ') - fm.WriteQuotedName("b/" + bName) - fm.WriteByte('\n') - - if f.OldMode != 0 { - if f.IsDelete { - fmt.Fprintf(fm, "deleted file mode %o\n", f.OldMode) - } else if f.NewMode != 0 { - fmt.Fprintf(fm, "old mode %o\n", f.OldMode) - } - } - - if f.NewMode != 0 { - if f.IsNew { - fmt.Fprintf(fm, "new file mode %o\n", f.NewMode) - } else if f.OldMode != 0 { - fmt.Fprintf(fm, "new mode %o\n", f.NewMode) - } - } - - if f.Score > 0 { - if f.IsCopy || f.IsRename { - fmt.Fprintf(fm, "similarity index %d%%\n", f.Score) - } else { - fmt.Fprintf(fm, "dissimilarity index %d%%\n", f.Score) - } - } - - if f.IsCopy { - if f.OldName != "" { - fm.WriteString("copy from ") - fm.WriteQuotedName(f.OldName) - fm.WriteByte('\n') - } - if f.NewName != "" { - fm.WriteString("copy to ") - fm.WriteQuotedName(f.NewName) - fm.WriteByte('\n') - } - } - - if f.IsRename { - if f.OldName != "" { - fm.WriteString("rename from ") - fm.WriteQuotedName(f.OldName) - fm.WriteByte('\n') - } - if f.NewName != "" { - fm.WriteString("rename to ") - fm.WriteQuotedName(f.NewName) - fm.WriteByte('\n') - } - } - - if f.OldOIDPrefix != "" && f.NewOIDPrefix != "" { - fmt.Fprintf(fm, "index %s..%s", f.OldOIDPrefix, f.NewOIDPrefix) - - // Mode is only included on the index line when it is not changing - if f.OldMode != 0 && ((f.NewMode == 0 && !f.IsDelete) || f.OldMode == f.NewMode) { - fmt.Fprintf(fm, " %o", f.OldMode) - } - - fm.WriteByte('\n') - } - - if f.IsBinary { - if f.BinaryFragment == nil { - fm.WriteString("Binary files ") - fm.WriteQuotedName("a/" + aName) - fm.WriteString(" and ") - fm.WriteQuotedName("b/" + bName) - fm.WriteString(" differ\n") - } else { - fm.WriteString("GIT binary patch\n") - fm.FormatBinaryFragment(f.BinaryFragment) - if f.ReverseBinaryFragment != nil { - fm.FormatBinaryFragment(f.ReverseBinaryFragment) - } - } - } - - // The "---" and "+++" lines only appear for text patches with fragments - if len(f.TextFragments) > 0 { - fm.WriteString("--- ") - if f.OldName == "" { - fm.WriteString("/dev/null") - } else { - fm.WriteQuotedName("a/" + f.OldName) - } - fm.WriteByte('\n') - - fm.WriteString("+++ ") - if f.NewName == "" { - fm.WriteString("/dev/null") - } else { - fm.WriteQuotedName("b/" + f.NewName) - } - fm.WriteByte('\n') - - for _, frag := range f.TextFragments { - fm.FormatTextFragment(frag) - } - } -} - -func (fm *formatter) FormatTextFragment(f *TextFragment) { - fm.FormatTextFragmentHeader(f) - fm.WriteByte('\n') - - for _, line := range f.Lines { - fm.WriteString(line.Op.String()) - fm.WriteString(line.Line) - if line.NoEOL() { - fm.WriteString("\n\\ No newline at end of file\n") - } - } -} - -func (fm *formatter) FormatTextFragmentHeader(f *TextFragment) { - fmt.Fprintf(fm, "@@ -%d,%d +%d,%d @@", f.OldPosition, f.OldLines, f.NewPosition, f.NewLines) - if f.Comment != "" { - fm.WriteByte(' ') - fm.WriteString(f.Comment) - } -} - -func (fm *formatter) FormatBinaryFragment(f *BinaryFragment) { - const ( - maxBytesPerLine = 52 - ) - - switch f.Method { - case BinaryPatchDelta: - fm.WriteString("delta ") - case BinaryPatchLiteral: - fm.WriteString("literal ") - } - fm.Write(strconv.AppendInt(nil, f.Size, 10)) - fm.WriteByte('\n') - - data := deflateBinaryChunk(f.Data) - n := (len(data) / maxBytesPerLine) * maxBytesPerLine - - buf := make([]byte, base85Len(maxBytesPerLine)) - for i := 0; i < n; i += maxBytesPerLine { - base85Encode(buf, data[i:i+maxBytesPerLine]) - fm.WriteByte('z') - fm.Write(buf) - fm.WriteByte('\n') - } - if remainder := len(data) - n; remainder > 0 { - buf = buf[0:base85Len(remainder)] - - sizeChar := byte(remainder) - if remainder <= 26 { - sizeChar = 'A' + sizeChar - 1 - } else { - sizeChar = 'a' + sizeChar - 27 - } - - base85Encode(buf, data[n:]) - fm.WriteByte(sizeChar) - fm.Write(buf) - fm.WriteByte('\n') - } - fm.WriteByte('\n') -} - -func deflateBinaryChunk(data []byte) []byte { - var b bytes.Buffer - - zw := zlib.NewWriter(&b) - _, _ = zw.Write(data) - _ = zw.Close() - - return b.Bytes() -} |
