KogenCredo.Diff.Git (KogenCredo v0.1.0)
View SourceRead-only git access for the diff runner.
Git is always started with System.cmd/3 and an argument list, never through a shell. User
input is validated before it reaches git: revision strings may only contain
[A-Za-z0-9_./@{}~^+-], must not start with -, and must not contain .. inside a side;
paths must be relative, free of control characters, .. segments and leading - or :.
Pathspecs are interpreted relative to the --repo directory: when --repo is a subdirectory
of the work tree, lib/ means <subdirectory>/lib/ (the prefix comes from
git rev-parse --show-prefix) and is then anchored at the repository top (:(top)).
Reported file names are always rooted at the repository top (--no-relative is forced, so a
repository-local diff.relative setting cannot change them). A path that matches nothing in
either the base or the head tree is an error, never an empty success.
Inherited git routing and pathspec variables (GIT_DIR, GIT_WORK_TREE, GIT_INDEX_FILE,
GIT_CONFIG_PARAMETERS, GIT_LITERAL_PATHSPECS, ...) are removed from git's environment, so
--repo is always the repository that is read, also when run from a git hook.
Revisions are resolved to full object ids first and only those ids are used afterwards.
Only read-only rev-parse, merge-base, diff, hash-object and cat-file commands run;
no Git objects, refs or repository files are written. Temporary files are cleaned up.
Any git failure is returned as {:error, message}; control characters in git's messages are
escaped so repository content cannot forge extra output lines.
Standard output and standard error are captured separately (through sh when it exists), so a
git warning can never corrupt a -z listing or a file's contents. A revision name that is
both a branch and a tag resolves by git's own precedence; pass a full ref or a SHA to be
explicit.
Summary
Functions
Changed .ex files between two commits, with renames detected.
Fails unless every path (relative to repo) matches at least one file in the base or the
head tree, so a wrong default (subproject, umbrella root) cannot yield an empty success.
Parses and validates A..B or A...B.
Resolves a parsed range to {base_sha, head_sha}. Three-dot ranges use the merge base.
File contents at a commit.
Validates repo-relative path filters.
Checks that the repository path is an existing directory.
Types
Functions
@spec changed_files(String.t(), String.t(), String.t(), [String.t()]) :: {:ok, [entry()]} | {:error, String.t()}
Changed .ex files between two commits, with renames detected.
Fails unless every path (relative to repo) matches at least one file in the base or the
head tree, so a wrong default (subproject, umbrella root) cannot yield an empty success.
Parses and validates A..B or A...B.
Resolves a parsed range to {base_sha, head_sha}. Three-dot ranges use the merge base.
File contents at a commit.
Validates repo-relative path filters.
Checks that the repository path is an existing directory.