Skip to content

Agent Git tab log ids contain leading newlines and break parent matching #666

Description

@HaningZS

What happened?

getLog() returns commit ids with a leading newline on every row after the first. Git inserts a newline between --pretty=format: records, after the record separator appended by this function. Splitting at \x1e leaves that newline attached to the next %H, and getLog() exposes it unchanged as sha (and slices it into shortSha).

This affects the agent detail panel's Git tab: GitTab.tsx calls window.cth.gitLog() and passes the result to CommitGraph. A real three-commit linear history is laid out as lanes [0, 1, 2] instead of [0, 0, 0], because child parent ids no longer match the returned commit ids. The graph then treats visible parents as outside the fetched window.

It also breaks the revision API contract: getCommitFiles(cwd, commits[1].sha) and getFileAtRev(...) reject these returned ids as invalid revision through isSafeRev().

Scope: the IDE History pane uses the separate getLogGraph() path, which already trims its SHA fields and does not exhibit this defect. This report concerns getLog()/git:log and its agent Git-tab consumer.

Steps to reproduce

  1. Create a temporary Git repository with three ordinary linear commits.
  2. On public main at f44b986a, call getLog(cwd, 3) from src/main/git.ts.
  3. Inspect JSON.stringify(commits.map(c => c.sha)): second and subsequent ids contain \n at the beginning; their shortSha fields also include it.
  4. Pass the list to the production layoutGraph() used by CommitGraph; its row lanes are [0, 1, 2] despite the linear history.
  5. Pass the second returned id to getCommitFiles() or getFileAtRev(); it is rejected as an invalid revision.

Executable regression tests using real Git repositories cover these steps, as well as merge history, tags, metadata, limited results and empty results. They do not mock Git or the application's log/revision functions.

Expected behavior

Every returned full and short SHA should match Git's actual id, and parent ids should match the corresponding history rows. The returned full ids should work with the application's existing revision APIs, without changing their validation rules or other commit metadata.

Evidence

The same final 8-test suite against unchanged main fails all 8 tests. This image renders actual node:test output, not a screenshot of the GUI:

Before: invalid getLog revisions and incorrect graph lanes

Environment and verification

  • Source revision: f44b986a4dd6490179a60a55db0a32e2f498f9ea, package.json version 0.4.6.
  • macOS 26.4.1, Apple Silicon; Node.js v24.13.0; Git 2.52.0.
  • Reproduced through the actual Git/log/layout/revision functions; native GUI smoke tests were not run.
  • Searched existing issues/PRs for getLog, newline/SHA and Git graph reports; no duplicate found. This is independent of fix: getStatus consumes the second path of porcelain -z rename records #572's porcelain status/rename parsing fix.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions