GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — go-gitdiff/gitdiff/gitdiff.go at master · bluekeyes/go-gitdiff Expand file tree/ Copy pathgitdiff.goMore file actions 247 lines (209 loc) · 6.46 KB / Copy pathgitdiff.goFile metadata and controls247 lines (209 loc) · 6.46 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 package gitdiff import ( "errors" "fmt" "io" "os" "strings" ) // File describes changes to a single file. It can be either a text file or a // binary file. type File struct { OldName string NewName string IsNew bool IsDelete bool IsCopy bool IsRename bool OldMode os.FileMode NewMode os.FileMode OldOIDPrefix string NewOIDPrefix string Score int // TextFragments contains the fragments describing changes to a text file. It // may be empty if the file is empty or if only the mode changes. TextFragments []*TextFragment // IsBinary is true if the file is a binary file. If the patch includes // binary data, BinaryFragment will be non-nil and describe the changes to // the data. If the patch is reversible, ReverseBinaryFragment will also be // non-nil and describe the changes needed to restore the original file // after applying the changes in BinaryFragment. IsBinary bool BinaryFragment *BinaryFragment ReverseBinaryFragment *BinaryFragment } // String returns a git diff representation of this file. The value can be // parsed by this library to obtain the same File, but may not be the same as // the original input. func (f *File) String() string { var diff strings.Builder newFormatter(&diff).FormatFile(f) return diff.String() } // TextFragment describes changed lines starting at a specific line in a text file. type TextFragment struct { Comment string OldPosition int64 OldLines int64 NewPosition int64 NewLines int64 LinesAdded int64 LinesDeleted int64 LeadingContext int64 TrailingContext int64 Lines []Line } // String returns a git diff format of this fragment. See [File.String] for // more details on this format. func (f *TextFragment) String() string { var diff strings.Builder newFormatter(&diff).FormatTextFragment(f) return diff.String() } // Header returns a git diff header of this fragment. See [File.String] for // more details on this format. func (f *TextFragment) Header() string { var hdr strings.Builder newFormatter(&hdr).FormatTextFragmentHeader(f) return hdr.String() } // Validate checks that the fragment is self-consistent and appliable. Validate // returns an error if and only if the fragment is invalid. func (f *TextFragment) Validate() error { if f == nil { return errors.New("nil fragment") } var ( oldLines, newLines int64 leadingContext, trailingContext int64 contextLines, addedLines, deletedLines int64 ) // count the types of lines in the fragment content for i, line := range f.Lines { switch line.Op { case OpContext: oldLines++ newLines++ contextLines++ if addedLines == 0 && deletedLines == 0 { leadingContext++ } else { trailingContext++ } case OpAdd: newLines++ addedLines++ trailingContext = 0 case OpDelete: oldLines++ deletedLines++ trailingContext = 0 default: return fmt.Errorf("unknown operator %q on line %d", line.Op, i+1) } } // check the actual counts against the reported counts if oldLines != f.OldLines { return lineCountErr("old", oldLines, f.OldLines) } if newLines != f.NewLines { return lineCountErr("new", newLines, f.NewLines) } if leadingContext != f.LeadingContext { return lineCountErr("leading context", leadingContext, f.LeadingContext) } if trailingContext != f.TrailingContext { return lineCountErr("trailing context", trailingContext, f.TrailingContext) } if addedLines != f.LinesAdded { return lineCountErr("added", addedLines, f.LinesAdded) } if deletedLines != f.LinesDeleted { return lineCountErr("deleted", deletedLines, f.LinesDeleted) } // if a file is being created, it can only contain additions if f.OldPosition == 0 && f.OldLines != 0 { return errors.New("file creation fragment contains context or deletion lines") } return nil } func lineCountErr(kind string, actual, reported int64) error { return fmt.Errorf("fragment contains %d %s lines but reports %d", actual, kind, reported) } // Line is a line in a text fragment. type Line struct { Op LineOp Line string } func (fl Line) String() string { return fl.Op.String() + fl.Line } // Old returns true if the line appears in the old content of the fragment. func (fl Line) Old() bool { return fl.Op == OpContext || fl.Op == OpDelete } // New returns true if the line appears in the new content of the fragment. func (fl Line) New() bool { return fl.Op == OpContext || fl.Op == OpAdd } // NoEOL returns true if the line is missing a trailing newline character. func (fl Line) NoEOL() bool { return len(fl.Line) == 0 || fl.Line[len(fl.Line)-1] != '\n' } // LineOp describes the type of a text fragment line: context, added, or removed. type LineOp int const ( // OpContext indicates a context line OpContext LineOp = iota // OpDelete indicates a deleted line OpDelete // OpAdd indicates an added line OpAdd ) func (op LineOp) String() string { switch op { case OpContext: return " " case OpDelete: return "-" case OpAdd: return "+" } return "?" } // BinaryFragment describes changes to a binary file. type BinaryFragment struct { // Method is the method used to create and apply this fragment. Method BinaryPatchMethod // Size is the expected size of the uncompressed data in bytes. Size int64 // RawData is the base85-decoded but otherwise unmodified binary content of // the fragment. The contents must be decompressed with zlib before use, // usually by calling [BinaryFragment.Data]. RawData []byte } // BinaryPatchMethod is the method used to create and apply the binary patch. type BinaryPatchMethod int const ( // BinaryPatchDelta indicates the data uses Git's packfile encoding BinaryPatchDelta BinaryPatchMethod = iota // BinaryPatchLiteral indicates the data is the exact file content BinaryPatchLiteral ) // Data returns an io.Reader for the decompressed data in the fragment. Clients // should read until the reader returns an error or io.EOF. The reader returns // an error if the data cannot be decompressed or if the length of the // decompressed data does not equal the expected size. // // Reading all data may return up to Size+1 bytes. Clients reading data from // untrusted sources should check the value of Size or limit their reads. func (f *BinaryFragment) Data() io.Reader { return newBinaryReader(f) } // String returns a git diff format of this fragment. See [File.String] for // more details on this format. func (f *BinaryFragment) String() string { var diff strings.Builder newFormatter(&diff).FormatBinaryFragment(f) return diff.String() } |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |