Custom git subcommands
There are two ways to register custom subcommands for the git CLI tool. That allows you to define your own shortcuts and invoke them as if they were natively supported by git. For example, just like the built-in subcommands such as git checkout
or git diff
, you could come up with git mycrazycommand
and define custom behaviour for it.
The following sections demonstrate two possible techniques to define a custom subcommand: aliases (1) and dedicated shell scripts (2).
The sample command is called git changed-files
and it’s supposed to print a list of all file names (paths) that were changed in a particular commit(-ish). In both cases, you would e.g. use it like so: git changed-files 8f42b8f
.
(1) Alias
You can define aliases in your .gitconfig
file:
[alias]
changed-files = "diff-tree --no-commit-id --name-status -r"
Aliases – as the name would already indicate – are mainly useful for assigning brief shortcuts for otherwise lengthy git
invocations.
Two things to note here:
- git automatically passes on any input arguments to your alias by appending them
- By default, the base command is
git
. For running arbitrary commands, start the alias with a!
character, e.g.!echo 'Hello'
.
(2) Shell script
When invoked with a subcommand, git tries to resolve it by following a particular lookup procedure: it looks for an executable in your $PATH
, whose name is prefixed with git-
.1
E.g., when running git changed-files
, git would try to execute a git-changed-files
script, if that resides somewhere in $PATH
. This can be a regular bash script, like the following.
#!/bin/bash
git diff-tree --no-commit-id --name-status -r "$1"
Shell scripts lend themselves nicely for more complex procedures, which e.g. consist of multiple steps, or which require more sophisticated pre- or postprocessing.
-
Note: git actually uses this lookup procedure for built-in subcommands as well. See
GIT_EXEC_PATH
to learn more. ↩︎