Thin adapter over the git plumbing commands presubmit relies on.
Every function takes the repository path first and returns tagged tuples;
run!/2 is the only place a shell command is executed. Keeping the surface
this small is what lets the rest of the library be tested against
in-memory trees.
Summary
Functions
Reads many blobs of tree in one process: git archive of the given paths,
extracted in memory. Every path must exist in the tree (git refuses a
pathspec that matches nothing); blobs excluded by export-ignore are
simply absent from the result.
Reads commit metadata and the raw message body for rev.
Reads a git configuration value as git itself would resolve it, or nil.
Diffs two trees with rename detection, returning one entry per changed path.
Whether anything on disk differs from HEAD: staged or unstaged edits, or
untracked files that are not ignored.
Returns the object id of the empty tree for this repository's hash algorithm.
Lists every blob path in tree.
Returns true when rev names an object that exists locally.
Reads the blob at path in tree.
Resolves rev to a full object id.
Runs git with args inside repo.
Runs git with args inside repo, raising Presubmit.GitError on
a non-zero exit.
Returns true when sha is a shallow-clone boundary: a commit whose real
parents were cut off by --depth. Git reports such commits as parentless,
so this is the only way to tell them apart from a genuine root commit.
Writes the current index to a tree object and returns its id.
Writes the working directory to a tree object and returns its id, without touching the repository's own index.
Types
@type commit_info() :: %{ sha: oid(), tree: oid(), parents: [oid()], author: %{name: String.t(), email: String.t(), date: DateTime.t()}, committer: %{name: String.t(), email: String.t(), date: DateTime.t()}, body: String.t() }
Metadata for a single commit as read by commit_info/2.
@type oid() :: String.t()
@type raw_entry() :: %{ status: :added | :modified | :deleted | :renamed | :copied | :type_changed, old_path: String.t() | nil, new_path: String.t() | nil, old_mode: String.t(), new_mode: String.t(), score: non_neg_integer() | nil }
One record from git diff-tree --raw.
score is the similarity percentage for renames and copies, nil otherwise.
@type repo() :: Path.t()
Functions
@spec archive(repo(), oid(), [String.t()]) :: {:ok, %{optional(String.t()) => binary()}} | {:error, Presubmit.GitError.t()}
Reads many blobs of tree in one process: git archive of the given paths,
extracted in memory. Every path must exist in the tree (git refuses a
pathspec that matches nothing); blobs excluded by export-ignore are
simply absent from the result.
@spec commit_info(repo(), String.t()) :: {:ok, commit_info()} | {:error, Presubmit.GitError.t()}
Reads commit metadata and the raw message body for rev.
Reads a git configuration value as git itself would resolve it, or nil.
@spec diff_trees(repo(), oid(), oid()) :: {:ok, [raw_entry()]} | {:error, Presubmit.GitError.t()}
Diffs two trees with rename detection, returning one entry per changed path.
Whether anything on disk differs from HEAD: staged or unstaged edits, or
untracked files that are not ignored.
Returns the object id of the empty tree for this repository's hash algorithm.
@spec ls_tree(repo(), oid()) :: {:ok, [String.t()]} | {:error, Presubmit.GitError.t()}
Lists every blob path in tree.
Returns true when rev names an object that exists locally.
Reads the blob at path in tree.
@spec rev_parse(repo(), String.t()) :: {:ok, oid()} | {:error, Presubmit.GitError.t()}
Resolves rev to a full object id.
@spec run(repo(), [String.t()], [{String.t(), String.t()}]) :: {:ok, binary()} | {:error, Presubmit.GitError.t()}
Runs git with args inside repo.
Runs git with args inside repo, raising Presubmit.GitError on
a non-zero exit.
The user's git configuration is honoured (so safe.directory, credential
and transport settings apply); every plumbing call passes the flags that
make its output independent of configuration (-z, --no-color,
explicit --format, --no-show-signature).
Returns true when sha is a shallow-clone boundary: a commit whose real
parents were cut off by --depth. Git reports such commits as parentless,
so this is the only way to tell them apart from a genuine root commit.
@spec write_index_tree(repo()) :: {:ok, oid()} | {:error, Presubmit.GitError.t()}
Writes the current index to a tree object and returns its id.
This is how the staged change set gets a tree that the rest of the pipeline can treat exactly like a commit's tree. Writing a tree object never touches refs or the working directory.
@spec write_worktree_tree(repo()) :: {:ok, oid()} | {:error, Presubmit.GitError.t()}
Writes the working directory to a tree object and returns its id, without touching the repository's own index.
A temporary index is seeded from HEAD (or left empty on an unborn
branch), everything on disk is added to it honouring .gitignore, and the
result is written as a tree. Only loose objects are created; git gc
reclaims them.