phase 3 initial completion

This commit is contained in:
2026-05-07 00:22:45 +02:00
parent 5d8662595c
commit ce2aa2c776
19 changed files with 1216 additions and 37 deletions
+64
View File
@@ -138,3 +138,67 @@ func TreeLS(repoPath, ref, subPath string) ([]TreeEntry, error) {
func BlobCat(repoPath, ref, filePath string) ([]byte, error) {
return run(repoPath, "show", ref+":"+filePath)
}
// FileDiff represents a single changed file in a diff.
type FileDiff struct {
Path string `json:"path"`
OldPath string `json:"oldPath,omitempty"` // set on renames
Additions int `json:"additions"`
Deletions int `json:"deletions"`
Patch string `json:"patch"` // unified diff hunk(s) for this file
}
// Diff returns per-file diffs between two refs.
func Diff(repoPath, base, head string) ([]FileDiff, error) {
out, err := run(repoPath,
"diff", "--unified=5", "--no-color",
"--diff-filter=ACDMRT", // exclude untracked
base+".."+head,
)
if err != nil {
return nil, err
}
return parseUnifiedDiff(string(out)), nil
}
// parseUnifiedDiff splits a multi-file unified diff into per-file FileDiff entries.
func parseUnifiedDiff(raw string) []FileDiff {
var files []FileDiff
var cur *FileDiff
var patchLines []string
commit := func() {
if cur != nil {
cur.Patch = strings.Join(patchLines, "\n")
files = append(files, *cur)
}
}
for _, line := range strings.Split(raw, "\n") {
if strings.HasPrefix(line, "diff --git ") {
commit()
cur = &FileDiff{}
patchLines = nil
continue
}
if cur == nil {
continue
}
switch {
case strings.HasPrefix(line, "--- a/"):
cur.OldPath = strings.TrimPrefix(line, "--- a/")
case strings.HasPrefix(line, "+++ b/"):
cur.Path = strings.TrimPrefix(line, "+++ b/")
case strings.HasPrefix(line, "+") && !strings.HasPrefix(line, "+++"):
cur.Additions++
patchLines = append(patchLines, line)
case strings.HasPrefix(line, "-") && !strings.HasPrefix(line, "---"):
cur.Deletions++
patchLines = append(patchLines, line)
default:
patchLines = append(patchLines, line)
}
}
commit()
return files
}