Adding a new built-in
There are 4 things to do to add a built-in command implementation to Git:
-
Define the implementation of the built-in command
foowith signature:int cmd_foo(int argc, const char **argv, const char *prefix); -
Add the external declaration for the function to
builtin.h. -
Add the command to the
commands[]table defined ingit.c. The entry should look like:{ "foo", cmd_foo, <options> },where options is the bitwise-or of:
-
RUN_SETUP -
If there is not a Git directory to work on, abort. If there is a work tree, chdir to the top of it if the command was invoked in a subdirectory. If there is no work tree, no chdir() is done.
-
RUN_SETUP_GENTLY -
If there is a Git directory, chdir as per RUN_SETUP, otherwise, don’t chdir anywhere.
-
USE_PAGER -
If the standard output is connected to a tty, spawn a pager and feed our output to it.
-
NEED_WORK_TREE -
Make sure there is a work tree, i.e. the command cannot act on bare repositories. This only makes sense when
RUN_SETUPis also set.
-
-
Add
builtin/foo.otoBUILTIN_OBJSinMakefile.
Additionally, if foo is a new command, there are 3 more things to do:
-
Add tests to
t/directory. -
Write documentation in
Documentation/git-foo.txt. -
Add an entry for
git-footocommand-list.txt. -
Add an entry for
/git-footo.gitignore.
How a built-in is called
The implementation cmd_foo() takes three parameters, argc, argv,
and `prefix. The first two are similar to what main() of a
standalone command would be called with.
When RUN_SETUP is specified in the commands[] table, and when you
were started from a subdirectory of the work tree, cmd_foo() is called
after chdir(2) to the top of the work tree, and prefix gets the path
to the subdirectory the command started from. This allows you to
convert a user-supplied pathname (typically relative to that directory)
to a pathname relative to the top of the work tree.
The return value from cmd_foo() becomes the exit status of the
command.