fix: --base mode reads the base ref's tree; --since distinguishes empty-repo from no-match - #1
Merged
Merged
Conversation
β¦ --since distinguishes empty-repo from no-match
Two real bugs in the --base compare path and one in the --since
empty-result path, plus a related timezone-ambiguity fix in the
--since/--until argument format.
1. --base compare mode was reading the working tree for the file list
AND the working tree for the file content. With --base v1.0, the
'language line deltas sorted by magnitude' and the
'len(baseFilesAtHEAD)' file count were derived from the user's
uncommitted working tree versus itself, not from v1.0 versus HEAD.
baseCommits/baseContributors/baseHotFiles used baseRef correctly,
so the inconsistency made the commit/contributor/hot-file columns
right but the language column and the file-count metric wrong.
Fix: add FilesAtRef(repoPath, ref) and LinesByFileAtRef(repoPath,
ref). FilesAtRef uses 'git ls-tree -r --name-only <ref>' (the
committed tree of the ref, not the working tree).
LinesByFileAtRef walks the ref's tree, resolves each path's OID
via 'git ls-tree <ref> -- <path>', and reads the blob content
via 'git cat-file blob <oid>' so the working tree is irrelevant.
The existing FilesAtHEAD and LinesByFile are now thin wrappers
around the new functions (HEAD) and marked Deprecated in the doc
for the working-tree caller. main.go's --base branch now uses the
ref-parameterised versions explicitly.
The dead 'var _ = time.Time{}' placeholder in helpers.go is
removed (it was the only consumer of the 'time' import; the new
code doesn't need it, so the import is dropped too).
2. --since 2099-01-01 (or any future date) on a real repo used to
print 'repository has no commits' and exit 1 (exitNotARepo). The
repo is fine; --since just filtered everything out. The two
failure modes are now distinguished: empty repo (no --since)
keeps the original 'repository has no commits' + exit 1; --since
with no matches prints 'no commits match --since=<ts> (try an
earlier date or drop --since)' and exits 64 (exitUsage).
3. Related fix: log.go's --since=/--until= argument to git was
formatted as '2006-01-02T15:04:05' (no Z) even though the time
was already converted to UTC. The bare wall-clock form is
ambiguous β git on some systems interprets it as local time of
the host running dig. Append the Z so the argument is
unambiguous. The H2 fix's error message format string was
updated in lockstep.
go build, go vet, go test ./... all green. Verified with a real
binary: --base at commit 85e8268 produces a 22K delta report;
--since=2030-01-01T00:00:00Z prints the new no-match message and
exits 64.
NovaLux12
added a commit
that referenced
this pull request
Jul 2, 2026
β¦ --since distinguishes empty-repo from no-match (#1) Two real bugs in the --base compare path and one in the --since empty-result path, plus a related timezone-ambiguity fix in the --since/--until argument format. 1. --base compare mode was reading the working tree for the file list AND the working tree for the file content. With --base v1.0, the 'language line deltas sorted by magnitude' and the 'len(baseFilesAtHEAD)' file count were derived from the user's uncommitted working tree versus itself, not from v1.0 versus HEAD. baseCommits/baseContributors/baseHotFiles used baseRef correctly, so the inconsistency made the commit/contributor/hot-file columns right but the language column and the file-count metric wrong. Fix: add FilesAtRef(repoPath, ref) and LinesByFileAtRef(repoPath, ref). FilesAtRef uses 'git ls-tree -r --name-only <ref>' (the committed tree of the ref, not the working tree). LinesByFileAtRef walks the ref's tree, resolves each path's OID via 'git ls-tree <ref> -- <path>', and reads the blob content via 'git cat-file blob <oid>' so the working tree is irrelevant. The existing FilesAtHEAD and LinesByFile are now thin wrappers around the new functions (HEAD) and marked Deprecated in the doc for the working-tree caller. main.go's --base branch now uses the ref-parameterised versions explicitly. The dead 'var _ = time.Time{}' placeholder in helpers.go is removed (it was the only consumer of the 'time' import; the new code doesn't need it, so the import is dropped too). 2. --since 2099-01-01 (or any future date) on a real repo used to print 'repository has no commits' and exit 1 (exitNotARepo). The repo is fine; --since just filtered everything out. The two failure modes are now distinguished: empty repo (no --since) keeps the original 'repository has no commits' + exit 1; --since with no matches prints 'no commits match --since=<ts> (try an earlier date or drop --since)' and exits 64 (exitUsage). 3. Related fix: log.go's --since=/--until= argument to git was formatted as '2006-01-02T15:04:05' (no Z) even though the time was already converted to UTC. The bare wall-clock form is ambiguous β git on some systems interprets it as local time of the host running dig. Append the Z so the argument is unambiguous. The H2 fix's error message format string was updated in lockstep. go build, go vet, go test ./... all green. Verified with a real binary: --base at commit c93cd33 produces a 22K delta report; --since=2030-01-01T00:00:00Z prints the new no-match message and exits 64. Co-authored-by: Nova Lux <NovaLux12@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this PR does
Two real bugs in the
--basecompare path, one in the--sinceempty-result path, and a related timezone-ambiguity fix in the--since/--untilargument format.1.
--basemode was reading the working tree, not the base ref's treeWith
dig --base v1.0, the "language line deltas sorted by magnitude" and thelen(baseFilesAtHEAD)file-count metric were derived from the user's uncommitted working tree versus itself, not from v1.0 versus HEAD.baseCommits/baseContributors/baseHotFilesdid usebaseRefcorrectly, so the inconsistency made the commit / contributor / hot-file columns right but the language column and the file-count metric wrong.Root cause:
git.FilesAtHEADandgit.LinesByFilewere both called with no ref argument inmain.go:177/182.FilesAtHEADis OK (it shellsgit ls-tree -r --name-only HEADβ that's the ref's committed tree, not the working tree).LinesByFileis the offender: it walks the file list and then reads content viaos.ReadFile(filepath.Join(repoPath, rel))β that's the working tree, not even HEAD's blobs.Fix: add
FilesAtRef(repoPath, ref)andLinesByFileAtRef(repoPath, ref). The new file-lister is the same asFilesAtHEADbut takes an explicit ref (with HEAD as the default). The new line-counter walks the ref's tree, resolves each path's OID viagit ls-tree <ref> -- <path>, and reads the blob content viagit cat-file blob <oid>. The existingFilesAtHEADandLinesByFileare now thin wrappers (HEAD) and marked Deprecated in the doc for the working-tree caller.main.go's--basebranch now uses the ref-parameterised versions explicitly.Side cleanup: the dead
var _ = time.Time{}placeholder inhelpers.gois removed (it was the only consumer of thetimeimport; the new code doesn't need it, so the import is dropped too).2.
--since 2099-01-01on a real repo used to say "repository has no commits" and exit 1The repo is fine;
--sincejust filtered everything out. The two failure modes are now distinguished:--since): "repository has no commits" + exit 1 (unchanged)--sincewith no matches: "no commits match--since=<ts>(try an earlier date or drop--since)" + exit 64 (usage)3.
log.go's--since=/--until=argument to git was missing theZThe time was already converted to UTC at
opts.Since.UTC(), but the format string was"2006-01-02T15:04:05"(no Z). The bare wall-clock form is ambiguous β git on some systems interprets it as local time of the host runningdig. Append the Z so the argument is unambiguous. The H2 fix's error message format string was updated in lockstep.Verification
go build ./...β greengo vet ./...β greengo test ./...β 3 packages ok, 1 no testsdig --versionβ "dig dev"dig --out /tmp/dig-self.html .on this repo β 19,067-byte single-ref reportdig --base 85e8268 --out /tmp/dig-compare.html .β 22,482-byte delta report (new code path)dig --since 2030-01-01T00:00:00Z .β "no commits match--since=2030-01-01T00:00:00Z(try an earlier date or drop--since)" + exit 64 (new H2 behaviour)Risk
FilesAtHEADandLinesByFilebehaviour is unchanged when called as before (still HEAD, still working-tree-bytes). The deprecation notes are comments only.LinesByFileAtRefshells one extragit ls-tree <ref> -- <path>and onegit cat-file blob <oid>per file in the base's tree. For a small-to-medium repo this is a few extra seconds in--basemode only. Not used in the single-ref path.Zsuffix in--since/--untilis a behaviour change for callers that passed local-time strings (impossible βparseSincealready converts to UTC before this code runs) or relied on the no-zone form being interpreted as their local zone (that was the bug).