DiffRaw parses raw git diff output (git diff --raw). Each entry (a line) is a changed file. The format is: :100644 100644 NULL NULL Old-hash and new-hash are the file object hashes. Status can be A added, D deleted, M modified, R renamed, C copied. When the
(r io.Reader)
| 62 | // |
| 63 | // :100644 100644 <old-hash> <new-hash> R<similarity index>NULL<old-name>NULL<new-name>NULL |
| 64 | func DiffRaw(r io.Reader) ([]DiffRawFile, error) { |
| 65 | var result []DiffRawFile |
| 66 | |
| 67 | scan := bufio.NewScanner(r) |
| 68 | scan.Split(ScanZeroSeparated) |
| 69 | for scan.Scan() { |
| 70 | s := scan.Text() |
| 71 | groups := regexpDiffRaw.FindStringSubmatch(s) |
| 72 | if groups == nil { |
| 73 | continue |
| 74 | } |
| 75 | |
| 76 | var oldPath, path string |
| 77 | |
| 78 | if !scan.Scan() { |
| 79 | return nil, fmt.Errorf("failed to get path for the entry: %q; err=%w", s, scan.Err()) |
| 80 | } |
| 81 | |
| 82 | path = scan.Text() |
| 83 | |
| 84 | status := DiffStatus(groups[5][0]) |
| 85 | switch status { |
| 86 | case DiffStatusRenamed, DiffStatusCopied: |
| 87 | if !scan.Scan() { |
| 88 | return nil, fmt.Errorf("failed to get new path for the entry: %q; err=%w", s, scan.Err()) |
| 89 | } |
| 90 | |
| 91 | oldPath, path = path, scan.Text() |
| 92 | case DiffStatusAdded, DiffStatusDeleted, DiffStatusModified, DiffStatusType: |
| 93 | default: |
| 94 | return nil, fmt.Errorf("got invalid raw diff status=%c for entry %s %s", status, s, path) |
| 95 | } |
| 96 | |
| 97 | result = append(result, DiffRawFile{ |
| 98 | OldFileMode: groups[1], |
| 99 | NewFileMode: groups[2], |
| 100 | OldBlobSHA: groups[3], |
| 101 | NewBlobSHA: groups[4], |
| 102 | Status: status, |
| 103 | OldPath: oldPath, |
| 104 | Path: path, |
| 105 | }) |
| 106 | } |
| 107 | if err := scan.Err(); err != nil { |
| 108 | return nil, fmt.Errorf("failed to scan raw diff: %w", scan.Err()) |
| 109 | } |
| 110 | |
| 111 | return result, nil |
| 112 | } |
| 113 | |
| 114 | type BatchCheckObject struct { |
| 115 | SHA sha.SHA |