Fix list breaking when the server's du fails

Two mistakes in the size support, reported from a real server.

The remote command used "2>/dev/null" to silence du. That is sh syntax,
and the git user's login shell need not be sh: in csh it parses as an
argument "2" followed by a redirection of stdout, so du was handed a
file named "2", complained, and exited non-zero. The redirection is
gone -- without it there is no bogus argument to trip over, and the
command now uses nothing that differs between sh and csh.

Worse, the exit status of the chain is the *last* command's, so that
failing du made sshOut return an error and `list` threw away a listing
that had arrived perfectly intact. It now reports a failure only when
nothing usable came back at all; a listing that parsed is shown whatever
the exit status, simply without the size column.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-26 17:35:50 +02:00
co-authored by Claude Opus 5
parent 3a420093d1
commit 86fb898df4
3 changed files with 74 additions and 7 deletions
+11 -6
View File
@@ -246,14 +246,12 @@ func runCommandDepth(line string, depth int) bool {
if !opt["a"] {
// archives are files and carry a real size; repositories are
// directories, whose listed size is the inode's, so ask du in the
// same round trip
remote += "; echo " + shq(listMarker) + "; du -sk *.git 2>/dev/null"
// same round trip. Nothing shell-specific here on purpose: the
// login shell may be csh, where "2>/dev/null" is not a redirection
// but an argument followed by one.
remote += "; echo " + shq(listMarker) + "; du -sk *.git"
}
lines, err := sshOut(remote)
if err != nil {
errorln("could not list " + many + " on the git server")
break
}
lsLines, duLines := splitAtMarker(lines, listMarker)
sizes := parseDuSizes(duLines)
@@ -272,7 +270,14 @@ func runCommandDepth(line string, depth int) bool {
total += e.size
entries = append(entries, e)
}
// The exit status belongs to the last command in the chain, so a `du`
// that fails must not discard a listing that arrived intact. Only
// complain when nothing usable came back at all.
if len(entries) == 0 {
if err != nil {
errorln("could not list " + many + " on the git server")
break
}
what := "no " + many + " on the git server"
if pat != "" {
what = "no " + many + " matching '" + word(words, 1) + "'"