git-cli
1 Command interface
git
git*
2 Provided commands
git-status
git-add
git-commit
git-push
git-pull
git-fetch
git-config
git-branch
git-remote
git-stash
git-restore
git-reset
git-revert
git-rebase
git-merge
git-cherry-pick
git-switch
git-clone
git-tag
git-rev-list
git-diff
git-log
git-show
git-grep
git-help
3 Package version
git-version
git-new-version
4 Low-level Git execution
run-git
5 Authentication retry
current-git-authentication-handler
exn:  fail:  git-auth?
exn:  fail:  git-auth-command
exn:  fail:  git-auth-args
exn:  fail:  git-auth-exit-code
exn:  fail:  git-auth-output
6 Authentication
default-git-authentication-handler
current-git-authentication-handler
9.3

git-cli🔗ℹ

Hans Dijkema

 (require git-cli) package: git-cli

The git-cli module provides a command-line-like Git interface implemented by invoking the git executable. Commands do not allow Git to read credentials or other answers from the terminal.

1 Command interface🔗ℹ

syntax

(git command argument ...)

Runs a registered Git command. The arguments are passed to the command. Registered command symbols are 'status, 'add, 'commit, 'push, 'pull, 'fetch, 'config, 'branch, 'remote, 'stash, 'restore, 'reset, 'revert, 'rebase, 'merge, 'cherry-pick, 'switch, 'clone, 'tag, 'log, 'rev-list, 'diff, 'show, 'grep, 'help, 'version, and 'new-version.

Most registered commands invoke the Git command with the same name. Some commands process the result into a Racket value, such as 'status, 'grep, 'log with list, 'version, and 'new-version.

syntax

(git* command argument ...)

Provides compact command-style syntax for git. The command name is used as a symbol. Other literal arguments are converted to strings.

(git* remote -v)
(git* switch main)

An argument written as (eval expression) is evaluated instead of being converted from its literal syntax.

(define branch "develop")
(git* switch (eval branch))

gt is retained as a compatibility alias for git*.

2 Provided commands🔗ℹ

procedure

(git-status argument ...)  list?

  argument : any/c
Runs git status porcelain with the supplied arguments.

Each result item has the form (index-status worktree-status file). The index status describes the change staged for the next commit. The worktree status describes the change in the working tree relative to the index.

Both statuses are one of 'unchanged, 'modified, 'type-changed, 'added, 'deleted, 'renamed, 'copied, 'unmerged, 'untracked, or 'ignored. For an untracked file, Git reports ??, so both statuses are 'untracked.

'((modified unchanged "staged.rkt")
  (unchanged modified "working-tree.rkt")
  (modified modified "both.rkt")
  (renamed unchanged "old.rkt -> new.rkt")
  (untracked untracked "new.rkt"))

procedure

(git-add argument ...)  boolean?

  argument : any/c
Adds file contents to the index. Returns #t when Git exits with status zero; otherwise an exception is raised.

procedure

(git-commit argument ...)  boolean?

  argument : any/c
Creates a commit. When -m is omitted, a commit message is requested before Git is started. A repository with nothing to commit returns #t. Other non-zero exit statuses, including a rejected commit hook, raise an exception.

procedure

(git-push argument ...)  boolean?

  argument : any/c
Pushes changes using porcelain. Returns #t when Git exits with status zero; otherwise an exception is raised.

procedure

(git-pull argument ...)  boolean?

  argument : any/c
Fetches and integrates changes. Normal progress written by Git to standard error is accepted when Git exits successfully.

procedure

(git-fetch argument ...)  boolean?

  argument : any/c
Downloads refs and objects from a remote repository without integrating them into the current branch. Arguments are passed directly to git fetch.

For example:

