mirror of
https://github.com/prdlk/gh-commit.git
synced 2026-09-16 23:16:25 +00:00
feat: rewrite gh-commit in Go with local Ollama backend
Replaces the Python/Crush/DuckDB implementation with a CGO-free Go binary: cobra CLI, modernc.org/sqlite storage, huh/lipgloss UI, and speed-tuned raw /api/generate calls (think:false, keep_alive, capped num_predict) against a local qwen3.5:2b. Ships as a gh extension via cli/gh-extension-precompile.
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
// Package diff filters git diffs before they reach the model: lock/generated
|
||||
// files lose their hunk bodies, JSON changes are capped, and every other file
|
||||
// is truncated. Behavior is a verbatim port of the Python filter_diff.
|
||||
package diff
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var lockPattern = regexp.MustCompile(
|
||||
`(package-lock\.json|yarn\.lock|pnpm-lock\.yaml|bun\.lockb|` +
|
||||
`go\.sum|go\.mod|Cargo\.lock|poetry\.lock|composer\.lock|Gemfile\.lock|` +
|
||||
`.*\.min\.(js|css)|.*\.bundle\.js|.*\.map|` +
|
||||
`dist/.*|build/.*|\.next/.*|node_modules/.*|vendor/.*|__pycache__/.*|\.pyc$|target/.*)`,
|
||||
)
|
||||
|
||||
var (
|
||||
fileNameRe = regexp.MustCompile(`b/([^ ]+)`)
|
||||
headerRe = regexp.MustCompile(`^(index|---|\+\+\+|@@)`)
|
||||
)
|
||||
|
||||
const (
|
||||
// MaxDiffLines caps the per-file line count for regular files.
|
||||
MaxDiffLines = 200
|
||||
// MaxJSONLines caps the +/- line count for JSON files.
|
||||
MaxJSONLines = 50
|
||||
)
|
||||
|
||||
// Filter rewrites a raw git diff for prompt consumption.
|
||||
func Filter(diff string) string {
|
||||
var lines []string
|
||||
inFiltered, inJSON := false, false
|
||||
lineCount, jsonCount := 0, 0
|
||||
|
||||
for _, line := range strings.Split(diff, "\n") {
|
||||
if strings.HasPrefix(line, "diff --git") {
|
||||
lineCount, jsonCount = 0, 0
|
||||
filename := ""
|
||||
if m := fileNameRe.FindStringSubmatch(line); m != nil {
|
||||
filename = m[1]
|
||||
}
|
||||
|
||||
switch {
|
||||
case lockPattern.MatchString(filename):
|
||||
inFiltered, inJSON = true, false
|
||||
lines = append(lines, line)
|
||||
continue
|
||||
case strings.HasSuffix(filename, ".json"):
|
||||
inFiltered, inJSON = false, true
|
||||
lines = append(lines, line)
|
||||
continue
|
||||
default:
|
||||
inFiltered, inJSON = false, false
|
||||
}
|
||||
}
|
||||
|
||||
// Lock/generated files: keep headers, replace each hunk body with a
|
||||
// marker. (The Python original stopped filtering after the first @@,
|
||||
// leaking hunk bodies; the spec requires bodies replaced, so filtering
|
||||
// holds until the next "diff --git".)
|
||||
if inFiltered {
|
||||
if headerRe.MatchString(line) {
|
||||
lines = append(lines, line)
|
||||
if strings.HasPrefix(line, "@@") {
|
||||
lines = append(lines, "[Generated/lock file - content filtered]")
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if inJSON {
|
||||
if headerRe.MatchString(line) {
|
||||
lines = append(lines, line)
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(line, "+") || strings.HasPrefix(line, "-") {
|
||||
jsonCount++
|
||||
if jsonCount <= MaxJSONLines {
|
||||
lines = append(lines, line)
|
||||
} else if jsonCount == MaxJSONLines+1 {
|
||||
lines = append(lines, fmt.Sprintf("[... JSON truncated after %d lines ...]", MaxJSONLines))
|
||||
}
|
||||
} else {
|
||||
lines = append(lines, line)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if lineCount < MaxDiffLines {
|
||||
lines = append(lines, line)
|
||||
lineCount++
|
||||
} else if lineCount == MaxDiffLines {
|
||||
lines = append(lines, fmt.Sprintf("[... truncated after %d lines ...]", MaxDiffLines))
|
||||
lineCount++
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
Reference in New Issue
Block a user