Next: , Previous: , Up: API  


1.4 (maak git)

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.

1.4.1 Procedures

Procedure: git arguments KEY: #:directory #:allow-failure? #:verbose?

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.

Procedure: git-add . paths

Stage PATHS, or every change in the tree when none is named.

Procedure: git-archive output KEY: #:format #:prefix #:revision #:directory

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/")
Procedure: git-archive-tar output KEY: #:prefix #:revision #:directory

Write REVISION as the gzipped tarball OUTPUT, under PREFIX.

Procedure: git-archive-zip output KEY: #:prefix #:revision #:directory

Write REVISION as the zip OUTPUT, under PREFIX.

Procedure: git-argv arguments KEY: #:directory

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.

Procedure: git-branch . names

List the branches, or create the branches NAMES name.

Procedure: git-checkout . arguments

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.

Procedure: git-cherry-pick . arguments

Cherry-pick with any arguments git cherry-pick takes.

Procedure: git-clean . arguments

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.

Procedure: git-clone url KEY: #:directory #:branch #:depth #:bare? #:verbose?

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")
Procedure: git-commit message KEY: #:all? #:amend? #:allow-empty? #:sign?

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
Procedure: git-config . arguments

Read or write configuration with any arguments git config takes.

Procedure: git-current-branch KEY: #:directory

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.

Procedure: git-current-revision KEY: #:directory

Return the full hash of the commit checked out in DIRECTORY.

Procedure: git-describe . arguments

Describe a commit, with any arguments git describe takes.

Procedure: git-describe-tag KEY: #:directory

Return the most recent tag reachable from HEAD in DIRECTORY.

(git-describe-tag)   ;; => v0.10.0
Procedure: git-diff . arguments

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.

Procedure: git-dirty? KEY: #:directory

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.

Procedure: git-fetch . arguments

Fetch from the remote, with any arguments git fetch takes.

Procedure: git-init . arguments

Initialise a git repository here, with any arguments git init takes.

Procedure: git-log . arguments

Show the history as a decorated one-line graph, twenty commits by default.

Procedure: git-merge . arguments

Merge with any arguments git merge takes.

Procedure: git-output arguments KEY: #:directory #:allow-failure?

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")))
Procedure: git-pull . arguments

Pull from the upstream branch, with any arguments git pull takes.

Procedure: git-push . arguments

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.

Procedure: git-rebase . arguments

Rebase with any arguments git rebase takes.

Procedure: git-remote . arguments

Manage remotes with any arguments git remote takes.

(git-remote (list "add" "origin" "https://example.org/project.git"))
(git-remote (list "-v"))
Procedure: git-remote-url name KEY: #:directory

Return the URL configured for remote NAME in DIRECTORY.

Procedure: git-remotes KEY: #:directory

Return the names of the remotes configured in DIRECTORY, sorted.

Procedure: git-reset . arguments

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.

Procedure: git-restore . arguments

Restore paths with any arguments git restore takes.

Procedure: git-rev-parse . arguments

Ask git about revisions, with any arguments git rev-parse takes.

Procedure: git-revert . arguments

Revert with any arguments git revert takes.

Procedure: git-show . arguments

Show a commit, tag or other object, with any arguments git show takes.

Procedure: git-stash . arguments

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.

Procedure: git-status

Show the current branch and a short status of the working tree.

Procedure: git-submodule . arguments

Manage submodules with any arguments git submodule takes.

Procedure: git-switch branch KEY: #:create? #:force?

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.

Procedure: git-tag name KEY: #:message #:force?

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")
Procedure: git-tags KEY: #:directory

Return the names of the tags in DIRECTORY, sorted.


Next: (maak guix), Previous: (maak dsl), Up: API