(git-fetch)
(git-fetch '--prune)
(git 'fetch '--prune)

procedure

(git-config argument ...)  any/c

  argument : any/c
Provides a Racket-oriented interface to git config. The same interface is available through git with command 'config.

(git 'config '--all)
(git 'config 'get '--all)
(git 'config '--global 'get '--all)
(git 'config 'get '--global '--all)

returns all visible configuration entries as key/value items:

'(("user.name" "Hans Dijkema")
  ("user.email" "hans@example.invalid")
  ("credential.helper" "manager"))

(git 'config 'get "credential.helper")

returns one value as a string, or #f when the key is absent.

(git 'config 'get '--all "credential.helper")

returns all values for one key as a list. An absent key produces the empty list.

Configuration values can be written with 'set!:

(git 'config 'set! "user.email" "hans@example.invalid")
(git 'config '--global 'set! "user.email" "hans@example.invalid")
(git 'config 'set! '--global "user.email" "hans@example.invalid")

The optional scope can be global, local, or system. It may appear directly after 'config or directly after 'get / 'set!. A successful write returns #t.

procedure

(git-branch argument ...)  (or/c boolean? list?)

  argument : any/c
Runs git branch with the supplied arguments. This can be used to list, create, rename, or delete branches according to the options supported by the installed Git executable.

With Git’s -l or list option, git-cli returns structured branch information. Each item starts with one of 'current, 'local, or 'remote, followed by the branch name.

(git-branch '-l)
 
'((current "main")
  (local "develop"))

Git’s normal branch selection and sorting options are passed through. For example, remote branches can be requested with -r, all branches with -a, and Git’s sort=<key> option controls the returned order.

(git 'branch '-l '-a "--sort=refname")
 
'((current "main")
  (local "develop")
  (remote "origin/main"))

Without -l or list, normal Git output is displayed and the procedure returns #t when Git exits successfully.

procedure

(git-remote argument ...)  any/c

  argument : any/c
Runs git remote with the supplied arguments and keeps the command’s own subcommand structure.

With no arguments, the remote names are returned as a Racket list.

(git-remote)
 
'("origin" "upstream")

With top-level -v or verbose, each line reported by Git is returned as a separate structured item containing the remote name, URL, and the 'fetch or 'push role.

(git-remote '-v)
 
'(("origin" "https://example.invalid/project.git" fetch)
  ("origin" "https://example.invalid/project.git" push))

The two Git lines are deliberately not merged. This keeps the result close to the output and semantics of git remote -v.

For get-url, one URL is returned as a string. With all, a list of URLs is returned.

(git 'remote 'get-url "origin")
(git 'remote 'get-url '--all "origin")
(git 'remote 'get-url '--push '--all "origin")

Other forms, including add, rename, remove, set-head, show, prune, update, set-branches, and set-url, are passed to Git unchanged and use the normal git-cli command result processing.

procedure

(git-stash argument ...)  (or/c boolean? list?)

  argument : any/c
Runs git stash with the supplied arguments. Calling it without a subcommand keeps Git’s normal behavior, which is equivalent to git stash push.

git stash list is returned as structured Racket data. Each item contains the stash reference and Git’s stash description.

(git-stash 'list)
 
'(("stash@{0}" "WIP on main: 1234567 Example")
  ("stash@{1}" "On main: older work"))

The structured form is only used when the caller has not supplied a format or pretty option. Explicit Git formatting is left unchanged.

Other stash subcommands, including push, show, pop, apply, drop, clear, branch, create, store, export, and import, are passed to Git unchanged.

procedure

(git-restore argument ...)  boolean?

  argument : any/c
Runs git restore with the supplied arguments. Git’s path, source, staged, worktree, and patch semantics are preserved.

(git-restore "main.rkt")
(git-restore '--staged "main.rkt")
(git* restore --source=HEAD~1 main.rkt)

procedure

(git-reset argument ...)  boolean?

  argument : any/c
Runs git reset with the supplied arguments. Modes such as soft, mixed, hard, merge, and keep, as well as path forms, are passed through unchanged.

(git-reset '--hard 'HEAD)
(git* reset --soft HEAD~1)

procedure

(git-revert argument ...)  boolean?

  argument : any/c
Runs git revert with the supplied arguments. Sequencer controls such as continue, skip, quit, and abort are passed through unchanged.

(git-revert 'HEAD)
(git* revert --abort)

procedure

(git-rebase argument ...)  boolean?

  argument : any/c
Runs git rebase with the supplied arguments, including normal, interactive, and continuation/abort forms.

(git-rebase "main")
(git* rebase --continue)
(git* rebase --abort)

procedure

(git-merge argument ...)  boolean?

  argument : any/c
Runs git merge with the supplied arguments and preserves Git’s merge options and control forms.

(git-merge "feature")
(git* merge --abort)

procedure

(git-cherry-pick argument ...)  boolean?

  argument : any/c
Runs git cherry-pick with the supplied arguments. Sequencer controls such as continue, skip, quit, and abort are passed through unchanged.

(git-cherry-pick "abc1234")
(git* cherry-pick --continue)

procedure

(git-switch argument ...)  boolean?

  argument : any/c
Runs git switch with the supplied arguments.

(git-switch "main")
(git-switch '-c "feature")
(git 'switch "main")

procedure

(git-clone argument ...)  boolean?

  argument : any/c
Runs git clone with the supplied arguments.

procedure

(git-tag argument ...)  (or/c boolean? list?)

  argument : any/c
Runs git tag with the supplied arguments. It can list, create, delete, or verify tags according to the options supported by Git.

When -l or list is supplied, the matching tag names are returned as a Racket list. Git’s sorting options are passed through unchanged, so the returned list keeps Git’s order.

(git-tag '-l)
(git-tag '--list "--sort=version:refname")
(git-tag '--list "--sort=-creatordate")

When -n or -n1 is combined with -l or list, each result item contains the tag name and the subject reported by Git.

(git-tag '-l '-n)
 
'(("v0.3.16" "Release 0.3.16")
  ("v0.3.17" "Release 0.3.17"))

With -n<number> and a number greater than one, git-cli asks Git for that many content lines using %(contents:lines=<number>). The returned message is kept as one string, including embedded newlines.

For structured tag output git-cli asks Git for an explicit format using %(refname:strip=2) and either %(contents:subject) or %(contents:lines=<number>). Generated field and record delimiters are used to split the result safely.

Other forms keep the normal command behavior and return #t when Git exits successfully. Git errors are handled by the standard git-cli result processor.

procedure

(git-rev-list argument ...)  boolean?

  argument : any/c
Runs git rev-list with the supplied arguments and displays Git’s normal output. It returns #t when Git exits successfully.

procedure

(git-diff argument ...)  (or/c boolean? string?)

  argument : any/c
Shows differences between Git objects or the working tree and index.

By default a successful diff is rendered as HTML in the default browser. The git-cli-specific option output=- keeps Git’s textual output on standard output. output=string returns the textual diff as a string.

(git-diff)
(git-diff '--cached)
(git-diff '--output=-)
(git-diff '--output=string)

procedure

(git-log argument ...)  (or/c boolean? list?)

  argument : any/c
Displays Git log output and returns #t when Git exits successfully.

The git-cli-specific option list, or its short form -l, changes the result to a Racket list. Internally this option is replaced by Git’s oneline option. Each returned item contains the abbreviated commit id and the commit subject.

(git-log '--list '-5)
 
'(("003f371" "Diverse commando's toegevoegd. Ik weet nog niet of ik ze allemaal ga houden")
  ("2cb7e93" "Small changes. git main function is now a real function, not syntax"))

Other Git log options are still passed to Git. Consequently, options that add extra output lines can also influence how useful list is as a structured result.

procedure

(git-show argument ...)  (or/c boolean? string? list?)

  argument : any/c
Shows a Git object.

For a commit that includes a patch, the default git-cli output is HTML. The commit information is shown above the diff and the diff is rendered using the same Diff2Html presentation as git-diff.

The git-cli-specific output options are output=html, output=-, and output=string. output=html explicitly selects the HTML presentation, output=- keeps Git’s normal textual output, and output=string returns that textual output as a string. Options such as stat, name-only, name-status, and no-patch default to textual output because they do not normally contain a patch.

The git-cli-specific option list, or its short form -l, returns a Racket value. Without another show-format option it implies stat.

(git-show '-l "9741b1c")

The result of stat list contains 'file and 'total items:

'((file "README.md" 67 "+++---")
  (file "main.rkt" 532 "++++-------------------------------------------")
  (total 9 124 823))

With name-only list, the result is a list of file names. With name-status list, every result item is the tab-separated Git name-status record converted to a list of strings.

list/-l cannot be combined with output=.... Only one of stat, name-only, and name-status can be used with list.

procedure

(git-grep argument ...)  list?

  argument : any/c
Searches tracked files. Each result contains the file, optional line number, optional match count, and matched text. Exit status one means that no matches were found and returns an empty list.

procedure

(git-help argument ...)  boolean?

  argument : any/c
Runs git help with the supplied arguments and returns #t when Git exits successfully.

3 Package version🔗ℹ

procedure

(git-version)  list?

Reads the package version from "info.rkt" and returns it as a list containing major, minor, and patch.

procedure

(git-new-version kind)  list?

  kind : symbol?
Updates the version in "info.rkt". The kind is 'major, 'minor, or 'patch, with 'maj and 'min as abbreviations. The result is the new version as a list of three integers.

4 Low-level Git execution🔗ℹ

procedure

(run-git args [#:input input])  
exact-integer? list?
  args : list?
  input : (or/c #f string?) = #f
Runs Git without interactive terminal prompts. When input is a string, it is written to Git’s standard input before that input port is closed.

The procedure returns two values: Git’s exit code and the ordered output items, where each item identifies either 'stdout or 'stderr.

(run-git '(credential fill)
         #:input "protocol=https\nhost=git.dijkewijk.nl\n\n")

5 Authentication retry🔗ℹ

Git commands recognize common authentication failures immediately after the Git process finishes and before command-specific result processing takes place. Such a failure is represented by exn:fail:git-auth?.

Controls the callback used when an authentication failure is detected. The callback receives the Git command symbol, the processed Git argument list and the exn:fail:git-auth exception.

The callback returns a true value when it has handled authentication and the original Git command should be tried again. A command is retried at most once. The default callback is default-git-authentication-handler.

(current-git-authentication-handler
 (lambda (cmd args e)
 
   #t))

procedure

(exn:fail:git-auth? v)  boolean?

  v : any/c
Recognizes the authentication exception used internally by git-cli.

Returns the Git command of the failed invocation.

procedure

(exn:fail:git-auth-args e)  list?

  e : exn:fail:git-auth?
Returns the processed Git arguments of the failed invocation.

Returns Git’s exit code.

Returns the ordered 'stdout/'stderr output items from the failed Git process.

6 Authentication🔗ℹ

procedure

(default-git-authentication-handler cmd    
  args    
  e)  boolean?
  cmd : symbol?
  args : list?
  e : exn:fail:git-auth?
Handles one authentication failure. A credential that already failed is first rejected. An existing Git credential helper is then asked for a replacement credential. If that does not succeed, git-cli requests a username and password/token using input-prompt. Its #:loop-until callbacks both validate the input and return the value that is used. If no helper is configured, Git’s non-persistent cache helper is configured locally before the credential is approved. The original command is retried once; a credential that fails on the retry is rejected before the Git error is raised.

Contains the authentication callback used after a recognized authentication failure. Its default value is default-git-authentication-handler.