Keep git's own words in a fetch's reason: a bare "error:" line no longer stands for the forge's refusal
mesh/delivery merged: source.main moved to novox/mesh-sdk@1888d1d230b3
mesh/delivery-group group fix/fetch-reads-all merged: every member is merged
mesh/check pass ff81bdf8cc8f on 960d6c34d25e | unit 5815 run, 345 kept, 18 skipped | integration 5603 run, 640 kept, 29 skipped | over bound: unit, in…

The mirror of jschoubben/car-hunter on ace said only "git -C: error:": git writes a bare
"error:" before the forge's message, and the reason kept the first non-empty line. forgekey.Said
keeps every line that says something, leaves bare prefixes out, joins them and bounds them at
600 bytes; every git and ssh-keygen reason of buildstep and forgekey goes through it, and the
mirror's commands are named by their verb, not by -C.
This commit is contained in:
2026-10-26 15:26:29 +01:00
parent 75be8acbad
commit ff81bdf8cc
7 changed files with 88 additions and 20 deletions
+31 -4
View File
@@ -9,6 +9,7 @@ import (
"os/exec"
"strings"
"time"
"unicode/utf8"
)
// Ran is what a command did: its output, its exit status, and why it never ran to an answer.
@@ -108,11 +109,37 @@ func stableDir(clean bool, env []string) string {
return os.TempDir()
}
func firstLine(s string) string {
// SaidBound bounds what Said keeps of a command's words, so a reason stays a line of a step's record and of a log.
const SaidBound = 600
// Said is what a command said of its failure in its own words, for a reason: every line that says something, trimmed
// and joined with "; ", bounded at SaidBound bytes. A line that is a bare prefix and nothing else (git writes "error:"
// alone before and after the forge's own message, "remote:" or "fatal:" likewise) is left out, so the cause is never
// cut off behind it: the first line alone of `git fetch` from a repository the account cannot read was "error:".
func Said(s string) string {
var keep []string
for _, l := range strings.Split(s, "\n") {
if l = strings.TrimSpace(l); l != "" {
return l
l = strings.TrimSpace(l)
if l == "" || barePrefix(l) {
continue
}
keep = append(keep, l)
}
return ""
out := strings.Join(keep, "; ")
if len(out) > SaidBound {
cut := SaidBound
for cut > 0 && !utf8.RuneStart(out[cut]) {
cut--
}
out = out[:cut] + " …"
}
return out
}
// barePrefix says whether a line is one word and a colon, such as "error:" or "remote:", with nothing after it.
func barePrefix(l string) bool {
if !strings.HasSuffix(l, ":") {
return false
}
return !strings.ContainsAny(strings.TrimSuffix(l, ":"), " \t:")
}