Next: (maak guix), Previous: (maak dsl), Up: API
The git commands a project’s Maak file usually wants, and the source archives it usually ships, as procedures rather than tasks. A Maak file decides which of them to expose, and under which names:
(define-module (maak) #:use-module (maak git))
(define (commit message) "Commit every tracked change." (git-commit message))
Every command goes through ‘run’, which hands the arguments to git as a list: a commit message with spaces or quotes reaches git as one argument, and no shell splits it again. Nothing here assumes a project layout – the archive helpers take the file name and the prefix, and ‘git’ itself takes ‘#:directory’ – so the same procedures serve a checkout here and one elsewhere.
‘git-output’ is the reading counterpart of ‘git’: it runs the same command and returns what git printed, which is what a task needs to make a decision (the current branch, the tags, whether the tree is dirty) rather than merely to show the user the output.
A command that fails stops the task with git’s own message and a maak error naming the command, the way any other ‘run’ does.
Run git with ARGUMENTS, a list of strings, in DIRECTORY.
This is what every wrapper below is made of, and the way to reach a
command that has no wrapper – git fetch, git reset, a
subcommand added tomorrow. Nothing is handed to a shell, so a value
with spaces in it stays one argument.
(git (list "fetch" "--all")) (git (list "log" "--oneline" "-3") #:directory "/path/to/checkout")
A command that exits non-zero raises a maak error naming it, unless ALLOW-FAILURE? is #t, in which case the call answers #f.
Stage PATHS, or every change in the tree when none is named.
Write REVISION as OUTPUT with git archive, under PREFIX, in FORMAT.
FORMAT is one git archive understands, tar.gz and zip
being the usual ones. PREFIX is the directory the archive unpacks into,
and it carries its own trailing slash. DIRECTORY is the checkout to
read from.
(git-archive "maak-1.0.tar.gz" #:prefix "maak-1.0/")
Write REVISION as the gzipped tarball OUTPUT, under PREFIX.
Write REVISION as the zip OUTPUT, under PREFIX.
Return the argv that runs git with ARGUMENTS in DIRECTORY.
The checkout is named with -C rather than by changing maak’s
working directory, so a task can read another checkout without
disturbing its own. Exposed because the argument list is the interface
every wrapper shares: a test can assert it, and a caller can log or
extend it without running git.
List the branches, or create the branches NAMES name.
Run git checkout with ARGUMENTS.
For a branch, git-switch says what it means; this wrapper is for
the rest of git checkout – restoring paths, detached commits,
--orphan.
Cherry-pick with any arguments git cherry-pick takes.
Remove untracked files with any arguments git clean takes.
git clean does nothing without -f; pass it, and -d
for directories, because there is no safer default that would still be
useful.
Clone URL into DIRECTORY, with BRANCH, DEPTH or BARE? when given.
git clone is the one command that cannot be pointed at a checkout
with -C, because the checkout it makes is the destination; the
destination is therefore the final argument rather than a decoration.
Without DIRECTORY git names the directory after the repository, exactly
as it does on the command line.
(git-clone "https://example.org/project.git" #:depth 1) (git-clone "../other" #:directory "vendor/other" #:branch "trunk")
Commit with MESSAGE, every tracked change by default.
ALL? is the -a that stages modified and deleted tracked files
without a separate git add; it is #t for the common case of
committing the working tree. AMEND? replaces the last commit,
ALLOW-EMPTY? makes a commit with no changes, and SIGN? signs it with the
configured GPG key.
(git-commit "fix: keep the config when it is missing") (git-commit "docs: typo" #:all? #f) ;; commit only what is staged
Read or write configuration with any arguments git config takes.
Return the branch the checkout in DIRECTORY is on.
A detached HEAD answers with the revision rather than the word HEAD, so a task that tags a release from CI still gets something it can record.
Return the full hash of the commit checked out in DIRECTORY.
Describe a commit, with any arguments git describe takes.
Return the most recent tag reachable from HEAD in DIRECTORY.
(git-describe-tag) ;; => v0.10.0
Show the changes between the working tree and the index, or as ARGUMENTS say.
Use --cached to compare the index with the last commit, or name
two revisions to compare them with each other.
Return #t when the checkout in DIRECTORY has anything uncommitted.
Both staged and unstaged changes count, as do untracked files: this is
the question git status --porcelain answers, rather than the
narrower one git diff --quiet answers.
Fetch from the remote, with any arguments git fetch takes.
Initialise a git repository here, with any arguments git init takes.
Show the history as a decorated one-line graph, twenty commits by default.
Merge with any arguments git merge takes.
Run git with ARGUMENTS in DIRECTORY and return what it printed.
This is the reading half of git: the output is a string the task
can trim, split and compare, not a line on the terminal. A command that
exits non-zero raises, unless ALLOW-FAILURE? is #t, in which case the
partial output is returned – the same contract as capture. In
dry-run mode nothing runs, the command is printed, and the empty string
comes back.
(string-trim (git-output (list "rev-parse" "--abbrev-ref" "HEAD")))
Pull from the upstream branch, with any arguments git pull takes.
Push the current branch, with any arguments git push takes.
A bare push does not send tags that are not annotated; (git-push
"--tags") sends them too.
Rebase with any arguments git rebase takes.
Manage remotes with any arguments git remote takes.
(git-remote (list "add" "origin" "https://example.org/project.git")) (git-remote (list "-v"))
Return the URL configured for remote NAME in DIRECTORY.
Return the names of the remotes configured in DIRECTORY, sorted.
Reset with any arguments git reset takes.
--soft and --mixed keep the changes; --hard throws
them away, which is what makes this wrapper worth naming explicitly in a
task.
Restore paths with any arguments git restore takes.
Ask git about revisions, with any arguments git rev-parse takes.
Revert with any arguments git revert takes.
Show a commit, tag or other object, with any arguments git show takes.
Stash with any arguments git stash takes.
The bare call saves the working tree; pass pop to bring it back,
or list to see what is saved.
Show the current branch and a short status of the working tree.
Manage submodules with any arguments git submodule takes.
Switch to BRANCH, creating it with CREATE? or discarding local changes with FORCE? when asked.
git switch is the modern spelling of the checkout half of
git checkout: it changes branches and nothing else, which is why
it is the default here.
Tag the current commit as NAME, without an annotation unless MESSAGE is given.
An annotated tag is what git push --follow-tags and most release
tooling expects, so passing MESSAGE is the usual choice for a release; a
lightweight tag is the default because it changes nothing in the
history.
(git-tag "v1.2.0" #:message "maak 1.2.0")
Return the names of the tags in DIRECTORY, sorted.
Next: (maak guix), Previous: (maak dsl), Up: API