Skip to content

perf(trace): post-commit starts three git processes for each committed file #3756

Open

Description

@jiparis

Problem

The post-commit hook of Chainloop Trace starts 3 git processes for each committed file that has pending AI lines. A large commit makes the hook slow.

settleCommittedLines (app/cli/pkg/action/trace_hook_handler.go) calls client.FileAt(repoRoot, sha, path) one time for each pending path in each session. ExecClient.FileAt (app/cli/internal/trace/git/lines.go) runs these commands for each call:

  1. git rev-parse --verify --quiet <sha>^{commit}
  2. git cat-file -e <sha>:<path>
  3. git cat-file blob <sha>:<path>

The commit SHA is the same for all the files. Thus step 1 runs again for each file without a reason.

Measurement

Local clone of this repository (3.3k files). One commit changes 301 files, and all the changes are AI lines that are pending.

Item Value
Git processes that post-commit starts More than 900
Time of post-commit Approximately 5.2 s

This is on main. It is not caused by #3631.

Suggested fix

Read all the files with one git cat-file --batch process. Send one <sha>:<path> line for each path on stdin. For a path that is not in the commit, Git prints <sha>:<path> missing. Use this result as "no content", as FileAt does now. Resolve the commit one time before the loop.

For example, add a Client method that takes a revision and a list of paths and returns the content by path. The GoGitClient version can read the commit tree one time.

recordRootChanges (app/cli/pkg/action/trace_agent_hook.go) calls FileAt for each changed path in the same way, during PostToolUse for Bash calls. The same method can fix that caller too.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions