G.4. Misc


G.4. Misc

G.4.1. gitcli(7)


gitcli - Git command-line interface and conventions




This manual describes the convention used throughout Git CLI.

Many commands take revisions (most often "commits", but sometimes "tree-ish", depending on the context and command) and paths as their arguments. Here are the rules:

  • Revisions come first and then paths. E.g. in git diff v1.0 v2.0 arch/x86 include/asm-x86, v1.0 and v2.0 are revisions and arch/x86 and include/asm-x86 are paths.
  • When an argument can be misunderstood as either a revision or a path, they can be disambiguated by placing -- between them. E.g. git diff -- HEAD is, "I have a file called HEAD in my work tree. Please show changes between the version I staged in the index and what I have in the work tree for that file", not "show difference between the HEAD commit and the work tree as a whole". You can say git diff HEAD -- to ask for the latter.
  • Without disambiguating --, Git makes a reasonable guess, but errors out and asking you to disambiguate when ambiguous. E.g. if you have a file called HEAD in your work tree, git diff HEAD is ambiguous, and you have to say either git diff HEAD -- or git diff -- HEAD to disambiguate.

    When writing a script that is expected to handle random user-input, it is a good practice to make it explicit which arguments are which by placing disambiguating -- at appropriate places.

  • Many commands allow wildcards in paths, but you need to protect them from getting globbed by the shell. These two mean different things:

    $ git checkout -- *.c
    $ git checkout -- \*.c

    The former lets your shell expand the fileglob, and you are asking the dot-C files in your working tree to be overwritten with the version in the index. The latter passes the *.c to Git, and you are asking the paths in the index that match the pattern to be checked out to your working tree. After running git add hello.c; rm hello.c, you will not see hello.c in your working tree with the former, but with the latter you will.

  • Just as the filesystem . (period) refers to the current directory, using a . as a repository name in Git (a dot-repository) is a relative path and means your current repository.

Here are the rules regarding the "flags" that you should follow when you are scripting Git:

  • it's preferred to use the non-dashed form of Git commands, which means that you should prefer git foo to git-foo.
  • splitting short options to separate words (prefer git foo -a -b to git foo -ab, the latter may not even work).
  • when a command-line option takes an argument, use the stuck form. In other words, write git foo -oArg instead of git foo -o Arg for short options, and git foo --long-opt=Arg instead of git foo --long-opt Arg for long options. An option that takes optional option-argument must be written in the stuck form.
  • when you give a revision parameter to a command, make sure the parameter is not ambiguous with a name of a file in the work tree. E.g. do not write git log -1 HEAD but write git log -1 HEAD --; the former will not work if you happen to have a file called HEAD in the work tree.
  • many commands allow a long option --option to be abbreviated only to their unique prefix (e.g. if there is no other option whose name begins with opt, you may be able to spell --opt to invoke the --option flag), but you should fully spell them out when writing your scripts; later versions of Git may introduce a new option whose name shares the same prefix, e.g. --optimize, to make a short prefix that used to be unique no longer unique.


From the Git 1.5.4 series and further, many Git commands (not all of them at the time of the writing though) come with an enhanced option parser.

Here is a list of the facilities provided by this option parser.

1. Magic Options

Commands which have the enhanced option parser activated all understand a couple of magic command-line options:


gives a pretty printed usage of the command.

$ git describe -h
usage: git describe [options] <commit-ish>*
   or: git describe [options] --dirty

    --contains            find the tag that comes after the commit
    --debug               debug search strategy on stderr
    --all                 use any ref
    --tags                use any tag, even unannotated
    --long                always use long format
    --abbrev[=<n>]        use <n> digits to display SHA-1s
Some Git commands take options that are only used for plumbing or that are deprecated, and such options are hidden from the default usage. This option gives the full list of options.

2. Negating options

Options with long option names can be negated by prefixing --no-. For example, git branch has the option --track which is on by default. You can use --no-track to override that behaviour. The same goes for --color and --no-color.

3. Aggregating short options

Commands that support the enhanced option parser allow you to aggregate short options. This means that you can for example use git rm -rf or git clean -fdx.

4. Abbreviating long options

Commands that support the enhanced option parser accepts unique prefix of a long option as if it is fully spelled out, but use this with a caution. For example, git commit --amen behaves as if you typed git commit --amend, but that is true only until a later version of Git introduces another option that shares the same prefix, e.g. git commit --amenity option.

5. Separating argument from the option

You can write the mandatory option parameter to an option as a separate word on the command line. That means that all the following uses work:

$ git foo --long-opt=Arg
$ git foo --long-opt Arg
$ git foo -oArg
$ git foo -o Arg

However, this is NOT allowed for switches with an optional value, where the stuck form must be used:

$ git describe --abbrev HEAD     # correct
$ git describe --abbrev=10 HEAD  # correct
$ git describe --abbrev 10 HEAD  # NOT WHAT YOU MEANT


Many commands that can work on files in the working tree and/or in the index can take --cached and/or --index options. Sometimes people incorrectly think that, because the index was originally called cache, these two are synonyms. They are not -- these two options mean very different things.

  • The --cached option is used to ask a command that usually works on files in the working tree to only work with the index. For example, git grep, when used without a commit to specify from which commit to look for strings in, usually works on files in the working tree, but with the --cached option, it looks for strings in the index.
  • The --index option is used to ask a command that usually works on files in the working tree to also affect the index. For example, git stash apply usually merges changes recorded in a stash to the working tree, but with the --index option, it also merges changes to the index as well.

git apply command can be used with --cached and --index (but not at the same time). Usually the command only affects the files in the working tree, but with --index, it patches both the files and their index entries, and with --cached, it modifies only the index entries.

See also http://marc.info/?l=git&m=116563135620359 and http://marc.info/?l=git&m=119150393620273 for further information.


Part of the Section G.3.1, “git(1)” suite

G.4.2. gitattributes(5)


gitattributes - defining attributes per path


$GIT_DIR/info/attributes, .gitattributes


A gitattributes file is a simple text file that gives attributes to pathnames.

Each line in gitattributes file is of form:

pattern attr1 attr2 ...

That is, a pattern followed by an attributes list, separated by whitespaces. When the pattern matches the path in question, the attributes listed on the line are given to the path.

Each attribute can be in one of these states for a given path:

The path has the attribute with special value "true"; this is specified by listing only the name of the attribute in the attribute list.
The path has the attribute with special value "false"; this is specified by listing the name of the attribute prefixed with a dash - in the attribute list.
Set to a value
The path has the attribute with specified string value; this is specified by listing the name of the attribute followed by an equal sign = and its value in the attribute list.
No pattern matches the path, and nothing says if the path has or does not have the attribute, the attribute for the path is said to be Unspecified.

When more than one pattern matches the path, a later line overrides an earlier line. This overriding is done per attribute. The rules how the pattern matches paths are the same as in .gitignore files; see Section G.4.5, “gitignore(5)”. Unlike .gitignore, negative patterns are forbidden.

When deciding what attributes are assigned to a path, Git consults $GIT_DIR/info/attributes file (which has the highest precedence), .gitattributes file in the same directory as the path in question, and its parent directories up to the toplevel of the work tree (the further the directory that contains .gitattributes is from the path in question, the lower its precedence). Finally global and system-wide files are considered (they have the lowest precedence).

When the .gitattributes file is missing from the work tree, the path in the index is used as a fall-back. During checkout process, .gitattributes in the index is used and then the file in the working tree is used as a fall-back.

If you wish to affect only a single repository (i.e., to assign attributes to files that are particular to one user's workflow for that repository), then attributes should be placed in the $GIT_DIR/info/attributes file. Attributes which should be version-controlled and distributed to other repositories (i.e., attributes of interest to all users) should go into .gitattributes files. Attributes that should affect all repositories for a single user should be placed in a file specified by the core.attributesFile configuration option (see Section G.3.27, “git-config(1)”). Its default value is $XDG_CONFIG_HOME/git/attributes. If $XDG_CONFIG_HOME is either not set or empty, $HOME/.config/git/attributes is used instead. Attributes for all users on a system should be placed in the $(prefix)/etc/gitattributes file.

Sometimes you would need to override an setting of an attribute for a path to Unspecified state. This can be done by listing the name of the attribute prefixed with an exclamation point !.


Certain operations by Git can be influenced by assigning particular attributes to a path. Currently, the following operations are attributes-aware.

1. Checking-out and checking-in

These attributes affect how the contents stored in the repository are copied to the working tree files when commands such as git checkout and git merge run. They also affect how Git stores the contents you prepare in the working tree in the repository upon git add and git commit.

1.1. text

This attribute enables and controls end-of-line normalization. When a text file is normalized, its line endings are converted to LF in the repository. To control what line ending style is used in the working directory, use the eol attribute for a single file and the core.eol configuration variable for all text files.

Setting the text attribute on a path enables end-of-line normalization and marks the path as a text file. End-of-line conversion takes place without guessing the content type.
Unsetting the text attribute on a path tells Git not to attempt any end-of-line conversion upon checkin or checkout.
Set to string value "auto"
When text is set to "auto", the path is marked for automatic end-of-line normalization. If Git decides that the content is text, its line endings are normalized to LF on checkin.
If the text attribute is unspecified, Git uses the core.autocrlf configuration variable to determine if the file should be converted.

Any other value causes Git to act as if text has been left unspecified.

1.2. eol

This attribute sets a specific line-ending style to be used in the working directory. It enables end-of-line normalization without any content checks, effectively setting the text attribute.

Set to string value "crlf"
This setting forces Git to normalize line endings for this file on checkin and convert them to CRLF when the file is checked out.
Set to string value "lf"
This setting forces Git to normalize line endings to LF on checkin and prevents conversion to CRLF when the file is checked out.

1.3. Backwards compatibility with crlf attribute

For backwards compatibility, the crlf attribute is interpreted as follows:

crlf            text
-crlf           -text
crlf=input      eol=lf

1.4. End-of-line conversion

While Git normally leaves file contents alone, it can be configured to normalize line endings to LF in the repository and, optionally, to convert them to CRLF when files are checked out.

Here is an example that will make Git normalize .txt, .vcproj and .sh files, ensure that .vcproj files have CRLF and .sh files have LF in the working directory, and prevent .jpg files from being normalized regardless of their content.

*.txt           text
*.vcproj        eol=crlf
*.sh            eol=lf
*.jpg           -text

Other source code management systems normalize all text files in their repositories, and there are two ways to enable similar automatic normalization in Git.

If you simply want to have CRLF line endings in your working directory regardless of the repository you are working with, you can set the config variable "core.autocrlf" without changing any attributes.

        autocrlf = true

This does not force normalization of all text files, but does ensure that text files that you introduce to the repository have their line endings normalized to LF when they are added, and that files that are already normalized in the repository stay normalized.

If you want to interoperate with a source code management system that enforces end-of-line normalization, or you simply want all text files in your repository to be normalized, you should instead set the text attribute to "auto" for all files.

*       text=auto

This ensures that all files that Git considers to be text will have normalized (LF) line endings in the repository. The core.eol configuration variable controls which line endings Git will use for normalized files in your working directory; the default is to use the native line ending for your platform, or CRLF if core.autocrlf is set.

[Note] Note

When text=auto normalization is enabled in an existing repository, any text files containing CRLFs should be normalized. If they are not they will be normalized the next time someone tries to change them, causing unfortunate misattribution. From a clean working directory:

$ echo "* text=auto" >>.gitattributes
$ rm .git/index     # Remove the index to force Git to
$ git reset         # re-scan the working directory
$ git status        # Show files that will be normalized
$ git add -u
$ git add .gitattributes
$ git commit -m "Introduce end-of-line normalization"

If any files that should not be normalized show up in git status, unset their text attribute before running git add -u.

manual.pdf      -text

Conversely, text files that Git does not detect can have normalization enabled manually.

weirdchars.txt  text

If core.safecrlf is set to "true" or "warn", Git verifies if the conversion is reversible for the current setting of core.autocrlf. For "true", Git rejects irreversible conversions; for "warn", Git only prints a warning but accepts an irreversible conversion. The safety triggers to prevent such a conversion done to the files in the work tree, but there are a few exceptions. Even though…

  • git add itself does not touch the files in the work tree, the next checkout would, so the safety triggers;
  • git apply to update a text file with a patch does touch the files in the work tree, but the operation is about text files and CRLF conversion is about fixing the line ending inconsistencies, so the safety does not trigger;
  • git diff itself does not touch the files in the work tree, it is often run to inspect the changes you intend to next git add. To catch potential problems early, safety triggers.

1.5. ident

When the attribute ident is set for a path, Git replaces $Id$ in the blob object with $Id:, followed by the 40-character hexadecimal blob object name, followed by a dollar sign $ upon checkout. Any byte sequence that begins with $Id: and ends with $ in the worktree file is replaced with $Id$ upon check-in.

1.6. filter

A filter attribute can be set to a string value that names a filter driver specified in the configuration.

A filter driver consists of a clean command and a smudge command, either of which can be left unspecified. Upon checkout, when the smudge command is specified, the command is fed the blob object from its standard input, and its standard output is used to update the worktree file. Similarly, the clean command is used to convert the contents of worktree file upon checkin.

One use of the content filtering is to massage the content into a shape that is more convenient for the platform, filesystem, and the user to use. For this mode of operation, the key phrase here is "more convenient" and not "turning something unusable into usable". In other words, the intent is that if someone unsets the filter driver definition, or does not have the appropriate filter program, the project should still be usable.

Another use of the content filtering is to store the content that cannot be directly used in the repository (e.g. a UUID that refers to the true content stored outside Git, or an encrypted content) and turn it into a usable form upon checkout (e.g. download the external content, or decrypt the encrypted content).

These two filters behave differently, and by default, a filter is taken as the former, massaging the contents into more convenient shape. A missing filter driver definition in the config, or a filter driver that exits with a non-zero status, is not an error but makes the filter a no-op passthru.

You can declare that a filter turns a content that by itself is unusable into a usable content by setting the filter.<driver>.required configuration variable to true.

For example, in .gitattributes, you would assign the filter attribute for paths.

*.c     filter=indent

Then you would define a "filter.indent.clean" and "filter.indent.smudge" configuration in your .git/config to specify a pair of commands to modify the contents of C programs when the source files are checked in ("clean" is run) and checked out (no change is made because the command is "cat").

[filter "indent"]
        clean = indent
        smudge = cat

For best results, clean should not alter its output further if it is run twice ("clean→clean" should be equivalent to "clean"), and multiple smudge commands should not alter clean's output ("smudge→smudge→clean" should be equivalent to "clean"). See the section on merging below.

The "indent" filter is well-behaved in this regard: it will not modify input that is already correctly indented. In this case, the lack of a smudge filter means that the clean filter must accept its own output without modifying it.

If a filter must succeed in order to make the stored contents usable, you can declare that the filter is required, in the configuration:

[filter "crypt"]
        clean = openssl enc ...
        smudge = openssl enc -d ...

Sequence "%f" on the filter command line is replaced with the name of the file the filter is working on. A filter might use this in keyword substitution. For example:

[filter "p4"]
        clean = git-p4-filter --clean %f
        smudge = git-p4-filter --smudge %f

1.7. Interaction between checkin/checkout attributes

In the check-in codepath, the worktree file is first converted with filter driver (if specified and corresponding driver defined), then the result is processed with ident (if specified), and then finally with text (again, if specified and applicable).

In the check-out codepath, the blob content is first converted with text, and then ident and fed to filter.

1.8. Merging branches with differing checkin/checkout attributes

If you have added attributes to a file that cause the canonical repository format for that file to change, such as adding a clean/smudge filter or text/eol/ident attributes, merging anything where the attribute is not in place would normally cause merge conflicts.

To prevent these unnecessary merge conflicts, Git can be told to run a virtual check-out and check-in of all three stages of a file when resolving a three-way merge by setting the merge.renormalize configuration variable. This prevents changes caused by check-in conversion from causing spurious merge conflicts when a converted file is merged with an unconverted file.

As long as a "smudge→clean" results in the same output as a "clean" even on files that are already smudged, this strategy will automatically resolve all filter-related conflicts. Filters that do not act in this way may cause additional merge conflicts that must be resolved manually.

2. Generating diff text

2.1. diff

The attribute diff affects how Git generates diffs for particular files. It can tell Git whether to generate a textual patch for the path or to treat the path as a binary file. It can also affect what line is shown on the hunk header @@ -k,l +n,m @@ line, tell Git to use an external command to generate the diff, or ask Git to convert binary files to a text format before generating the diff.

A path to which the diff attribute is set is treated as text, even when they contain byte values that normally never appear in text files, such as NUL.
A path to which the diff attribute is unset will generate Binary files differ (or a binary patch, if binary patches are enabled).
A path to which the diff attribute is unspecified first gets its contents inspected, and if it looks like text and is smaller than core.bigFileThreshold, it is treated as text. Otherwise it would generate Binary files differ.
Diff is shown using the specified diff driver. Each driver may specify one or more options, as described in the following section. The options for the diff driver "foo" are defined by the configuration variables in the "diff.foo" section of the Git config file.

2.2. Defining an external diff driver

The definition of a diff driver is done in gitconfig, not gitattributes file, so strictly speaking this manual page is a wrong place to talk about it. However…

To define an external diff driver jcdiff, add a section to your $GIT_DIR/config file (or $HOME/.gitconfig file) like this:

[diff "jcdiff"]
        command = j-c-diff

When Git needs to show you a diff for the path with diff attribute set to jcdiff, it calls the command you specified with the above configuration, i.e. j-c-diff, with 7 parameters, just like GIT_EXTERNAL_DIFF program is called. See Section G.3.1, “git(1)” for details.

2.3. Defining a custom hunk-header

Each group of changes (called a "hunk") in the textual diff output is prefixed with a line of the form:

@@ -k,l +n,m @@ TEXT

This is called a hunk header. The "TEXT" portion is by default a line that begins with an alphabet, an underscore or a dollar sign; this matches what GNU diff -p output uses. This default selection however is not suited for some contents, and you can use a customized pattern to make a selection.

First, in .gitattributes, you would assign the diff attribute for paths.

*.tex   diff=tex

Then, you would define a "diff.tex.xfuncname" configuration to specify a regular expression that matches a line that you would want to appear as the hunk header "TEXT". Add a section to your $GIT_DIR/config file (or $HOME/.gitconfig file) like this:

[diff "tex"]
        xfuncname = "^(\\\\(sub)*section\\{.*)$"

Note. A single level of backslashes are eaten by the configuration file parser, so you would need to double the backslashes; the pattern above picks a line that begins with a backslash, and zero or more occurrences of sub followed by section followed by open brace, to the end of line.

There are a few built-in patterns to make this easier, and tex is one of them, so you do not have to write the above in your configuration file (you still need to enable this with the attribute mechanism, via .gitattributes). The following built in patterns are available:

  • ada suitable for source code in the Ada language.
  • bibtex suitable for files with BibTeX coded references.
  • cpp suitable for source code in the C and C++ languages.
  • csharp suitable for source code in the C# language.
  • fortran suitable for source code in the Fortran language.
  • fountain suitable for Fountain documents.
  • html suitable for HTML/XHTML documents.
  • java suitable for source code in the Java language.
  • matlab suitable for source code in the MATLAB language.
  • objc suitable for source code in the Objective-C language.
  • pascal suitable for source code in the Pascal/Delphi language.
  • perl suitable for source code in the Perl language.
  • php suitable for source code in the PHP language.
  • python suitable for source code in the Python language.
  • ruby suitable for source code in the Ruby language.
  • tex suitable for source code for LaTeX documents.

2.4. Customizing word diff

You can customize the rules that git diff --word-diff uses to split words in a line, by specifying an appropriate regular expression in the "diff.*.wordRegex" configuration variable. For example, in TeX a backslash followed by a sequence of letters forms a command, but several such commands can be run together without intervening whitespace. To separate them, use a regular expression in your $GIT_DIR/config file (or $HOME/.gitconfig file) like this:

[diff "tex"]
        wordRegex = "\\\\[a-zA-Z]+|[{}]|\\\\.|[^\\{}[:space:]]+"

A built-in pattern is provided for all languages listed in the previous section.

2.5. Performing text diffs of binary files

Sometimes it is desirable to see the diff of a text-converted version of some binary files. For example, a word processor document can be converted to an ASCII text representation, and the diff of the text shown. Even though this conversion loses some information, the resulting diff is useful for human viewing (but cannot be applied directly).

The textconv config option is used to define a program for performing such a conversion. The program should take a single argument, the name of a file to convert, and produce the resulting text on stdout.

For example, to show the diff of the exif information of a file instead of the binary information (assuming you have the exif tool installed), add the following section to your $GIT_DIR/config file (or $HOME/.gitconfig file):

[diff "jpg"]
        textconv = exif
[Note] Note

The text conversion is generally a one-way conversion; in this example, we lose the actual image contents and focus just on the text data. This means that diffs generated by textconv are not suitable for applying. For this reason, only git diff and the git log family of commands (i.e., log, whatchanged, show) will perform text conversion. git format-patch will never generate this output. If you want to send somebody a text-converted diff of a binary file (e.g., because it quickly conveys the changes you have made), you should generate it separately and send it as a comment in addition to the usual binary diff that you might send.

Because text conversion can be slow, especially when doing a large number of them with git log -p, Git provides a mechanism to cache the output and use it in future diffs. To enable caching, set the "cachetextconv" variable in your diff driver's config. For example:

[diff "jpg"]
        textconv = exif
        cachetextconv = true

This will cache the result of running "exif" on each blob indefinitely. If you change the textconv config variable for a diff driver, Git will automatically invalidate the cache entries and re-run the textconv filter. If you want to invalidate the cache manually (e.g., because your version of "exif" was updated and now produces better output), you can remove the cache manually with git update-ref -d refs/notes/textconv/jpg (where "jpg" is the name of the diff driver, as in the example above).

2.6. Choosing textconv versus external diff

If you want to show differences between binary or specially-formatted blobs in your repository, you can choose to use either an external diff command, or to use textconv to convert them to a diff-able text format. Which method you choose depends on your exact situation.

The advantage of using an external diff command is flexibility. You are not bound to find line-oriented changes, nor is it necessary for the output to resemble unified diff. You are free to locate and report changes in the most appropriate way for your data format.

A textconv, by comparison, is much more limiting. You provide a transformation of the data into a line-oriented text format, and Git uses its regular diff tools to generate the output. There are several advantages to choosing this method:

  1. Ease of use. It is often much simpler to write a binary to text transformation than it is to perform your own diff. In many cases, existing programs can be used as textconv filters (e.g., exif, odt2txt).
  2. Git diff features. By performing only the transformation step yourself, you can still utilize many of Git's diff features, including colorization, word-diff, and combined diffs for merges.
  3. Caching. Textconv caching can speed up repeated diffs, such as those you might trigger by running git log -p.

2.7. Marking files as binary

Git usually guesses correctly whether a blob contains text or binary data by examining the beginning of the contents. However, sometimes you may want to override its decision, either because a blob contains binary data later in the file, or because the content, while technically composed of text characters, is opaque to a human reader. For example, many postscript files contain only ASCII characters, but produce noisy and meaningless diffs.

The simplest way to mark a file as binary is to unset the diff attribute in the .gitattributes file:

*.ps -diff

This will cause Git to generate Binary files differ (or a binary patch, if binary patches are enabled) instead of a regular diff.

However, one may also want to specify other diff driver attributes. For example, you might want to use textconv to convert postscript files to an ASCII representation for human viewing, but otherwise treat them as binary files. You cannot specify both -diff and diff=ps attributes. The solution is to use the diff.*.binary config option:

[diff "ps"]
  textconv = ps2ascii
  binary = true

3. Performing a three-way merge

3.1. merge

The attribute merge affects how three versions of a file are merged when a file-level merge is necessary during git merge, and other commands such as git revert and git cherry-pick.

Built-in 3-way merge driver is used to merge the contents in a way similar to merge command of RCS suite. This is suitable for ordinary text files.
Take the version from the current branch as the tentative merge result, and declare that the merge has conflicts. This is suitable for binary files that do not have a well-defined merge semantics.
By default, this uses the same built-in 3-way merge driver as is the case when the merge attribute is set. However, the merge.default configuration variable can name different merge driver to be used with paths for which the merge attribute is unspecified.
3-way merge is performed using the specified custom merge driver. The built-in 3-way merge driver can be explicitly specified by asking for "text" driver; the built-in "take the current branch" driver can be requested with "binary".

3.2. Built-in merge drivers

There are a few built-in low-level merge drivers defined that can be asked for via the merge attribute.

Usual 3-way file level merge for text files. Conflicted regions are marked with conflict markers <<<<<<<, ======= and >>>>>>>. The version from your branch appears before the ======= marker, and the version from the merged branch appears after the ======= marker.
Keep the version from your branch in the work tree, but leave the path in the conflicted state for the user to sort out.
Run 3-way file level merge for text files, but take lines from both versions, instead of leaving conflict markers. This tends to leave the added lines in the resulting file in random order and the user should verify the result. Do not use this if you do not understand the implications.

3.3. Defining a custom merge driver

The definition of a merge driver is done in the .git/config file, not in the gitattributes file, so strictly speaking this manual page is a wrong place to talk about it. However…

To define a custom merge driver filfre, add a section to your $GIT_DIR/config file (or $HOME/.gitconfig file) like this:

[merge "filfre"]
        name = feel-free merge driver
        driver = filfre %O %A %B %L %P
        recursive = binary

The merge.*.name variable gives the driver a human-readable name.

The merge.*.driver` variable's value is used to construct a command to run to merge ancestor's version (%O), current version (%A) and the other branches version (%B). These three tokens are replaced with the names of temporary files that hold the contents of these versions when the command line is built. Additionally, %L will be replaced with the conflict marker size (see below).

The merge driver is expected to leave the result of the merge in the file named with %A by overwriting it, and exit with zero status if it managed to merge them cleanly, or non-zero if there were conflicts.

The merge.*.recursive variable specifies what other merge driver to use when the merge driver is called for an internal merge between common ancestors, when there are more than one. When left unspecified, the driver itself is used for both internal merge and the final merge.

The merge driver can learn the pathname in which the merged result will be stored via placeholder %P.

3.4. conflict-marker-size

This attribute controls the length of conflict markers left in the work tree file during a conflicted merge. Only setting to the value to a positive integer has any meaningful effect.

For example, this line in .gitattributes can be used to tell the merge machinery to leave much longer (instead of the usual 7-character-long) conflict markers when merging the file Documentation/git-merge.txt results in a conflict.

Documentation/git-merge.txt     conflict-marker-size=32

4. Checking whitespace errors

4.1. whitespace

The core.whitespace configuration variable allows you to define what diff and apply should consider whitespace errors for all paths in the project (See Section G.3.27, “git-config(1)”). This attribute gives you finer control per path.

Notice all types of potential whitespace errors known to Git. The tab width is taken from the value of the core.whitespace configuration variable.
Do not notice anything as error.
Use the value of the core.whitespace configuration variable to decide what to notice as error.
Specify a comma separate list of common whitespace problems to notice in the same format as the core.whitespace configuration variable.

5. Creating an archive

5.1. export-ignore

Files and directories with the attribute export-ignore won't be added to archive files.

5.2. export-subst

If the attribute export-subst is set for a file then Git will expand several placeholders when adding this file to an archive. The expansion depends on the availability of a commit ID, i.e., if Section G.3.7, “git-archive(1)” has been given a tree instead of a commit or a tag then no replacement will be done. The placeholders are the same as those for the option --pretty=format: of Section G.3.68, “git-log(1)”, except that they need to be wrapped like this: $Format:PLACEHOLDERS$ in the file. E.g. the string $Format:%H$ will be replaced by the commit hash.

6. Packing objects

6.1. delta

Delta compression will not be attempted for blobs for paths with the attribute delta set to false.

7. Viewing files in GUI tools

7.1. encoding

The value of this attribute specifies the character encoding that should be used by GUI tools (e.g. Section G.4.7, “gitk(1)” and Section G.3.56, “git-gui(1)”) to display the contents of the relevant file. Note that due to performance considerations Section G.4.7, “gitk(1)” does not use this attribute unless you manually enable per-file encodings in its options.

If this attribute is not set or has an invalid value, the value of the gui.encoding configuration variable is used instead (See Section G.3.27, “git-config(1)”).


You do not want any end-of-line conversions applied to, nor textual diffs produced for, any binary file you track. You would need to specify e.g.

*.jpg -text -diff

but that may become cumbersome, when you have many attributes. Using macro attributes, you can define an attribute that, when set, also sets or unsets a number of other attributes at the same time. The system knows a built-in macro attribute, binary:

*.jpg binary

Setting the "binary" attribute also unsets the "text" and "diff" attributes as above. Note that macro attributes can only be "Set", though setting one might have the effect of setting or unsetting other attributes or even returning other attributes to the "Unspecified" state.


Custom macro attributes can be defined only in top-level gitattributes files ($GIT_DIR/info/attributes, the .gitattributes file at the top level of the working tree, or the global or system-wide gitattributes files), not in .gitattributes files in working tree subdirectories. The built-in macro attribute "binary" is equivalent to:

[attr]binary -diff -merge -text


If you have these three gitattributes file:

(in $GIT_DIR/info/attributes)

a*      foo !bar -baz

(in .gitattributes)
abc     foo bar baz

(in t/.gitattributes)
ab*     merge=filfre
abc     -foo -bar
*.c     frotz

the attributes given to path t/abc are computed as follows:

  1. By examining t/.gitattributes (which is in the same directory as the path in question), Git finds that the first line matches. merge attribute is set. It also finds that the second line matches, and attributes foo and bar are unset.
  2. Then it examines .gitattributes (which is in the parent directory), and finds that the first line matches, but t/.gitattributes file already decided how merge, foo and bar attributes should be given to this path, so it leaves foo and bar unset. Attribute baz is set.
  3. Finally it examines $GIT_DIR/info/attributes. This file is used to override the in-tree settings. The first line is a match, and foo is set, bar is reverted to unspecified state, and baz is unset.

As the result, the attributes assignment to t/abc becomes:

foo     set to true
bar     unspecified
baz     set to false
merge   set to string value "filfre"
frotz   unspecified


Part of the Section G.3.1, “git(1)” suite

G.4.3. gitcredentials(7)


gitcredentials - providing usernames and passwords to Git


git config credential.https://example.com.username myusername
git config credential.helper "$helper $options"


Git will sometimes need credentials from the user in order to perform operations; for example, it may need to ask for a username and password in order to access a remote repository over HTTP. This manual describes the mechanisms Git uses to request these credentials, as well as some features to avoid inputting these credentials repeatedly.


Without any credential helpers defined, Git will try the following strategies to ask the user for usernames and passwords:

  1. If the GIT_ASKPASS environment variable is set, the program specified by the variable is invoked. A suitable prompt is provided to the program on the command line, and the user's input is read from its standard output.
  2. Otherwise, if the core.askPass configuration variable is set, its value is used as above.
  3. Otherwise, if the SSH_ASKPASS environment variable is set, its value is used as above.
  4. Otherwise, the user is prompted on the terminal.


It can be cumbersome to input the same credentials over and over. Git provides two methods to reduce this annoyance:

  1. Static configuration of usernames for a given authentication context.
  2. Credential helpers to cache or store passwords, or to interact with a system password wallet or keychain.

The first is simple and appropriate if you do not have secure storage available for a password. It is generally configured by adding this to your config:

[credential "https://example.com"]
        username = me

Credential helpers, on the other hand, are external programs from which Git can request both usernames and passwords; they typically interface with secure storage provided by the OS or other programs.

To use a helper, you must first select one to use. Git currently includes the following helpers:

Cache credentials in memory for a short period of time. See Section G.3.31, “git-credential-cache(1)” for details.
Store credentials indefinitely on disk. See Section G.3.32, “git-credential-store(1)” for details.

You may also have third-party helpers installed; search for credential-* in the output of git help -a, and consult the documentation of individual helpers. Once you have selected a helper, you can tell Git to use it by putting its name into the credential.helper variable.

  1. Find a helper.

    $ git help -a | grep credential-
  2. Read its description.

    $ git help credential-foo
  3. Tell Git to use it.

    $ git config --global credential.helper foo

If there are multiple instances of the credential.helper configuration variable, each helper will be tried in turn, and may provide a username, password, or nothing. Once Git has acquired both a username and a password, no more helpers will be tried.

If credential.helper is configured to the empty string, this resets the helper list to empty (so you may override a helper set by a lower-priority config file by configuring the empty-string helper, followed by whatever set of helpers you would like).


Git considers each credential to have a context defined by a URL. This context is used to look up context-specific configuration, and is passed to any helpers, which may use it as an index into secure storage.

For instance, imagine we are accessing https://example.com/foo.git. When Git looks into a config file to see if a section matches this context, it will consider the two a match if the context is a more-specific subset of the pattern in the config file. For example, if you have this in your config file:

[credential "https://example.com"]
        username = foo

then we will match: both protocols are the same, both hosts are the same, and the "pattern" URL does not care about the path component at all. However, this context would not match:

[credential "https://kernel.org"]
        username = foo

because the hostnames differ. Nor would it match foo.example.com; Git compares hostnames exactly, without considering whether two hosts are part of the same domain. Likewise, a config entry for http://example.com would not match: Git compares the protocols exactly.


Options for a credential context can be configured either in credential.* (which applies to all credentials), or credential.<url>.*, where <url> matches the context as described above.

The following options are available in either location:

The name of an external credential helper, and any associated options. If the helper name is not an absolute path, then the string git credential- is prepended. The resulting string is executed by the shell (so, for example, setting this to foo --option=bar will execute git credential-foo --option=bar via the shell. See the manual of specific helpers for examples of their use.
A default username, if one is not provided in the URL.
By default, Git does not consider the "path" component of an http URL to be worth matching via external helpers. This means that a credential stored for https://example.com/foo.git will also be used for https://example.com/bar.git. If you do want to distinguish these cases, set this option to true.


You can write your own custom helpers to interface with any system in which you keep credentials. See the documentation for Git's credentials API for details.


Part of the Section G.3.1, “git(1)” suite

G.4.4. gitdiffcore(7)


gitdiffcore - Tweaking diff output


git diff *


The diff commands git diff-index, git diff-files, and git diff-tree can be told to manipulate differences they find in unconventional ways before showing diff output. The manipulation is collectively called "diffcore transformation". This short note describes what they are and how to use them to produce diff output that is easier to understand than the conventional kind.

The chain of operation

The git diff-* family works by first comparing two sets of files:

  • git diff-index compares contents of a "tree" object and the working directory (when --cached flag is not used) or a "tree" object and the index file (when --cached flag is used);
  • git diff-files compares contents of the index file and the working directory;
  • git diff-tree compares contents of two "tree" objects;

In all of these cases, the commands themselves first optionally limit the two sets of files by any pathspecs given on their command-lines, and compare corresponding paths in the two resulting sets of files.

The pathspecs are used to limit the world diff operates in. They remove the filepairs outside the specified sets of pathnames. E.g. If the input set of filepairs included:

:100644 100644 bcd1234... 0123456... M junkfile

but the command invocation was git diff-files myfile, then the junkfile entry would be removed from the list because only "myfile" is under consideration.

The result of comparison is passed from these commands to what is internally called "diffcore", in a format similar to what is output when the -p option is not used. E.g.

in-place edit  :100644 100644 bcd1234... 0123456... M file0
create         :000000 100644 0000000... 1234567... A file4
delete         :100644 000000 1234567... 0000000... D file5
unmerged       :000000 000000 0000000... 0000000... U file6

The diffcore mechanism is fed a list of such comparison results (each of which is called "filepair", although at this point each of them talks about a single file), and transforms such a list into another list. There are currently 5 such transformations:

  • diffcore-break
  • diffcore-rename
  • diffcore-merge-broken
  • diffcore-pickaxe
  • diffcore-order

These are applied in sequence. The set of filepairs git diff-* commands find are used as the input to diffcore-break, and the output from diffcore-break is used as the input to the next transformation. The final result is then passed to the output routine and generates either diff-raw format (see Output format sections of the manual for git diff-* commands) or diff-patch format.

diffcore-break: For Splitting Up "Complete Rewrites"

The second transformation in the chain is diffcore-break, and is controlled by the -B option to the git diff-* commands. This is used to detect a filepair that represents "complete rewrite" and break such filepair into two filepairs that represent delete and create. E.g. If the input contained this filepair:

:100644 100644 bcd1234... 0123456... M file0

and if it detects that the file "file0" is completely rewritten, it changes it to:

:100644 000000 bcd1234... 0000000... D file0
:000000 100644 0000000... 0123456... A file0

For the purpose of breaking a filepair, diffcore-break examines the extent of changes between the contents of the files before and after modification (i.e. the contents that have "bcd1234…" and "0123456…" as their SHA-1 content ID, in the above example). The amount of deletion of original contents and insertion of new material are added together, and if it exceeds the "break score", the filepair is broken into two. The break score defaults to 50% of the size of the smaller of the original and the result (i.e. if the edit shrinks the file, the size of the result is used; if the edit lengthens the file, the size of the original is used), and can be customized by giving a number after "-B" option (e.g. "-B75" to tell it to use 75%).

diffcore-rename: For Detection Renames and Copies

This transformation is used to detect renames and copies, and is controlled by the -M option (to detect renames) and the -C option (to detect copies as well) to the git diff-* commands. If the input contained these filepairs:

:100644 000000 0123456... 0000000... D fileX
:000000 100644 0000000... 0123456... A file0

and the contents of the deleted file fileX is similar enough to the contents of the created file file0, then rename detection merges these filepairs and creates:

:100644 100644 0123456... 0123456... R100 fileX file0

When the "-C" option is used, the original contents of modified files, and deleted files (and also unmodified files, if the "--find-copies-harder" option is used) are considered as candidates of the source files in rename/copy operation. If the input were like these filepairs, that talk about a modified file fileY and a newly created file file0:

:100644 100644 0123456... 1234567... M fileY
:000000 100644 0000000... bcd3456... A file0

the original contents of fileY and the resulting contents of file0 are compared, and if they are similar enough, they are changed to:

:100644 100644 0123456... 1234567... M fileY
:100644 100644 0123456... bcd3456... C100 fileY file0

In both rename and copy detection, the same "extent of changes" algorithm used in diffcore-break is used to determine if two files are "similar enough", and can be customized to use a similarity score different from the default of 50% by giving a number after the "-M" or "-C" option (e.g. "-M8" to tell it to use 8/10 = 80%).

Note. When the "-C" option is used with --find-copies-harder option, git diff-* commands feed unmodified filepairs to diffcore mechanism as well as modified ones. This lets the copy detector consider unmodified files as copy source candidates at the expense of making it slower. Without --find-copies-harder, git diff-* commands can detect copies only if the file that was copied happened to have been modified in the same changeset.

diffcore-merge-broken: For Putting "Complete Rewrites" Back Together

This transformation is used to merge filepairs broken by diffcore-break, and not transformed into rename/copy by diffcore-rename, back into a single modification. This always runs when diffcore-break is used.

For the purpose of merging broken filepairs back, it uses a different "extent of changes" computation from the ones used by diffcore-break and diffcore-rename. It counts only the deletion from the original, and does not count insertion. If you removed only 10 lines from a 100-line document, even if you added 910 new lines to make a new 1000-line document, you did not do a complete rewrite. diffcore-break breaks such a case in order to help diffcore-rename to consider such filepairs as candidate of rename/copy detection, but if filepairs broken that way were not matched with other filepairs to create rename/copy, then this transformation merges them back into the original "modification".

The "extent of changes" parameter can be tweaked from the default 80% (that is, unless more than 80% of the original material is deleted, the broken pairs are merged back into a single modification) by giving a second number to -B option, like these:

  • -B50/60 (give 50% "break score" to diffcore-break, use 60% for diffcore-merge-broken).
  • -B/60 (the same as above, since diffcore-break defaults to 50%).

Note that earlier implementation left a broken pair as a separate creation and deletion patches. This was an unnecessary hack and the latest implementation always merges all the broken pairs back into modifications, but the resulting patch output is formatted differently for easier review in case of such a complete rewrite by showing the entire contents of old version prefixed with -, followed by the entire contents of new version prefixed with +.

diffcore-pickaxe: For Detecting Addition/Deletion of Specified String

This transformation limits the set of filepairs to those that change specified strings between the preimage and the postimage in a certain way. -S<block of text> and -G<regular expression> options are used to specify different ways these strings are sought.

"-S<block of text>" detects filepairs whose preimage and postimage have different number of occurrences of the specified block of text. By definition, it will not detect in-file moves. Also, when a changeset moves a file wholesale without affecting the interesting string, diffcore-rename kicks in as usual, and -S omits the filepair (since the number of occurrences of that string didn't change in that rename-detected filepair). When used with --pickaxe-regex, treat the <block of text> as an extended POSIX regular expression to match, instead of a literal string.

"-G<regular expression>" (mnemonic: grep) detects filepairs whose textual diff has an added or a deleted line that matches the given regular expression. This means that it will detect in-file (or what rename-detection considers the same file) moves, which is noise. The implementation runs diff twice and greps, and this can be quite expensive.

When -S or -G are used without --pickaxe-all, only filepairs that match their respective criterion are kept in the output. When --pickaxe-all is used, if even one filepair matches their respective criterion in a changeset, the entire changeset is kept. This behavior is designed to make reviewing changes in the context of the whole changeset easier.

diffcore-order: For Sorting the Output Based on Filenames

This is used to reorder the filepairs according to the user's (or project's) taste, and is controlled by the -O option to the git diff-* commands.

This takes a text file each of whose lines is a shell glob pattern. Filepairs that match a glob pattern on an earlier line in the file are output before ones that match a later line, and filepairs that do not match any glob pattern are output last.

As an example, a typical orderfile for the core Git probably would look like this:



Part of the Section G.3.1, “git(1)” suite.

G.4.5. gitignore(5)


gitignore - Specifies intentionally untracked files to ignore


$HOME/.config/git/ignore, $GIT_DIR/info/exclude, .gitignore


A gitignore file specifies intentionally untracked files that Git should ignore. Files already tracked by Git are not affected; see the NOTES below for details.

Each line in a gitignore file specifies a pattern. When deciding whether to ignore a path, Git normally checks gitignore patterns from multiple sources, with the following order of precedence, from highest to lowest (within one level of precedence, the last matching pattern decides the outcome):

  • Patterns read from the command line for those commands that support them.
  • Patterns read from a .gitignore file in the same directory as the path, or in any parent directory, with patterns in the higher level files (up to the toplevel of the work tree) being overridden by those in lower level files down to the directory containing the file. These patterns match relative to the location of the .gitignore file. A project normally includes such .gitignore files in its repository, containing patterns for files generated as part of the project build.
  • Patterns read from $GIT_DIR/info/exclude.
  • Patterns read from the file specified by the configuration variable core.excludesFile.

Which file to place a pattern in depends on how the pattern is meant to be used.

  • Patterns which should be version-controlled and distributed to other repositories via clone (i.e., files that all developers will want to ignore) should go into a .gitignore file.
  • Patterns which are specific to a particular repository but which do not need to be shared with other related repositories (e.g., auxiliary files that live inside the repository but are specific to one user's workflow) should go into the $GIT_DIR/info/exclude file.
  • Patterns which a user wants Git to ignore in all situations (e.g., backup or temporary files generated by the user's editor of choice) generally go into a file specified by core.excludesFile in the user's ~/.gitconfig. Its default value is $XDG_CONFIG_HOME/git/ignore. If $XDG_CONFIG_HOME is either not set or empty, $HOME/.config/git/ignore is used instead.

The underlying Git plumbing tools, such as git ls-files and git read-tree, read gitignore patterns specified by command-line options, or from files specified by command-line options. Higher-level Git tools, such as git status and git add, use patterns from the sources specified above.


  • A blank line matches no files, so it can serve as a separator for readability.
  • A line starting with # serves as a comment. Put a backslash ("\") in front of the first hash for patterns that begin with a hash.
  • Trailing spaces are ignored unless they are quoted with backslash ("\").
  • An optional prefix "!" which negates the pattern; any matching file excluded by a previous pattern will become included again. It is not possible to re-include a file if a parent directory of that file is excluded. Git doesn't list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined. Put a backslash ("\") in front of the first "!" for patterns that begin with a literal "!", for example, "\!important!.txt".
  • If the pattern ends with a slash, it is removed for the purpose of the following description, but it would only find a match with a directory. In other words, foo/ will match a directory foo and paths underneath it, but will not match a regular file or a symbolic link foo (this is consistent with the way how pathspec works in general in Git).
  • If the pattern does not contain a slash /, Git treats it as a shell glob pattern and checks for a match against the pathname relative to the location of the .gitignore file (relative to the toplevel of the work tree if not from a .gitignore file).
  • Otherwise, Git treats the pattern as a shell glob suitable for consumption by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the pattern will not match a / in the pathname. For example, "Documentation/*.html" matches "Documentation/git.html" but not "Documentation/ppc/ppc.html" or "tools/perf/Documentation/perf.html".
  • A leading slash matches the beginning of the pathname. For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".

Two consecutive asterisks ("**") in patterns matched against full pathname may have special meaning:

  • A leading "**" followed by a slash means match in all directories. For example, "**/foo" matches file or directory "foo" anywhere, the same as pattern "foo". "**/foo/bar" matches file or directory "bar" anywhere that is directly under directory "foo".
  • A trailing "/**" matches everything inside. For example, "abc/**" matches all files inside directory "abc", relative to the location of the .gitignore file, with infinite depth.
  • A slash followed by two consecutive asterisks then a slash matches zero or more directories. For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on.
  • Other consecutive asterisks are considered invalid.


The purpose of gitignore files is to ensure that certain files not tracked by Git remain untracked.

To stop tracking a file that is currently tracked, use git rm --cached.


    $ git status
    # Untracked files:
    #       Documentation/foo.html
    #       Documentation/gitignore.html
    #       file.o
    #       lib.a
    #       src/internal.o
    $ cat .git/info/exclude
    # ignore objects and archives, anywhere in the tree.
    $ cat Documentation/.gitignore
    # ignore generated html files,
    # except foo.html which is maintained by hand
    $ git status
    # Untracked files:
    #       Documentation/foo.html

Another example:

    $ cat .gitignore
    $ ls arch/foo/kernel/vm*
    $ echo '!/vmlinux*' >arch/foo/kernel/.gitignore

The second .gitignore prevents Git from ignoring arch/foo/kernel/vmlinux.lds.S.

Example to exclude everything except a specific directory foo/bar (note the /* - without the slash, the wildcard would also exclude everything within foo/bar):

    $ cat .gitignore
    # exclude everything except directory foo/bar


Part of the Section G.3.1, “git(1)” suite

G.4.6. githooks(5)


githooks - Hooks used by Git




Hooks are little scripts you can place in $GIT_DIR/hooks directory to trigger action at certain points. When git init is run, a handful of example hooks are copied into the hooks directory of the new repository, but by default they are all disabled. To enable a hook, rename it by removing its .sample suffix.

[Note] Note

It is also a requirement for a given hook to be executable. However - in a freshly initialized repository - the .sample files are executable by default.

This document describes the currently defined hooks.


1. applypatch-msg

This hook is invoked by git am script. It takes a single parameter, the name of the file that holds the proposed commit log message. Exiting with non-zero status causes git am to abort before applying the patch.

The hook is allowed to edit the message file in place, and can be used to normalize the message into some project standard format (if the project has one). It can also be used to refuse the commit after inspecting the message file.

The default applypatch-msg hook, when enabled, runs the commit-msg hook, if the latter is enabled.

2. pre-applypatch

This hook is invoked by git am. It takes no parameter, and is invoked after the patch is applied, but before a commit is made.

If it exits with non-zero status, then the working tree will not be committed after applying the patch.

It can be used to inspect the current working tree and refuse to make a commit if it does not pass certain test.

The default pre-applypatch hook, when enabled, runs the pre-commit hook, if the latter is enabled.

3. post-applypatch

This hook is invoked by git am. It takes no parameter, and is invoked after the patch is applied and a commit is made.

This hook is meant primarily for notification, and cannot affect the outcome of git am.

4. pre-commit

This hook is invoked by git commit, and can be bypassed with --no-verify option. It takes no parameter, and is invoked before obtaining the proposed commit log message and making a commit. Exiting with non-zero status from this script causes the git commit to abort.

The default pre-commit hook, when enabled, catches introduction of lines with trailing whitespaces and aborts the commit when such a line is found.

All the git commit hooks are invoked with the environment variable GIT_EDITOR=: if the command will not bring up an editor to modify the commit message.

5. prepare-commit-msg

This hook is invoked by git commit right after preparing the default log message, and before the editor is started.

It takes one to three parameters. The first is the name of the file that contains the commit log message. The second is the source of the commit message, and can be: message (if a -m or -F option was given); template (if a -t option was given or the configuration option commit.template is set); merge (if the commit is a merge or a .git/MERGE_MSG file exists); squash (if a .git/SQUASH_MSG file exists); or commit, followed by a commit SHA-1 (if a -c, -C or --amend option was given).

If the exit status is non-zero, git commit will abort.

The purpose of the hook is to edit the message file in place, and it is not suppressed by the --no-verify option. A non-zero exit means a failure of the hook and aborts the commit. It should not be used as replacement for pre-commit hook.

The sample prepare-commit-msg hook that comes with Git comments out the Conflicts: part of a merge's commit message.

6. commit-msg

This hook is invoked by git commit, and can be bypassed with --no-verify option. It takes a single parameter, the name of the file that holds the proposed commit log message. Exiting with non-zero status causes the git commit to abort.

The hook is allowed to edit the message file in place, and can be used to normalize the message into some project standard format (if the project has one). It can also be used to refuse the commit after inspecting the message file.

The default commit-msg hook, when enabled, detects duplicate "Signed-off-by" lines, and aborts the commit if one is found.

7. post-commit

This hook is invoked by git commit. It takes no parameter, and is invoked after a commit is made.

This hook is meant primarily for notification, and cannot affect the outcome of git commit.

8. pre-rebase

This hook is called by git rebase and can be used to prevent a branch from getting rebased. The hook may be called with one or two parameters. The first parameter is the upstream from which the series was forked. The second parameter is the branch being rebased, and is not set when rebasing the current branch.

9. post-checkout

This hook is invoked when a git checkout is run after having updated the worktree. The hook is given three parameters: the ref of the previous HEAD, the ref of the new HEAD (which may or may not have changed), and a flag indicating whether the checkout was a branch checkout (changing branches, flag=1) or a file checkout (retrieving a file from the index, flag=0). This hook cannot affect the outcome of git checkout.

It is also run after git clone, unless the --no-checkout (-n) option is used. The first parameter given to the hook is the null-ref, the second the ref of the new HEAD and the flag is always 1.

This hook can be used to perform repository validity checks, auto-display differences from the previous HEAD if different, or set working dir metadata properties.

10. post-merge

This hook is invoked by git merge, which happens when a git pull is done on a local repository. The hook takes a single parameter, a status flag specifying whether or not the merge being done was a squash merge. This hook cannot affect the outcome of git merge and is not executed, if the merge failed due to conflicts.

This hook can be used in conjunction with a corresponding pre-commit hook to save and restore any form of metadata associated with the working tree (e.g.: permissions/ownership, ACLS, etc). See contrib/hooks/setgitperms.perl for an example of how to do this.

11. pre-push

This hook is called by git push and can be used to prevent a push from taking place. The hook is called with two parameters which provide the name and location of the destination remote, if a named remote is not being used both values will be the same.

Information about what is to be pushed is provided on the hook's standard input with lines of the form:

<local ref> SP <local sha1> SP <remote ref> SP <remote sha1> LF

For instance, if the command git push origin master:foreign were run the hook would receive a line like the following:

refs/heads/master 67890 refs/heads/foreign 12345

although the full, 40-character SHA-1s would be supplied. If the foreign ref does not yet exist the <remote SHA-1> will be 40 0. If a ref is to be deleted, the <local ref> will be supplied as (delete) and the <local SHA-1> will be 40 0. If the local commit was specified by something other than a name which could be expanded (such as HEAD~, or a SHA-1) it will be supplied as it was originally given.

If this hook exits with a non-zero status, git push will abort without pushing anything. Information about why the push is rejected may be sent to the user by writing to standard error.

12. pre-receive

This hook is invoked by git-receive-pack on the remote repository, which happens when a git push is done on a local repository. Just before starting to update refs on the remote repository, the pre-receive hook is invoked. Its exit status determines the success or failure of the update.

This hook executes once for the receive operation. It takes no arguments, but for each ref to be updated it receives on standard input a line of the format:

<old-value> SP <new-value> SP <ref-name> LF

where <old-value> is the old object name stored in the ref, <new-value> is the new object name to be stored in the ref and <ref-name> is the full name of the ref. When creating a new ref, <old-value> is 40 0.

If the hook exits with non-zero status, none of the refs will be updated. If the hook exits with zero, updating of individual refs can still be prevented by the update hook.

Both standard output and standard error output are forwarded to git send-pack on the other end, so you can simply echo messages for the user.

13. update

This hook is invoked by git-receive-pack on the remote repository, which happens when a git push is done on a local repository. Just before updating the ref on the remote repository, the update hook is invoked. Its exit status determines the success or failure of the ref update.

The hook executes once for each ref to be updated, and takes three parameters:

  • the name of the ref being updated,
  • the old object name stored in the ref,
  • and the new object name to be stored in the ref.

A zero exit from the update hook allows the ref to be updated. Exiting with a non-zero status prevents git-receive-pack from updating that ref.

This hook can be used to prevent forced update on certain refs by making sure that the object name is a commit object that is a descendant of the commit object named by the old object name. That is, to enforce a "fast-forward only" policy.

It could also be used to log the old..new status. However, it does not know the entire set of branches, so it would end up firing one e-mail per ref when used naively, though. The post-receive hook is more suited to that.

Another use suggested on the mailing list is to use this hook to implement access control which is finer grained than the one based on filesystem group.

Both standard output and standard error output are forwarded to git send-pack on the other end, so you can simply echo messages for the user.

The default update hook, when enabled--and with hooks.allowunannotated config option unset or set to false--prevents unannotated tags to be pushed.

14. post-receive

This hook is invoked by git-receive-pack on the remote repository, which happens when a git push is done on a local repository. It executes on the remote repository once after all the refs have been updated.

This hook executes once for the receive operation. It takes no arguments, but gets the same information as the pre-receive hook does on its standard input.

This hook does not affect the outcome of git-receive-pack, as it is called after the real work is done.

This supersedes the post-update hook in that it gets both old and new values of all the refs in addition to their names.

Both standard output and standard error output are forwarded to git send-pack on the other end, so you can simply echo messages for the user.

The default post-receive hook is empty, but there is a sample script post-receive-email provided in the contrib/hooks directory in Git distribution, which implements sending commit emails.

15. post-update

This hook is invoked by git-receive-pack on the remote repository, which happens when a git push is done on a local repository. It executes on the remote repository once after all the refs have been updated.

It takes a variable number of parameters, each of which is the name of ref that was actually updated.

This hook is meant primarily for notification, and cannot affect the outcome of git-receive-pack.

The post-update hook can tell what are the heads that were pushed, but it does not know what their original and updated values are, so it is a poor place to do log old..new. The post-receive hook does get both original and updated values of the refs. You might consider it instead if you need them.

When enabled, the default post-update hook runs git update-server-info to keep the information used by dumb transports (e.g., HTTP) up-to-date. If you are publishing a Git repository that is accessible via HTTP, you should probably enable this hook.

Both standard output and standard error output are forwarded to git send-pack on the other end, so you can simply echo messages for the user.

16. push-to-checkout

This hook is invoked by git-receive-pack on the remote repository, which happens when a git push is done on a local repository, when the push tries to update the branch that is currently checked out and the receive.denyCurrentBranch configuration variable is set to updateInstead. Such a push by default is refused if the working tree and the index of the remote repository has any difference from the currently checked out commit; when both the working tree and the index match the current commit, they are updated to match the newly pushed tip of the branch. This hook is to be used to override the default behaviour.

The hook receives the commit with which the tip of the current branch is going to be updated. It can exit with a non-zero status to refuse the push (when it does so, it must not modify the index or the working tree). Or it can make any necessary changes to the working tree and to the index to bring them to the desired state when the tip of the current branch is updated to the new commit, and exit with a zero status.

For example, the hook can simply run git read-tree -u -m HEAD "$1" in order to emulate git fetch that is run in the reverse direction with git push, as the two-tree form of read-tree -u -m is essentially the same as git checkout that switches branches while keeping the local changes in the working tree that do not interfere with the difference between the branches.

17. pre-auto-gc

This hook is invoked by git gc --auto. It takes no parameter, and exiting with non-zero status from this script causes the git gc --auto to abort.

18. post-rewrite

This hook is invoked by commands that rewrite commits (git commit --amend, git-rebase; currently git-filter-branch does not call it!). Its first argument denotes the command it was invoked by: currently one of amend or rebase. Further command-dependent arguments may be passed in the future.

The hook receives a list of the rewritten commits on stdin, in the format

<old-sha1> SP <new-sha1> [ SP <extra-info> ] LF

The extra-info is again command-dependent. If it is empty, the preceding SP is also omitted. Currently, no commands pass any extra-info.

The hook always runs after the automatic note copying (see "notes.rewrite.<command>" in Section G.3.27, “git-config(1)”) has happened, and thus has access to these notes.

The following command-specific comments apply:


For the squash and fixup operation, all commits that were squashed are listed as being rewritten to the squashed commit. This means that there will be several lines sharing the same new-sha1.

The commits are guaranteed to be listed in the order that they were processed by rebase.


Part of the Section G.3.1, “git(1)” suite

G.4.7. gitk(1)


gitk - The Git repository browser


gitk [<options>] [<revision range>] [--] [<path>…]


Displays changes in a repository or a selected set of commits. This includes visualizing the commit graph, showing information related to each commit, and the files in the trees of each revision.


To control which revisions to show, gitk supports most options applicable to the git rev-list command. It also supports a few options applicable to the git diff-* commands to control how the changes each commit introduces are shown. Finally, it supports some gitk-specific options.

gitk generally only understands options with arguments in the sticked form (see Section G.4.1, “gitcli(7)”) due to limitations in the command-line parser.

1. rev-list options and arguments

This manual page describes only the most frequently used options. See Section G.3.112, “git-rev-list(1)” for a complete list.

Show all refs (branches, tags, etc.).
--branches[=<pattern>] , --tags[=<pattern>] , --remotes[=<pattern>]
Pretend as if all the branches (tags, remote branches, resp.) are listed on the command line as <commit>. If <pattern> is given, limit refs to ones matching given shell glob. If pattern lacks ?, *, or [, /* at the end is implied.
Show commits more recent than a specific date.
Show commits older than a specific date.
Sort commits by date when possible.
After an attempt to merge stops with conflicts, show the commits on the history between two branches (i.e. the HEAD and the MERGE_HEAD) that modify the conflicted files and do not exist on all the heads being merged.
Mark which side of a symmetric diff a commit is reachable from. Commits from the left side are prefixed with a < symbol and those from the right with a > symbol.
When filtering history with <path>…, does not prune some history. (See "History simplification" in Section G.3.68, “git-log(1)” for a more detailed explanation.)
Additional option to --full-history to remove some needless merges from the resulting history, as there are no selected commits contributing to this merge. (See "History simplification" in Section G.3.68, “git-log(1)” for a more detailed explanation.)
When given a range of commits to display (e.g. commit1..commit2 or commit2 ^commit1), only display commits that exist directly on the ancestry chain between the commit1 and commit2, i.e. commits that are both descendants of commit1, and ancestors of commit2. (See "History simplification" in Section G.3.68, “git-log(1)” for a more detailed explanation.)
-L<start>,<end>:<file> , -L:<funcname>:<file>

Trace the evolution of the line range given by "<start>,<end>" (or the function name regex <funcname>) within the <file>. You may not give any pathspec limiters. This is currently limited to a walk starting from a single revision, i.e., you may only give zero or one positive revision arguments. You can specify this option more than once.

Note: gitk (unlike Section G.3.68, “git-log(1)”) currently only understands this option if you specify it "glued together" with its argument. Do not put a space after -L.

<start> and <end> can take one of these forms:

  • number

    If <start> or <end> is a number, it specifies an absolute line number (lines count from 1).

  • /regex/

    This form will use the first line matching the given POSIX regex. If <start> is a regex, it will search from the end of the previous -L range, if any, otherwise from the start of file. If <start> is ^/regex/, it will search from the start of file. If <end> is a regex, it will search starting at the line given by <start>.

  • +offset or -offset

    This is only valid for <end> and will specify a number of lines before or after the line given by <start>.

If :<funcname> is given in place of <start> and <end>, it is a regular expression that denotes the range from the first funcname line that matches <funcname>, up to the next funcname line. :<funcname> searches from the end of the previous -L range, if any, otherwise from the start of file. ^:<funcname> searches from the start of file.

<revision range>
Limit the revisions to show. This can be either a single revision meaning show from the given revision and back, or it can be a range in the form "<from>..<to>" to show all revisions between <from> and back to <to>. Note, more advanced revision selection can be applied. For a more complete list of ways to spell object names, see Section G.4.12, “gitrevisions(7)”.
Limit commits to the ones touching files in the given paths. Note, to avoid ambiguity with respect to revision names use "--" to separate the paths from any preceding options.

2. gitk-specific options

Command to be run each time gitk has to determine the revision range to show. The command is expected to print on its standard output a list of additional revisions to be shown, one per line. Use this instead of explicitly specifying a <revision range> if the set of commits to show may vary between refreshes.
Select the specified commit after loading the graph. Default behavior is equivalent to specifying --select-commit=HEAD.


gitk v2.6.12.. include/scsi drivers/scsi
Show the changes since version v2.6.12 that changed any file in the include/scsi or drivers/scsi subdirectories
gitk --since="2 weeks ago" -- gitk
Show the changes during the last two weeks to the file gitk. The "--" is necessary to avoid confusion with the branch named gitk
gitk --max-count=100 --all -- Makefile
Show at most 100 changes made to the file Makefile. Instead of only looking for changes in the current branch look in all branches.


User configuration and preferences are stored at:

  • $XDG_CONFIG_HOME/git/gitk if it exists, otherwise
  • $HOME/.gitk if it exists

If neither of the above exist then $XDG_CONFIG_HOME/git/gitk is created and used by default. If $XDG_CONFIG_HOME is not set it defaults to $HOME/.config in all cases.


Gitk was the first graphical repository browser. It's written in tcl/tk and started off in a separate repository but was later merged into the main Git repository.


A repository browser written in C++ using Qt.
A repository browser written in Python using Gtk. It's based on bzrk(1) and distributed in the contrib area of the Git repository.
A minimal repository browser and Git tool output highlighter written in C using Ncurses.


Part of the Section G.3.1, “git(1)” suite

G.4.8. gitmodules(5)


gitmodules - defining submodule properties




The .gitmodules file, located in the top-level directory of a Git working tree, is a text file with a syntax matching the requirements of Section G.3.27, “git-config(1)”.

The file contains one subsection per submodule, and the subsection value is the name of the submodule. The name is set to the path where the submodule has been added unless it was customized with the --name option of git submodule add. Each submodule section also contains the following required keys:

Defines the path, relative to the top-level directory of the Git working tree, where the submodule is expected to be checked out. The path name must not end with a /. All submodule paths must be unique within the .gitmodules file.
Defines a URL from which the submodule repository can be cloned. This may be either an absolute URL ready to be passed to Section G.3.23, “git-clone(1)” or (if it begins with ./ or ../) a location relative to the superproject's origin repository.

In addition, there are a number of optional keys:

Defines the default update procedure for the named submodule, i.e. how the submodule is updated by "git submodule update" command in the superproject. This is only used by git submodule init to initialize the configuration variable of the same name. Allowed values here are checkout, rebase, merge or none. See description of update command in Section G.3.131, “git-submodule(1)” for their meaning. Note that the !command form is intentionally ignored here for security reasons.
A remote branch name for tracking updates in the upstream submodule. If the option is not specified, it defaults to master. See the --remote documentation in Section G.3.131, “git-submodule(1)” for details.
This option can be used to control recursive fetching of this submodule. If this option is also present in the submodules entry in .git/config of the superproject, the setting there will override the one found in .gitmodules. Both settings can be overridden on the command line by using the "--[no-]recurse-submodules" option to "git fetch" and "git pull".
Defines under what circumstances "git status" and the diff family show a submodule as modified. When set to "all", it will never be considered modified (but will nonetheless show up in the output of status and commit when it has been staged), "dirty" will ignore all changes to the submodules work tree and takes only differences between the HEAD of the submodule and the commit recorded in the superproject into account. "untracked" will additionally let submodules with modified tracked files in their work tree show up. Using "none" (the default when this option is not set) also shows submodules that have untracked files in their work tree as changed. If this option is also present in the submodules entry in .git/config of the superproject, the setting there will override the one found in .gitmodules. Both settings can be overridden on the command line by using the "--ignore-submodule" option. The git submodule commands are not affected by this setting.


Consider the following .gitmodules file:

[submodule "libfoo"]
        path = include/foo
        url = git://foo.com/git/lib.git
[submodule "libbar"]
        path = include/bar
        url = git://bar.com/git/lib.git

This defines two submodules, libfoo and libbar. These are expected to be checked out in the paths include/foo and include/bar, and for both submodules a URL is specified which can be used for cloning the submodules.


Part of the Section G.3.1, “git(1)” suite

G.4.9. gitnamespaces(7)


gitnamespaces - Git namespaces


GIT_NAMESPACE=<namespace> git upload-pack
GIT_NAMESPACE=<namespace> git receive-pack


Git supports dividing the refs of a single repository into multiple namespaces, each of which has its own branches, tags, and HEAD. Git can expose each namespace as an independent repository to pull from and push to, while sharing the object store, and exposing all the refs to operations such as Section G.3.53, “git-gc(1)”.

Storing multiple repositories as namespaces of a single repository avoids storing duplicate copies of the same objects, such as when storing multiple branches of the same source. The alternates mechanism provides similar support for avoiding duplicates, but alternates do not prevent duplication between new objects added to the repositories without ongoing maintenance, while namespaces do.

To specify a namespace, set the GIT_NAMESPACE environment variable to the namespace. For each ref namespace, Git stores the corresponding refs in a directory under refs/namespaces/. For example, GIT_NAMESPACE=foo will store refs under refs/namespaces/foo/. You can also specify namespaces via the --namespace option to Section G.3.1, “git(1)”.

Note that namespaces which include a / will expand to a hierarchy of namespaces; for example, GIT_NAMESPACE=foo/bar will store refs under refs/namespaces/foo/refs/namespaces/bar/. This makes paths in GIT_NAMESPACE behave hierarchically, so that cloning with GIT_NAMESPACE=foo/bar produces the same result as cloning with GIT_NAMESPACE=foo and cloning from that repo with GIT_NAMESPACE=bar. It also avoids ambiguity with strange namespace paths such as foo/refs/heads/, which could otherwise generate directory/file conflicts within the refs directory.

Section G.3.141, “git-upload-pack(1)” and Section G.3.100, “git-receive-pack(1)” rewrite the names of refs as specified by GIT_NAMESPACE. git-upload-pack and git-receive-pack will ignore all references outside the specified namespace.

The smart HTTP server, Section G.3.59, “git-http-backend(1)”, will pass GIT_NAMESPACE through to the backend programs; see Section G.3.59, “git-http-backend(1)” for sample configuration to expose repository namespaces as repositories.

For a simple local test, you can use Section G.3.103, “git-remote-ext(1)”:

git clone ext::'git --namespace=foo %s /tmp/prefixed.git'


Anyone with access to any namespace within a repository can potentially access objects from any other namespace stored in the same repository. You can't directly say "give me object ABCD" if you don't have a ref to it, but you can do some other sneaky things like:

  1. Claiming to push ABCD, at which point the server will optimize out the need for you to actually send it. Now you have a ref to ABCD and can fetch it (claiming not to have it, of course).
  2. Requesting other refs, claiming that you have ABCD, at which point the server may generate deltas against ABCD.

None of this causes a problem if you only host public repositories, or if everyone who may read one namespace may also read everything in every other namespace (for instance, if everyone in an organization has read permission to every repository).

G.4.10. gitremote-helpers(1)


gitremote-helpers - Helper programs to interact with remote repositories


git remote-<transport> <repository> [<URL>]


Remote helper programs are normally not used directly by end users, but they are invoked by Git when it needs to interact with remote repositories Git does not support natively. A given helper will implement a subset of the capabilities documented here. When Git needs to interact with a repository using a remote helper, it spawns the helper as an independent process, sends commands to the helper's standard input, and expects results from the helper's standard output. Because a remote helper runs as an independent process from Git, there is no need to re-link Git to add a new helper, nor any need to link the helper with the implementation of Git.

Every helper must support the "capabilities" command, which Git uses to determine what other commands the helper will accept. Those other commands can be used to discover and update remote refs, transport objects between the object database and the remote repository, and update the local object store.

Git comes with a "curl" family of remote helpers, that handle various transport protocols, such as git-remote-http, git-remote-https, git-remote-ftp and git-remote-ftps. They implement the capabilities fetch, option, and push.


Remote helper programs are invoked with one or (optionally) two arguments. The first argument specifies a remote repository as in Git; it is either the name of a configured remote or a URL. The second argument specifies a URL; it is usually of the form <transport>://<address>, but any arbitrary string is possible. The GIT_DIR environment variable is set up for the remote helper and can be used to determine where to store additional data or from which directory to invoke auxiliary Git commands.

When Git encounters a URL of the form <transport>://<address>, where <transport> is a protocol that it cannot handle natively, it automatically invokes git remote-<transport> with the full URL as the second argument. If such a URL is encountered directly on the command line, the first argument is the same as the second, and if it is encountered in a configured remote, the first argument is the name of that remote.

A URL of the form <transport>::<address> explicitly instructs Git to invoke git remote-<transport> with <address> as the second argument. If such a URL is encountered directly on the command line, the first argument is <address>, and if it is encountered in a configured remote, the first argument is the name of that remote.

Additionally, when a configured remote has remote.<name>.vcs set to <transport>, Git explicitly invokes git remote-<transport> with <name> as the first argument. If set, the second argument is remote.<name>.url; otherwise, the second argument is omitted.


Git sends the remote helper a list of commands on standard input, one per line. The first command is always the capabilities command, in response to which the remote helper must print a list of the capabilities it supports (see below) followed by a blank line. The response to the capabilities command determines what commands Git uses in the remainder of the command stream.

The command stream is terminated by a blank line. In some cases (indicated in the documentation of the relevant commands), this blank line is followed by a payload in some other protocol (e.g., the pack protocol), while in others it indicates the end of input.

1. Capabilities

Each remote helper is expected to support only a subset of commands. The operations a helper supports are declared to Git in the response to the capabilities command (see COMMANDS, below).

In the following, we list all defined capabilities and for each we list which commands a helper with that capability must provide.

1.1. Capabilities for Pushing


Can attempt to connect to git receive-pack (for pushing), git upload-pack, etc for communication using git's native packfile protocol. This requires a bidirectional, full-duplex connection.

Supported commands: connect.


Can discover remote refs and push local commits and the history leading up to them to new or existing remote refs.

Supported commands: list for-push, push.


Can discover remote refs and push specified objects from a fast-import stream to remote refs.

Supported commands: list for-push, export.

If a helper advertises connect, Git will use it if possible and fall back to another capability if the helper requests so when connecting (see the connect command under COMMANDS). When choosing between push and export, Git prefers push. Other frontends may have some other order of preference.

When using the refspec capability, git normally updates the private ref on successful push. This update is disabled when the remote-helper declares the capability no-private-update.

1.2. Capabilities for Fetching


Can try to connect to git upload-pack (for fetching), git receive-pack, etc for communication using the Git's native packfile protocol. This requires a bidirectional, full-duplex connection.

Supported commands: connect.


Can discover remote refs and transfer objects reachable from them to the local object store.

Supported commands: list, fetch.


Can discover remote refs and output objects reachable from them as a stream in fast-import format.

Supported commands: list, import.

Can guarantee that when a clone is requested, the received pack is self contained and is connected.

If a helper advertises connect, Git will use it if possible and fall back to another capability if the helper requests so when connecting (see the connect command under COMMANDS). When choosing between fetch and import, Git prefers fetch. Other frontends may have some other order of preference.

1.3. Miscellaneous capabilities

For specifying settings like verbosity (how much output to write to stderr) and depth (how much history is wanted in the case of a shallow clone) that affect how other commands are carried out.
refspec <refspec>

For remote helpers that implement import or export, this capability allows the refs to be constrained to a private namespace, instead of writing to refs/heads or refs/remotes directly. It is recommended that all importers providing the import capability use this. It's mandatory for export.

A helper advertising the capability refspec refs/heads/*:refs/svn/origin/branches/* is saying that, when it is asked to import refs/heads/topic, the stream it outputs will update the refs/svn/origin/branches/topic ref.

This capability can be advertised multiple times. The first applicable refspec takes precedence. The left-hand of refspecs advertised with this capability must cover all refs reported by the list command. If no refspec capability is advertised, there is an implied refspec *:*.

When writing remote-helpers for decentralized version control systems, it is advised to keep a local copy of the repository to interact with, and to let the private namespace refs point to this local repository, while the refs/remotes namespace is used to track the remote repository.

This modifies the import capability. The fast-import commands cat-blob and ls can be used by remote-helpers to retrieve information about blobs and trees that already exist in fast-import's memory. This requires a channel from fast-import to the remote-helper. If it is advertised in addition to "import", Git establishes a pipe from fast-import to the remote-helper's stdin. It follows that Git and fast-import are both connected to the remote-helper's stdin. Because Git can send multiple commands to the remote-helper it is required that helpers that use bidi-import buffer all import commands of a batch before sending data to fast-import. This is to prevent mixing commands and fast-import responses on the helper's stdin.
export-marks <file>
This modifies the export capability, instructing Git to dump the internal marks table to <file> when complete. For details, read up on --export-marks=<file> in Section G.3.43, “git-fast-export(1)”.
import-marks <file>
This modifies the export capability, instructing Git to load the marks specified in <file> before processing any input. For details, read up on --import-marks=<file> in Section G.3.43, “git-fast-export(1)”.
This modifies the export capability, instructing Git to pass --signed-tags=verbatim to Section G.3.43, “git-fast-export(1)”. In the absence of this capability, Git will use --signed-tags=warn-strip.


Commands are given by the caller on the helper's standard input, one per line.


Lists the capabilities of the helper, one per line, ending with a blank line. Each capability may be preceded with *, which marks them mandatory for Git versions using the remote helper to understand. Any unknown mandatory capability is a fatal error.

Support for this command is mandatory.


Lists the refs, one per line, in the format "<value> <name> [<attr> …]". The value may be a hex sha1 hash, "@<dest>" for a symref, or "?" to indicate that the helper could not get the value of the ref. A space-separated list of attributes follows the name; unrecognized attributes are ignored. The list ends with a blank line.

See REF LIST ATTRIBUTES for a list of currently defined attributes.

Supported if the helper has the "fetch" or "import" capability.

list for-push

Similar to list, except that it is used if and only if the caller wants to the resulting ref list to prepare push commands. A helper supporting both push and fetch can use this to distinguish for which operation the output of list is going to be used, possibly reducing the amount of work that needs to be performed.

Supported if the helper has the "push" or "export" capability.

option <name> <value>

Sets the transport helper option <name> to <value>. Outputs a single line containing one of ok (option successfully set), unsupported (option not recognized) or error <msg> (option <name> is supported but <value> is not valid for it). Options should be set before other commands, and may influence the behavior of those commands.

See OPTIONS for a list of currently defined options.

Supported if the helper has the "option" capability.

fetch <sha1> <name>

Fetches the given object, writing the necessary objects to the database. Fetch commands are sent in a batch, one per line, terminated with a blank line. Outputs a single blank line when all fetch commands in the same batch are complete. Only objects which were reported in the output of list with a sha1 may be fetched this way.

Optionally may output a lock <file> line indicating a file under GIT_DIR/objects/pack which is keeping a pack until refs can be suitably updated.

If option check-connectivity is requested, the helper must output connectivity-ok if the clone is self-contained and connected.

Supported if the helper has the "fetch" capability.

push +<src>:<dst>

Pushes the given local <src> commit or branch to the remote branch described by <dst>. A batch sequence of one or more push commands is terminated with a blank line (if there is only one reference to push, a single push command is followed by a blank line). For example, the following would be two batches of push, the first asking the remote-helper to push the local ref master to the remote ref master and the local HEAD to the remote branch, and the second asking to push ref foo to ref bar (forced update requested by the +).

push refs/heads/master:refs/heads/master
push HEAD:refs/heads/branch
push +refs/heads/foo:refs/heads/bar

Zero or more protocol options may be entered after the last push command, before the batch's terminating blank line.

When the push is complete, outputs one or more ok <dst> or error <dst> <why>? lines to indicate success or failure of each pushed ref. The status report output is terminated by a blank line. The option field <why> may be quoted in a C style string if it contains an LF.

Supported if the helper has the "push" capability.

import <name>

Produces a fast-import stream which imports the current value of the named ref. It may additionally import other refs as needed to construct the history efficiently. The script writes to a helper-specific private namespace. The value of the named ref should be written to a location in this namespace derived by applying the refspecs from the "refspec" capability to the name of the ref.

Especially useful for interoperability with a foreign versioning system.

Just like push, a batch sequence of one or more import is terminated with a blank line. For each batch of import, the remote helper should produce a fast-import stream terminated by a done command.

Note that if the bidi-import capability is used the complete batch sequence has to be buffered before starting to send data to fast-import to prevent mixing of commands and fast-import responses on the helper's stdin.

Supported if the helper has the "import" capability.


Instructs the remote helper that any subsequent input is part of a fast-import stream (generated by git fast-export) containing objects which should be pushed to the remote.

Especially useful for interoperability with a foreign versioning system.

The export-marks and import-marks capabilities, if specified, affect this command in so far as they are passed on to git fast-export, which then will load/store a table of marks for local objects. This can be used to implement for incremental operations.

Supported if the helper has the "export" capability.

connect <service>

Connects to given service. Standard input and standard output of helper are connected to specified service (git prefix is included in service name so e.g. fetching uses git-upload-pack as service) on remote side. Valid replies to this command are empty line (connection established), fallback (no smart transport support, fall back to dumb transports) and just exiting with error message printed (can't connect, don't bother trying to fall back). After line feed terminating the positive (empty) response, the output of service starts. After the connection ends, the remote helper exits.

Supported if the helper has the "connect" capability.

If a fatal error occurs, the program writes the error message to stderr and exits. The caller should expect that a suitable error message has been printed if the child closes the connection without completing a valid response for the current command.

Additional commands may be supported, as may be determined from capabilities reported by the helper.


The list command produces a list of refs in which each ref may be followed by a list of attributes. The following ref list attributes are defined.

This ref is unchanged since the last import or fetch, although the helper cannot necessarily determine what value that produced.


The following options are defined and (under suitable circumstances) set by Git if the remote helper has the option capability.

option verbosity <n>
Changes the verbosity of messages displayed by the helper. A value of 0 for <n> means that processes operate quietly, and the helper produces only error output. 1 is the default level of verbosity, and higher values of <n> correspond to the number of -v flags passed on the command line.
option progress {true|false}
Enables (or disables) progress messages displayed by the transport helper during a command.
option depth <depth>
Deepens the history of a shallow repository.
option followtags {true|false}
If enabled the helper should automatically fetch annotated tag objects if the object the tag points at was transferred during the fetch command. If the tag is not fetched by the helper a second fetch command will usually be sent to ask for the tag specifically. Some helpers may be able to use this option to avoid a second network connection.

option dry-run {true|false}: If true, pretend the operation completed successfully, but don't actually change any repository data. For most helpers this only applies to the push, if supported.

option servpath <c-style-quoted-path>
Sets service path (--upload-pack, --receive-pack etc.) for next connect. Remote helper may support this option, but must not rely on this option being set before connect request occurs.
option check-connectivity {true|false}
Request the helper to check connectivity of a clone.
option force {true|false}
Request the helper to perform a force update. Defaults to false.
option cloning {'true|false}
Notify the helper this is a clone request (i.e. the current repository is guaranteed empty).
option update-shallow {'true|false}
Allow to extend .git/shallow if the new refs require it.
option pushcert {'true|false}
GPG sign pushes.


Part of the Section G.3.1, “git(1)” suite

G.4.11. gitrepository-layout(5)


gitrepository-layout - Git Repository Layout




A Git repository comes in two different flavours:

  • a .git directory at the root of the working tree;
  • a <project>.git directory that is a bare repository (i.e. without its own working tree), that is typically used for exchanging histories with others by pushing into it and fetching from it.

Note: Also you can have a plain text file .git at the root of your working tree, containing gitdir: <path> to point at the real directory that has the repository. This mechanism is often used for a working tree of a submodule checkout, to allow you in the containing superproject to git checkout a branch that does not have the submodule. The checkout has to remove the entire submodule working tree, without losing the submodule repository.

These things may exist in a Git repository.


Object store associated with this repository. Usually an object store is self sufficient (i.e. all the objects that are referred to by an object found in it are also found in it), but there are a few ways to violate it.

  1. You could have an incomplete but locally usable repository by creating a shallow clone. See Section G.3.23, “git-clone(1)”.
  2. You could be using the objects/info/alternates or $GIT_ALTERNATE_OBJECT_DIRECTORIES mechanisms to borrow objects from other object stores. A repository with this kind of incomplete object store is not suitable to be published for use with dumb transports but otherwise is OK as long as objects/info/alternates points at the object stores it borrows from.

    This directory is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/objects" will be used instead.

A newly created object is stored in its own file. The objects are splayed over 256 subdirectories using the first two characters of the sha1 object name to keep the number of directory entries in objects itself to a manageable number. Objects found here are often called unpacked (or loose) objects.
Packs (files that store many object in compressed form, along with index files to allow them to be randomly accessed) are found in this directory.
Additional information about the object store is recorded in this directory.
This file is to help dumb transports discover what packs are available in this object store. Whenever a pack is added or removed, git update-server-info should be run to keep this file up-to-date if the repository is published for dumb transports. git repack does this by default.
This file records paths to alternate object stores that this object store borrows objects from, one pathname per line. Note that not only native Git tools use it locally, but the HTTP fetcher also tries to use it remotely; this will usually work if you have relative paths (relative to the object database, not to the repository!) in your alternates file, but it will not work if you use absolute paths unless the absolute path in filesystem and web URL is the same. See also objects/info/http-alternates.
This file records URLs to alternate object stores that this object store borrows objects from, to be used when the repository is fetched over HTTP.
References are stored in subdirectories of this directory. The git prune command knows to preserve objects reachable from refs found in this directory and its subdirectories. This directory is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/refs" will be used instead.
records tip-of-the-tree commit objects of branch name
records any object name (not necessarily a commit object, or a tag object that points at a commit object).
records tip-of-the-tree commit objects of branches copied from a remote repository.
records the SHA-1 of the object that replaces <obj-sha1>. This is similar to info/grafts and is internally used and maintained by Section G.3.108, “git-replace(1)”. Such refs can be exchanged between repositories while grafts are not.
records the same information as refs/heads/, refs/tags/, and friends record in a more efficient way. See Section G.3.90, “git-pack-refs(1)”. This file is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/packed-refs" will be used instead.

A symref (see glossary) to the refs/heads/ namespace describing the currently active branch. It does not mean much if the repository is not associated with any working tree (i.e. a bare repository), but a valid Git repository must have the HEAD file; some porcelains may use it to guess the designated "default" branch of the repository (usually master). It is legal if the named branch name does not (yet) exist. In some legacy setups, it is a symbolic link instead of a symref that points at the current branch.

HEAD can also record a specific commit directly, instead of being a symref to point at the current branch. Such a state is often called detached HEAD. See Section G.3.18, “git-checkout(1)” for details.

Repository specific configuration file. This file is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/config" will be used instead.
A slightly deprecated way to store shorthands to be used to specify a URL to git fetch, git pull and git push. A file can be stored as branches/<name> and then name can be given to these commands in place of repository argument. See the REMOTES section in Section G.3.46, “git-fetch(1)” for details. This mechanism is legacy and not likely to be found in modern repositories. This directory is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/branches" will be used instead.
Hooks are customization scripts used by various Git commands. A handful of sample hooks are installed when git init is run, but all of them are disabled by default. To enable, the .sample suffix has to be removed from the filename by renaming. Read Section G.4.6, “githooks(5)” for more details about each hook. This directory is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/hooks" will be used instead.
The current index file for the repository. It is usually not found in a bare repository.
The shared index part, to be referenced by $GIT_DIR/index and other temporary index files. Only valid in split index mode.
Additional information about the repository is recorded in this directory. This directory is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/index" will be used instead.
This file helps dumb transports discover what refs are available in this repository. If the repository is published for dumb transports, this file should be regenerated by git update-server-info every time a tag or branch is created or modified. This is normally done from the hooks/update hook, which is run by the git-receive-pack command when you git push into the repository.

This file records fake commit ancestry information, to pretend the set of parents a commit has is different from how the commit was actually created. One record per line describes a commit and its fake parents by listing their 40-byte hexadecimal object names separated by a space and terminated by a newline.

Note that the grafts mechanism is outdated and can lead to problems transferring objects between repositories; see Section G.3.108, “git-replace(1)” for a more flexible and robust system to do the same thing.

This file, by convention among Porcelains, stores the exclude pattern list. .gitignore is the per-directory ignore file. git status, git add, git rm and git clean look at it but the core Git commands do not look at it. See also: Section G.4.5, “gitignore(5)”.
This file stores sparse checkout patterns. See also: Section G.3.98, “git-read-tree(1)”.
Stores shorthands for URL and default refnames for use when interacting with remote repositories via git fetch, git pull and git push commands. See the REMOTES section in Section G.3.46, “git-fetch(1)” for details. This mechanism is legacy and not likely to be found in modern repositories. This directory is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/remotes" will be used instead.
Records of changes made to refs are stored in this directory. See Section G.3.138, “git-update-ref(1)” for more information. This directory is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/logs" will be used instead.
Records all changes made to the branch tip named name.
Records all changes made to the tag named name.
This is similar to info/grafts but is internally used and maintained by shallow clone mechanism. See --depth option to Section G.3.23, “git-clone(1)” and Section G.3.46, “git-fetch(1)”. This file is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/shallow" will be used instead.
If this file exists, $GIT_COMMON_DIR (see Section G.3.1, “git(1)”) will be set to the path specified in this file if it is not explicitly set. If the specified path is relative, it is relative to $GIT_DIR. The repository with commondir is incomplete without the repository pointed by "commondir".
Contains the git-repositories of the submodules.
Contains administrative data for linked working trees. Each subdirectory contains the working tree-related part of a linked working tree. This directory is ignored if $GIT_COMMON_DIR is set, in which case "$GIT_COMMON_DIR/worktrees" will be used instead.
A text file containing the absolute path back to the .git file that points to here. This is used to check if the linked repository has been manually removed and there is no need to keep this directory any more. The mtime of this file should be updated every time the linked repository is accessed.
If this file exists, the linked working tree may be on a portable device and not available. The presence of this file prevents worktrees/<id> from being pruned either automatically or manually by git worktree prune. The file may contain a string explaining why the repository is locked.
If this file exists, it is a hard link to the linked .git file. It is used to detect if the linked repository is manually removed.


Part of the Section G.3.1, “git(1)” suite.

G.4.12. gitrevisions(7)


gitrevisions - specifying revisions and ranges for Git




Many Git commands take revision parameters as arguments. Depending on the command, they denote a specific commit or, for commands which walk the revision graph (such as Section G.3.68, “git-log(1)”), all commits which can be reached from that commit. In the latter case one can also specify a range of revisions explicitly.

In addition, some Git commands (such as Section G.3.126, “git-show(1)”) also take revision parameters which denote other objects than commits, e.g. blobs ("files") or trees ("directories of files").


A revision parameter <rev> typically, but not necessarily, names a commit object. It uses what is called an extended SHA-1 syntax. Here are various ways to spell object names. The ones listed near the end of this list name trees and blobs contained in a commit.

<sha1>, e.g. dae86e1950b1277e545cee180551750029cfe735, dae86e
The full SHA-1 object name (40-byte hexadecimal string), or a leading substring that is unique within the repository. E.g. dae86e1950b1277e545cee180551750029cfe735 and dae86e both name the same commit object if there is no other object in your repository whose object name starts with dae86e.
<describeOutput>, e.g. v1.7.4.2-679-g3bee7fb
Output from git describe; i.e. a closest tag, optionally followed by a dash and a number of commits, followed by a dash, a g, and an abbreviated object name.
<refname>, e.g. master, heads/master, refs/heads/master

A symbolic ref name. E.g. master typically means the commit object referenced by refs/heads/master. If you happen to have both heads/master and tags/master, you can explicitly say heads/master to tell Git which one you mean. When ambiguous, a <refname> is disambiguated by taking the first match in the following rules:

  1. If $GIT_DIR/<refname> exists, that is what you mean (this is usually useful only for HEAD, FETCH_HEAD, ORIG_HEAD, MERGE_HEAD and CHERRY_PICK_HEAD);
  2. otherwise, refs/<refname> if it exists;
  3. otherwise, refs/tags/<refname> if it exists;
  4. otherwise, refs/heads/<refname> if it exists;
  5. otherwise, refs/remotes/<refname> if it exists;
  6. otherwise, refs/remotes/<refname>/HEAD if it exists.

    HEAD names the commit on which you based the changes in the working tree. FETCH_HEAD records the branch which you fetched from a remote repository with your last git fetch invocation. ORIG_HEAD is created by commands that move your HEAD in a drastic way, to record the position of the HEAD before their operation, so that you can easily change the tip of the branch back to the state before you ran them. MERGE_HEAD records the commit(s) which you are merging into your branch when you run git merge. CHERRY_PICK_HEAD records the commit which you are cherry-picking when you run git cherry-pick.

    Note that any of the refs/* cases above may come either from the $GIT_DIR/refs directory or from the $GIT_DIR/packed-refs file. While the ref name encoding is unspecified, UTF-8 is preferred as some output processing may assume ref names in UTF-8.

@ alone is a shortcut for HEAD.
<refname>@{<date>}, e.g. master@{yesterday}, HEAD@{5 minutes ago}
A ref followed by the suffix @ with a date specification enclosed in a brace pair (e.g. {yesterday}, {1 month 2 weeks 3 days 1 hour 1 second ago} or {1979-02-26 18:30:00}) specifies the value of the ref at a prior point in time. This suffix may only be used immediately following a ref name and the ref must have an existing log ($GIT_DIR/logs/<ref>). Note that this looks up the state of your local ref at a given time; e.g., what was in your local master branch last week. If you want to look at commits made during certain times, see --since and --until.
<refname>@{<n>}, e.g. master@{1}
A ref followed by the suffix @ with an ordinal specification enclosed in a brace pair (e.g. {1}, {15}) specifies the n-th prior value of that ref. For example master@{1} is the immediate prior value of master while master@{5} is the 5th prior value of master. This suffix may only be used immediately following a ref name and the ref must have an existing log ($GIT_DIR/logs/<refname>).
@{<n>}, e.g. @{1}
You can use the @ construct with an empty ref part to get at a reflog entry of the current branch. For example, if you are on branch blabla then @{1} means the same as blabla@{1}.
@{-<n>}, e.g. @{-1}
The construct @{-<n>} means the <n>th branch/commit checked out before the current one.
<branchname>@{upstream}, e.g. master@{upstream}, @{u}
The suffix @{upstream} to a branchname (short form <branchname>@{u}) refers to the branch that the branch specified by branchname is set to build on top of (configured with branch.<name>.remote and branch.<name>.merge). A missing branchname defaults to the current one.
<branchname>@{push}, e.g. master@{push}, @{push}

The suffix @{push} reports the branch "where we would push to" if git push were run while branchname was checked out (or the current HEAD if no branchname is specified). Since our push destination is in a remote repository, of course, we report the local tracking branch that corresponds to that branch (i.e., something in refs/remotes/).

Here's an example to make it more clear:

$ git config push.default current
$ git config remote.pushdefault myfork
$ git checkout -b mybranch origin/master

$ git rev-parse --symbolic-full-name @{upstream}

$ git rev-parse --symbolic-full-name @{push}

Note in the example that we set up a triangular workflow, where we pull from one location and push to another. In a non-triangular workflow, @{push} is the same as @{upstream}, and there is no need for it.

<rev>^, e.g. HEAD^, v1.5.1^0
A suffix ^ to a revision parameter means the first parent of that commit object. ^<n> means the <n>th parent (i.e. <rev>^ is equivalent to <rev>^1). As a special rule, <rev>^0 means the commit itself and is used when <rev> is the object name of a tag object that refers to a commit object.
<rev>~<n>, e.g. master~3
A suffix ~<n> to a revision parameter means the commit object that is the <n>th generation ancestor of the named commit object, following only the first parents. I.e. <rev>~3 is equivalent to <rev>^^^ which is equivalent to <rev>^1^1^1. See below for an illustration of the usage of this form.
<rev>^{<type>}, e.g. v0.99.8^{commit}

A suffix ^ followed by an object type name enclosed in brace pair means dereference the object at <rev> recursively until an object of type <type> is found or the object cannot be dereferenced anymore (in which case, barf). For example, if <rev> is a commit-ish, <rev>^{commit} describes the corresponding commit object. Similarly, if <rev> is a tree-ish, <rev>^{tree} describes the corresponding tree object. <rev>^0 is a short-hand for <rev>^{commit}.

rev^{object} can be used to make sure rev names an object that exists, without requiring rev to be a tag, and without dereferencing rev; because a tag is already an object, it does not have to be dereferenced even once to get to an object.

rev^{tag} can be used to ensure that rev identifies an existing tag object.

<rev>^{}, e.g. v0.99.8^{}
A suffix ^ followed by an empty brace pair means the object could be a tag, and dereference the tag recursively until a non-tag object is found.
<rev>^{/<text>}, e.g. HEAD^{/fix nasty bug}
A suffix ^ to a revision parameter, followed by a brace pair that contains a text led by a slash, is the same as the :/fix nasty bug syntax below except that it returns the youngest matching commit which is reachable from the <rev> before ^.
:/<text>, e.g. :/fix nasty bug
A colon, followed by a slash, followed by a text, names a commit whose commit message matches the specified regular expression. This name returns the youngest matching commit which is reachable from any ref. The regular expression can match any part of the commit message. To match messages starting with a string, one can use e.g. :/^foo. The special sequence :/! is reserved for modifiers to what is matched. :/!-foo performs a negative match, while :/!!foo matches a literal ! character, followed by foo. Any other sequence beginning with :/! is reserved for now.
<rev>:<path>, e.g. HEAD:README, :README, master:./README
A suffix : followed by a path names the blob or tree at the given path in the tree-ish object named by the part before the colon. :path (with an empty part before the colon) is a special case of the syntax described next: content recorded in the index at the given path. A path starting with ./ or ../ is relative to the current working directory. The given path will be converted to be relative to the working tree's root directory. This is most useful to address a blob or tree from a commit or tree that has the same tree structure as the working tree.
:<n>:<path>, e.g. :0:README, :README
A colon, optionally followed by a stage number (0 to 3) and a colon, followed by a path, names a blob object in the index at the given path. A missing stage number (and the colon that follows it) names a stage 0 entry. During a merge, stage 1 is the common ancestor, stage 2 is the target branch's version (typically the current branch), and stage 3 is the version from the branch which is being merged.

Here is an illustration, by Jon Loeliger. Both commit nodes B and C are parents of commit node A. Parent commits are ordered left-to-right.

G   H   I   J
 \ /     \ /
  D   E   F
   \  |  / \
    \ | /   |
     \|/    |
      B     C
       \   /
        \ /
A =      = A^0
B = A^   = A^1     = A~1
C = A^2  = A^2
D = A^^  = A^1^1   = A~2
E = B^2  = A^^2
F = B^3  = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2  = B^^2    = A^^^2  = A~2^2
I = F^   = B^3^    = A^^3^
J = F^2  = B^3^2   = A^^3^2


History traversing commands such as git log operate on a set of commits, not just a single commit. To these commands, specifying a single revision with the notation described in the previous section means the set of commits reachable from that commit, following the commit ancestry chain.

To exclude commits reachable from a commit, a prefix ^ notation is used. E.g. ^r1 r2 means commits reachable from r2 but exclude the ones reachable from r1.

This set operation appears so often that there is a shorthand for it. When you have two commits r1 and r2 (named according to the syntax explained in SPECIFYING REVISIONS above), you can ask for commits that are reachable from r2 excluding those that are reachable from r1 by ^r1 r2 and it can be written as r1..r2.

A similar notation r1...r2 is called symmetric difference of r1 and r2 and is defined as r1 r2 --not $(git merge-base --all r1 r2). It is the set of commits that are reachable from either one of r1 or r2 but not from both.

In these two shorthands, you can omit one end and let it default to HEAD. For example, origin.. is a shorthand for origin..HEAD and asks "What did I do since I forked from the origin branch?" Similarly, ..origin is a shorthand for HEAD..origin and asks "What did the origin do since I forked from them?" Note that .. would mean HEAD..HEAD which is an empty range that is both reachable and unreachable from HEAD.

Two other shorthands for naming a set that is formed by a commit and its parent commits exist. The r1^@ notation means all parents of r1. r1^! includes commit r1 but excludes all of its parents.

To summarize:

Include commits that are reachable from (i.e. ancestors of) <rev>.
Exclude commits that are reachable from (i.e. ancestors of) <rev>.
Include commits that are reachable from <rev2> but exclude those that are reachable from <rev1>. When either <rev1> or <rev2> is omitted, it defaults to HEAD.
Include commits that are reachable from either <rev1> or <rev2> but exclude those that are reachable from both. When either <rev1> or <rev2> is omitted, it defaults to HEAD.
<rev>^@, e.g. HEAD^@
A suffix ^ followed by an at sign is the same as listing all parents of <rev> (meaning, include anything reachable from its parents, but not the commit itself).
<rev>^!, e.g. HEAD^!
A suffix ^ followed by an exclamation mark is the same as giving commit <rev> and then all its parents prefixed with ^ to exclude them (and their ancestors).

Here are a handful of examples:

D                G H D
D F              G H I J D F
^G D             H D
^D B             E I J F B
B..C             C
B...C            G H D E B C
^D B C           E I J F B C
C                I J F C
C^@              I J F
C^!              C
F^! D            G H D F


Part of the Section G.3.1, “git(1)” suite

G.4.13. gitweb(1)


gitweb - Git web interface (web frontend to Git repositories)


To get started with gitweb, run Section G.3.66, “git-instaweb(1)” from a Git repository. This would configure and start your web server, and run web browser pointing to gitweb.


Gitweb provides a web interface to Git repositories. Its features include:

  • Viewing multiple Git repositories with common root.
  • Browsing every revision of the repository.
  • Viewing the contents of files in the repository at any revision.
  • Viewing the revision log of branches, history of files and directories, see what was changed when, by who.
  • Viewing the blame/annotation details of any file (if enabled).
  • Generating RSS and Atom feeds of commits, for any branch. The feeds are auto-discoverable in modern web browsers.
  • Viewing everything that was changed in a revision, and step through revisions one at a time, viewing the history of the repository.
  • Finding commits which commit messages matches given search term.

See http://git.kernel.org/?p=git/git.git;a=tree;f=gitweb[] or http://repo.or.cz/w/git.git/tree/HEAD:/gitweb/[] for gitweb source code, browsed using gitweb itself.


Various aspects of gitweb's behavior can be controlled through the configuration file gitweb_config.perl or /etc/gitweb.conf. See the Section G.4.14, “gitweb.conf(5)” for details.

1. Repositories

Gitweb can show information from one or more Git repositories. These repositories have to be all on local filesystem, and have to share common repository root, i.e. be all under a single parent repository (but see also "Advanced web server setup" section, "Webserver configuration with multiple projects' root" subsection).

our $projectroot = '/path/to/parent/directory';

The default value for $projectroot is /pub/git. You can change it during building gitweb via GITWEB_PROJECTROOT build configuration variable.

By default all Git repositories under $projectroot are visible and available to gitweb. The list of projects is generated by default by scanning the $projectroot directory for Git repositories (for object databases to be more exact; gitweb is not interested in a working area, and is best suited to showing "bare" repositories).

The name of the repository in gitweb is the path to its $GIT_DIR (its object database) relative to $projectroot. Therefore the repository $repo can be found at "$projectroot/$repo".

2. Projects list file format

Instead of having gitweb find repositories by scanning filesystem starting from $projectroot, you can provide a pre-generated list of visible projects by setting $projects_list to point to a plain text file with a list of projects (with some additional info).

This file uses the following format:

  • One record (for project / repository) per line; does not support line continuation (newline escaping).
  • Leading and trailing whitespace are ignored.
  • Whitespace separated fields; any run of whitespace can be used as field separator (rules for Perl's "split(" ", $line)").
  • Fields use modified URI encoding, defined in RFC 3986, section 2.1 (Percent-Encoding), or rather "Query string encoding" (see http://en.wikipedia.org/wiki/Query_string#URL_encoding[]), the difference being that SP (" ") can be encoded as "+" (and therefore "+" has to be also percent-encoded).

    Reserved characters are: "%" (used for encoding), "+" (can be used to encode SPACE), all whitespace characters as defined in Perl, including SP, TAB and LF, (used to separate fields in a record).

  • Currently recognized fields are:

    <repository path>
    path to repository GIT_DIR, relative to $projectroot
    <repository owner>
    displayed as repository owner, preferably full name, or email, or both

You can generate the projects list index file using the project_index action (the TXT link on projects list page) directly from gitweb; see also "Generating projects list using gitweb" section below.

Example contents:

foo.git       Joe+R+Hacker+<joe@example.com>
foo/bar.git   O+W+Ner+<[email protected]>

By default this file controls only which projects are visible on projects list page (note that entries that do not point to correctly recognized Git repositories won't be displayed by gitweb). Even if a project is not visible on projects list page, you can view it nevertheless by hand-crafting a gitweb URL. By setting $strict_export configuration variable (see Section G.4.14, “gitweb.conf(5)”) to true value you can allow viewing only of repositories also shown on the overview page (i.e. only projects explicitly listed in projects list file will be accessible).

3. Generating projects list using gitweb

We assume that GITWEB_CONFIG has its default Makefile value, namely gitweb_config.perl. Put the following in gitweb_make_index.perl file:

$projects_list = $projectroot;

Then create the following script to get list of project in the format suitable for GITWEB_LIST build configuration variable (or $projects_list variable in gitweb config):


export GITWEB_CONFIG="gitweb_make_index.perl"
export HTTP_ACCEPT="*/*"
export QUERY_STRING="a=project_index"

perl -- /var/www/cgi-bin/gitweb.cgi

Run this script and save its output to a file. This file could then be used as projects list file, which means that you can set $projects_list to its filename.

4. Controlling access to Git repositories

By default all Git repositories under $projectroot are visible and available to gitweb. You can however configure how gitweb controls access to repositories.

  • As described in "Projects list file format" section, you can control which projects are visible by selectively including repositories in projects list file, and setting $projects_list gitweb configuration variable to point to it. With $strict_export set, projects list file can be used to control which repositories are available as well.
  • You can configure gitweb to only list and allow viewing of the explicitly exported repositories, via $export_ok variable in gitweb config file; see Section G.4.14, “gitweb.conf(5)” manpage. If it evaluates to true, gitweb shows repositories only if this file named by $export_ok exists in its object database (if directory has the magic file named $export_ok).

    For example Section G.3.36, “git-daemon(1)” by default (unless --export-all option is used) allows pulling only for those repositories that have git-daemon-export-ok file. Adding

    our $export_ok = "git-daemon-export-ok";

    makes gitweb show and allow access only to those repositories that can be fetched from via git:// protocol.

  • Finally, it is possible to specify an arbitrary perl subroutine that will be called for each repository to determine if it can be exported. The subroutine receives an absolute path to the project (repository) as its only parameter (i.e. "$projectroot/$project").

    For example, if you use mod_perl to run the script, and have dumb HTTP protocol authentication configured for your repositories, you can use the following hook to allow access only if the user is authorized to read the files:

    $export_auth_hook = sub {
            use Apache2::SubRequest ();
            use Apache2::Const -compile => qw(HTTP_OK);
            my $path = "$_[0]/HEAD";
            my $r    = Apache2::RequestUtil->request;
            my $sub  = $r->lookup_file($path);
            return $sub->filename eq $path
                && $sub->status == Apache2::Const::HTTP_OK;

5. Per-repository gitweb configuration

You can configure individual repositories shown in gitweb by creating file in the GIT_DIR of Git repository, or by setting some repo configuration variable (in GIT_DIR/config, see Section G.3.27, “git-config(1)”).

You can use the following files in repository:

A html file (HTML fragment) which is included on the gitweb project "summary" page inside <div> block element. You can use it for longer description of a project, to provide links (for example to project's homepage), etc. This is recognized only if XSS prevention is off ($prevent_xss is false, see Section G.4.14, “gitweb.conf(5)”); a way to include a README safely when XSS prevention is on may be worked out in the future.
description (or gitweb.description)

Short (shortened to $projects_list_description_width in the projects list page, which is 25 characters by default; see Section G.4.14, “gitweb.conf(5)”) single line description of a project (of a repository). Plain text file; HTML will be escaped. By default set to

Unnamed repository; edit this file to name it for gitweb.

from the template during repository creation, usually installed in /usr/share/git-core/templates/. You can use the gitweb.description repo configuration variable, but the file takes precedence.

category (or gitweb.category)

Singe line category of a project, used to group projects if $projects_list_group_categories is enabled. By default (file and configuration variable absent), uncategorized projects are put in the $project_list_default_category category. You can use the gitweb.category repo configuration variable, but the file takes precedence.

The configuration variables $projects_list_group_categories and $project_list_default_category are described in Section G.4.14, “gitweb.conf(5)”

cloneurl (or multiple-valued gitweb.url)

File with repository URL (used for clone and fetch), one per line. Displayed in the project summary page. You can use multiple-valued gitweb.url repository configuration variable for that, but the file takes precedence.

This is per-repository enhancement / version of global prefix-based @git_base_url_list gitweb configuration variable (see Section G.4.14, “gitweb.conf(5)”).


You can use the gitweb.owner repository configuration variable to set repository's owner. It is displayed in the project list and summary page.

If it's not set, filesystem directory's owner is used (via GECOS field, i.e. real name field from getpwuid(3)) if $projects_list is unset (gitweb scans $projectroot for repositories); if $projects_list points to file with list of repositories, then project owner defaults to value from this file for given repository.

various gitweb.* config variables (in config)
Read description of %feature hash for detailed list, and descriptions. See also "Configuring gitweb features" section in Section G.4.14, “gitweb.conf(5)”


Gitweb can use path_info (component) based URLs, or it can pass all necessary information via query parameters. The typical gitweb URLs are broken down in to five components:


The repository the action will be performed on.

All actions except for those that list all available projects, in whatever form, require this parameter.

The action that will be run. Defaults to projects_list if repo is not set, and to summary otherwise.
Revision shown. Defaults to HEAD.
The path within the <repository> that the action is performed on, for those actions that require it.
Any arguments that control the behaviour of the action.

Some actions require or allow to specify two revisions, and sometimes even two pathnames. In most general form such path_info (component) based gitweb URL looks like this:


Each action is implemented as a subroutine, and must be present in %actions hash. Some actions are disabled by default, and must be turned on via feature mechanism. For example to enable blame view add the following to gitweb configuration file:

$feature{'blame'}{'default'} = [1];

1. Actions:

The standard actions are:

Lists the available Git repositories. This is the default command if no repository is specified in the URL.
Displays summary about given repository. This is the default command if no action is specified in URL, and only repository is specified.
heads , remotes

Lists all local or all remote-tracking branches in given repository.

The latter is not available by default, unless configured.

List all tags (lightweight and annotated) in given repository.
blob , tree
Shows the files and directories in a given repository path, at given revision. This is default command if no action is specified in the URL, and path is given.
Returns the raw data for the file in given repository, at given path and revision. Links to this action are marked raw.
Shows the difference between two revisions of the same file.
blame , blame_incremental

Shows the blame (also called annotation) information for a file. On a per line basis it shows the revision in which that line was last changed and the user that committed the change. The incremental version (which if configured is used automatically when JavaScript is enabled) uses Ajax to incrementally add blame info to the contents of given file.

This action is disabled by default for performance reasons.

commit , commitdiff
Shows information about a specific commit in a repository. The commit view shows information about commit in more detail, the commitdiff action shows changeset for given commit.
Returns the commit in plain text mail format, suitable for applying with Section G.3.3, “git-am(1)”.
Display specific annotated tag (tag object).
log , shortlog

Shows log information (commit message or just commit subject) for a given branch (starting from given revision).

The shortlog view is more compact; it shows one commit per line.


Shows history of the file or directory in a given repository path, starting from given revision (defaults to HEAD, i.e. default branch).

This view is similar to shortlog view.

rss , atom
Generates an RSS (or Atom) feed of changes to repository.


This section explains how to configure some common webservers to run gitweb. In all cases, /path/to/gitweb in the examples is the directory you ran installed gitweb in, and contains gitweb_config.perl.

If you've configured a web server that isn't listed here for gitweb, please send in the instructions so they can be included in a future release.

1. Apache as CGI

Apache must be configured to support CGI scripts in the directory in which gitweb is installed. Let's assume that it is /var/www/cgi-bin directory.

ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

<Directory "/var/www/cgi-bin">
    Options Indexes FollowSymlinks ExecCGI
    AllowOverride None
    Order allow,deny
    Allow from all

With that configuration the full path to browse repositories would be:


2. Apache with mod_perl, via ModPerl::Registry

You can use mod_perl with gitweb. You must install Apache::Registry (for mod_perl 1.x) or ModPerl::Registry (for mod_perl 2.x) to enable this support.

Assuming that gitweb is installed to /var/www/perl, the following Apache configuration (for mod_perl 2.x) is suitable.

Alias /perl "/var/www/perl"

<Directory "/var/www/perl">
    SetHandler perl-script
    PerlResponseHandler ModPerl::Registry
    PerlOptions +ParseHeaders
    Options Indexes FollowSymlinks +ExecCGI
    AllowOverride None
    Order allow,deny
    Allow from all

With that configuration the full path to browse repositories would be:


3. Apache with FastCGI

Gitweb works with Apache and FastCGI. First you need to rename, copy or symlink gitweb.cgi to gitweb.fcgi. Let's assume that gitweb is installed in /usr/share/gitweb directory. The following Apache configuration is suitable (UNTESTED!)

FastCgiServer /usr/share/gitweb/gitweb.cgi
ScriptAlias /gitweb /usr/share/gitweb/gitweb.cgi

Alias /gitweb/static /usr/share/gitweb/static
<Directory /usr/share/gitweb/static>
    SetHandler default-handler

With that configuration the full path to browse repositories would be:



All of those examples use request rewriting, and need mod_rewrite (or equivalent; examples below are written for Apache).

1. Single URL for gitweb and for fetching

If you want to have one URL for both gitweb and your http:// repositories, you can configure Apache like this:

<VirtualHost *:80>
    ServerName    git.example.org
    DocumentRoot  /pub/git
    SetEnv        GITWEB_CONFIG   /etc/gitweb.conf

    # turning on mod rewrite
    RewriteEngine on

    # make the front page an internal rewrite to the gitweb script
    RewriteRule ^/$  /cgi-bin/gitweb.cgi

    # make access for "dumb clients" work
    RewriteRule ^/(.*\.git/(?!/?(HEAD|info|objects|refs)).*)?$ \
                /cgi-bin/gitweb.cgi%{REQUEST_URI}  [L,PT]

The above configuration expects your public repositories to live under /pub/git and will serve them as http://git.domain.org/dir-under-pub-git, both as clonable Git URL and as browseable gitweb interface. If you then start your Section G.3.36, “git-daemon(1)” with --base-path=/pub/git --export-all then you can even use the git:// URL with exactly the same path.

Setting the environment variable GITWEB_CONFIG will tell gitweb to use the named file (i.e. in this example /etc/gitweb.conf) as a configuration for gitweb. You don't really need it in above example; it is required only if your configuration file is in different place than built-in (during compiling gitweb) gitweb_config.perl or /etc/gitweb.conf. See Section G.4.14, “gitweb.conf(5)” for details, especially information about precedence rules.

If you use the rewrite rules from the example you might also need something like the following in your gitweb configuration file (/etc/gitweb.conf following example):

@stylesheets = ("/some/absolute/path/gitweb.css");
$my_uri    = "/";
$home_link = "/";
$per_request_config = 1;

Nowadays though gitweb should create HTML base tag when needed (to set base URI for relative links), so it should work automatically.

2. Webserver configuration with multiple projects' root

If you want to use gitweb with several project roots you can edit your Apache virtual host and gitweb configuration files in the following way.

The virtual host configuration (in Apache configuration file) should look like this:

<VirtualHost *:80>
    ServerName    git.example.org
    DocumentRoot  /pub/git
    SetEnv        GITWEB_CONFIG  /etc/gitweb.conf

    # turning on mod rewrite
    RewriteEngine on

    # make the front page an internal rewrite to the gitweb script
    RewriteRule ^/$  /cgi-bin/gitweb.cgi  [QSA,L,PT]

    # look for a public_git folder in unix users' home
    # http://git.example.org/~<user>/
    RewriteRule ^/\~([^\/]+)(/|/gitweb.cgi)?$   /cgi-bin/gitweb.cgi \

    # http://git.example.org/+<user>/
    #RewriteRule ^/\+([^\/]+)(/|/gitweb.cgi)?$  /cgi-bin/gitweb.cgi \

    # http://git.example.org/user/<user>/
    #RewriteRule ^/user/([^\/]+)/(gitweb.cgi)?$ /cgi-bin/gitweb.cgi \

    # defined list of project roots
    RewriteRule ^/scm(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi \
    RewriteRule ^/var(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi \

    # make access for "dumb clients" work
    RewriteRule ^/(.*\.git/(?!/?(HEAD|info|objects|refs)).*)?$ \
                /cgi-bin/gitweb.cgi%{REQUEST_URI}  [L,PT]

Here actual project root is passed to gitweb via GITWEB_PROJECT_ROOT environment variable from a web server, so you need to put the following line in gitweb configuration file (/etc/gitweb.conf in above example):

$projectroot = $ENV{'GITWEB_PROJECTROOT'} || "/pub/git";

Note that this requires to be set for each request, so either $per_request_config must be false, or the above must be put in code referenced by $per_request_config;

These configurations enable two things. First, each unix user (<user>) of the server will be able to browse through gitweb Git repositories found in ~/public_git/ with the following url:


If you do not want this feature on your server just remove the second rewrite rule.

If you already use mod_userdir` in your virtual host or you don't want to use the '~ as first character, just comment or remove the second rewrite rule, and uncomment one of the following according to what you want.

Second, repositories found in /pub/scm/ and /var/git/ will be accessible through http://git.example.org/scm/ and http://git.example.org/var/. You can add as many project roots as you want by adding rewrite rules like the third and the fourth.

3. PATH_INFO usage

If you enable PATH_INFO usage in gitweb by putting

$feature{'pathinfo'}{'default'} = [1];

in your gitweb configuration file, it is possible to set up your server so that it consumes and produces URLs in the form


i.e. without gitweb.cgi part, by using a configuration such as the following. This configuration assumes that /var/www/gitweb is the DocumentRoot of your webserver, contains the gitweb.cgi script and complementary static files (stylesheet, favicon, JavaScript):

<VirtualHost *:80>
        ServerAlias git.example.com

        DocumentRoot /var/www/gitweb

        <Directory /var/www/gitweb>
                Options ExecCGI
                AddHandler cgi-script cgi

                DirectoryIndex gitweb.cgi

                RewriteEngine On
                RewriteCond %{REQUEST_FILENAME} !-f
                RewriteCond %{REQUEST_FILENAME} !-d
                RewriteRule ^.* /gitweb.cgi/$0 [L,PT]

The rewrite rule guarantees that existing static files will be properly served, whereas any other URL will be passed to gitweb as PATH_INFO parameter.

Notice that in this case you don't need special settings for @stylesheets, $my_uri and $home_link, but you lose "dumb client" access to your project .git dirs (described in "Single URL for gitweb and for fetching" section). A possible workaround for the latter is the following: in your project root dir (e.g. /pub/git) have the projects named without a .git extension (e.g. /pub/git/project instead of /pub/git/project.git) and configure Apache as follows:

<VirtualHost *:80>
        ServerAlias git.example.com

        DocumentRoot /var/www/gitweb

        AliasMatch ^(/.*?)(\.git)(/.*)?$ /pub/git$1$3
        <Directory /var/www/gitweb>
                Options ExecCGI
                AddHandler cgi-script cgi

                DirectoryIndex gitweb.cgi

                RewriteEngine On
                RewriteCond %{REQUEST_FILENAME} !-f
                RewriteCond %{REQUEST_FILENAME} !-d
                RewriteRule ^.* /gitweb.cgi/$0 [L,PT]

The additional AliasMatch makes it so that


will give raw access to the project's Git dir (so that the project can be cloned), while


will provide human-friendly gitweb access.

This solution is not 100% bulletproof, in the sense that if some project has a named ref (branch, tag) starting with git/, then paths such as


will fail with a 404 error.


Please report any bugs or feature requests to [email protected], putting "gitweb" in the subject of email.


Part of the Section G.3.1, “git(1)” suite

G.4.14. gitweb.conf(5)


gitweb.conf - Gitweb (Git web interface) configuration file


/etc/gitweb.conf, /etc/gitweb-common.conf, $GITWEBDIR/gitweb_config.perl


The gitweb CGI script for viewing Git repositories over the web uses a perl script fragment as its configuration file. You can set variables using "our $variable = value"; text from a "#" character until the end of a line is ignored. See perlsyn(1) for details.

An example:

# gitweb configuration file for http://git.example.org
our $projectroot = "/srv/git"; # FHS recommendation
our $site_name = 'Example.org >> Repos';

The configuration file is used to override the default settings that were built into gitweb at the time the gitweb.cgi script was generated.

While one could just alter the configuration settings in the gitweb CGI itself, those changes would be lost upon upgrade. Configuration settings might also be placed into a file in the same directory as the CGI script with the default name gitweb_config.perl -- allowing one to have multiple gitweb instances with different configurations by the use of symlinks.

Note that some configuration can be controlled on per-repository rather than gitweb-wide basis: see "Per-repository gitweb configuration" subsection on Section G.4.13, “gitweb(1)” manpage.


Gitweb reads configuration data from the following sources in the following order:

  • built-in values (some set during build stage),
  • common system-wide configuration file (defaults to /etc/gitweb-common.conf),
  • either per-instance configuration file (defaults to gitweb_config.perl in the same directory as the installed gitweb), or if it does not exists then fallback system-wide configuration file (defaults to /etc/gitweb.conf).

Values obtained in later configuration files override values obtained earlier in the above sequence.

Locations of the common system-wide configuration file, the fallback system-wide configuration file and the per-instance configuration file are defined at compile time using build-time Makefile configuration variables, respectively GITWEB_CONFIG_COMMON, GITWEB_CONFIG_SYSTEM and GITWEB_CONFIG.

You can also override locations of gitweb configuration files during runtime by setting the following environment variables: GITWEB_CONFIG_COMMON, GITWEB_CONFIG_SYSTEM and GITWEB_CONFIG to a non-empty value.

The syntax of the configuration files is that of Perl, since these files are handled by sourcing them as fragments of Perl code (the language that gitweb itself is written in). Variables are typically set using the our qualifier (as in "our $variable = <value>;") to avoid syntax errors if a new version of gitweb no longer uses a variable and therefore stops declaring it.

You can include other configuration file using read_config_file() subroutine. For example, one might want to put gitweb configuration related to access control for viewing repositories via Gitolite (one of Git repository management tools) in a separate file, e.g. in /etc/gitweb-gitolite.conf. To include it, put


somewhere in gitweb configuration file used, e.g. in per-installation gitweb configuration file. Note that read_config_file() checks itself that the file it reads exists, and does nothing if it is not found. It also handles errors in included file.

The default configuration with no configuration file at all may work perfectly well for some installations. Still, a configuration file is useful for customizing or tweaking the behavior of gitweb in many ways, and some optional features will not be present unless explicitly enabled using the configurable %features variable (see also "Configuring gitweb features" section below).


Some configuration variables have their default values (embedded in the CGI script) set during building gitweb -- if that is the case, this fact is put in their description. See gitweb's INSTALL file for instructions on building and installing gitweb.

1. Location of repositories

The configuration variables described below control how gitweb finds Git repositories, and how repositories are displayed and accessed.

See also "Repositories" and later subsections in Section G.4.13, “gitweb(1)” manpage.


Absolute filesystem path which will be prepended to project path; the path to repository is $projectroot/$project. Set to $GITWEB_PROJECTROOT during installation. This variable has to be set correctly for gitweb to find repositories.

For example, if $projectroot is set to "/srv/git" by putting the following in gitweb config file:

our $projectroot = "/srv/git";



and its path_info based equivalent


will map to the path /srv/git/foo/bar.git on the filesystem.


Name of a plain text file listing projects, or a name of directory to be scanned for projects.

Project list files should list one project per line, with each line having the following format

<URI-encoded filesystem path to repository> SP <URI-encoded repository owner>

The default value of this variable is determined by the GITWEB_LIST makefile variable at installation time. If this variable is empty, gitweb will fall back to scanning the $projectroot directory for repositories.


If $projects_list variable is unset, gitweb will recursively scan filesystem for Git repositories. The $project_maxdepth is used to limit traversing depth, relative to $projectroot (starting point); it means that directories which are further from $projectroot than $project_maxdepth will be skipped.

It is purely performance optimization, originally intended for MacOS X, where recursive directory traversal is slow. Gitweb follows symbolic links, but it detects cycles, ignoring any duplicate files and directories.

The default value of this variable is determined by the build-time configuration variable GITWEB_PROJECT_MAXDEPTH, which defaults to 2007.

Show repository only if this file exists (in repository). Only effective if this variable evaluates to true. Can be set when building gitweb by setting GITWEB_EXPORT_OK. This path is relative to GIT_DIR. git-daemon[1] uses git-daemon-export-ok, unless started with --export-all. By default this variable is not set, which means that this feature is turned off.

Function used to determine which repositories should be shown. This subroutine should take one parameter, the full path to a project, and if it returns true, that project will be included in the projects list and can be accessed through gitweb as long as it fulfills the other requirements described by $export_ok, $projects_list, and $projects_maxdepth. Example:

our $export_auth_hook = sub { return -e "$_[0]/git-daemon-export-ok"; };

though the above might be done by using $export_ok instead

our $export_ok = "git-daemon-export-ok";

If not set (default), it means that this feature is disabled.

See also more involved example in "Controlling access to Git repositories" subsection on Section G.4.13, “gitweb(1)” manpage.

Only allow viewing of repositories also shown on the overview page. This for example makes $gitweb_export_ok file decide if repository is available and not only if it is shown. If $gitweb_list points to file with list of project, only those repositories listed would be available for gitweb. Can be set during building gitweb via GITWEB_STRICT_EXPORT. By default this variable is not set, which means that you can directly access those repositories that are hidden from projects list page (e.g. the are not listed in the $projects_list file).

2. Finding files

The following configuration variables tell gitweb where to find files. The values of these variables are paths on the filesystem.

Core git executable to use. By default set to $GIT_BINDIR/git, which in turn is by default set to $(bindir)/git. If you use Git installed from a binary package, you should usually set this to "/usr/bin/git". This can just be "git" if your web server has a sensible PATH; from security point of view it is better to use absolute path to git binary. If you have multiple Git versions installed it can be used to choose which one to use. Must be (correctly) set for gitweb to be able to work.
File to use for (filename extension based) guessing of MIME types before trying /etc/mime.types. NOTE that this path, if relative, is taken as relative to the current Git repository, not to CGI script. If unset, only /etc/mime.types is used (if present on filesystem). If no mimetypes file is found, mimetype guessing based on extension of file is disabled. Unset by default.

Path to the highlight executable to use (it must be the one from http://www.andre-simon.de[] due to assumptions about parameters and output). By default set to highlight; set it to full path to highlight executable if it is not installed on your web server's PATH. Note that highlight feature must be set for gitweb to actually use syntax highlighting.

NOTE: if you want to add support for new file type (supported by "highlight" but not used by gitweb), you need to modify %highlight_ext or %highlight_basename, depending on whether you detect type of file based on extension (for example "sh") or on its basename (for example "Makefile"). The keys of these hashes are extension and basename, respectively, and value for given key is name of syntax to be passed via --syntax <syntax> to highlighter.

For example if repositories you are hosting use "phtml" extension for PHP files, and you want to have correct syntax-highlighting for those files, you can add the following to gitweb configuration:

our %highlight_ext;
$highlight_ext{'phtml'} = 'php';

3. Links and their targets

The configuration variables described below configure some of gitweb links: their target and their look (text or image), and where to find page prerequisites (stylesheet, favicon, images, scripts). Usually they are left at their default values, with the possible exception of @stylesheets variable.


List of URIs of stylesheets (relative to the base URI of a page). You might specify more than one stylesheet, for example to use "gitweb.css" as base with site specific modifications in a separate stylesheet to make it easier to upgrade gitweb. For example, you can add a site stylesheet by putting

push @stylesheets, "gitweb-site.css";

in the gitweb config file. Those values that are relative paths are relative to base URI of gitweb.

This list should contain the URI of gitweb's standard stylesheet. The default URI of gitweb stylesheet can be set at build time using the GITWEB_CSS makefile variable. Its default value is static/gitweb.css (or static/gitweb.min.css if the CSSMIN variable is defined, i.e. if CSS minifier is used during build).

Note: there is also a legacy $stylesheet configuration variable, which was used by older gitweb. If $stylesheet variable is defined, only CSS stylesheet given by this variable is used by gitweb.

Points to the location where you put git-logo.png on your web server, or to be more the generic URI of logo, 72x27 size). This image is displayed in the top right corner of each gitweb page and used as a logo for the Atom feed. Relative to the base URI of gitweb (as a path). Can be adjusted when building gitweb using GITWEB_LOGO variable By default set to static/git-logo.png.
Points to the location where you put git-favicon.png on your web server, or to be more the generic URI of favicon, which will be served as "image/png" type. Web browsers that support favicons (website icons) may display them in the browser's URL bar and next to the site name in bookmarks. Relative to the base URI of gitweb. Can be adjusted at build time using GITWEB_FAVICON variable. By default set to static/git-favicon.png.

Points to the location where you put gitweb.js on your web server, or to be more generic the URI of JavaScript code used by gitweb. Relative to the base URI of gitweb. Can be set at build time using the GITWEB_JS build-time configuration variable.

The default value is either static/gitweb.js, or static/gitweb.min.js if the JSMIN build variable was defined, i.e. if JavaScript minifier was used at build time. Note that this single file is generated from multiple individual JavaScript "modules".

Target of the home link on the top of all pages (the first part of view "breadcrumbs"). By default it is set to the absolute URI of a current page (to the value of $my_uri variable, or to "/" if $my_uri is undefined or is an empty string).
Label for the "home link" at the top of all pages, leading to $home_link (usually the main gitweb page, which contains the projects list). It is used as the first component of gitweb's "breadcrumb trail": <home link> / <project> / <action>. Can be set at build time using the GITWEB_HOME_LINK_STR variable. By default it is set to "projects", as this link leads to the list of projects. Another popular choice is to set it to the name of site. Note that it is treated as raw HTML so it should not be set from untrusted sources.

Additional links to be added to the start of the breadcrumb trail before the home link, to pages that are logically "above" the gitweb projects list, such as the organization and department which host the gitweb server. Each element of the list is a reference to an array, in which element 0 is the link text (equivalent to $home_link_str) and element 1 is the target URL (equivalent to $home_link).

For example, the following setting produces a breadcrumb trail like "home / dev / projects / …" where "projects" is the home link.

    our @extra_breadcrumbs = (
      [ 'home' => 'https://www.example.org/' ],
      [ 'dev'  => 'https://dev.example.org/' ],
$logo_url , $logo_label
URI and label (title) for the Git logo link (or your site logo, if you chose to use different logo image). By default, these both refer to Git homepage, http://git-scm.com[]; in the past, they pointed to Git documentation at http://www.kernel.org[].

4. Changing gitweb's look

You can adjust how pages generated by gitweb look using the variables described below. You can change the site name, add common headers and footers for all pages, and add a description of this gitweb installation on its main page (which is the projects list page), etc.


Name of your site or organization, to appear in page titles. Set it to something descriptive for clearer bookmarks etc. If this variable is not set or is, then gitweb uses the value of the SERVER_NAME CGI environment variable, setting site name to "$SERVER_NAME Git", or "Untitled Git" if this variable is not set (e.g. if running gitweb as standalone script).

Can be set using the GITWEB_SITENAME at build time. Unset by default.

HTML snippet to be included in the <head> section of each page. Can be set using GITWEB_SITE_HTML_HEAD_STRING at build time. No default value.
Name of a file with HTML to be included at the top of each page. Relative to the directory containing the gitweb.cgi script. Can be set using GITWEB_SITE_HEADER at build time. No default value.
Name of a file with HTML to be included at the bottom of each page. Relative to the directory containing the gitweb.cgi script. Can be set using GITWEB_SITE_FOOTER at build time. No default value.
Name of a HTML file which, if it exists, is included on the gitweb projects overview page ("projects_list" view). Relative to the directory containing the gitweb.cgi script. Default value can be adjusted during build time using GITWEB_HOMETEXT variable. By default set to indextext.html.
The width (in characters) of the "Description" column of the projects list. Longer descriptions will be truncated (trying to cut at word boundary); the full description is available in the title attribute (usually shown on mouseover). The default is 25, which might be too small if you use long project descriptions.

Default value of ordering of projects on projects list page, which means the ordering used if you don't explicitly sort projects list (if there is no "o" CGI query parameter in the URL). Valid values are "none" (unsorted), "project" (projects are by project name, i.e. path to repository relative to $projectroot), "descr" (project description), "owner", and "age" (by date of most current commit).

Default value is "project". Unknown value means unsorted.

5. Changing gitweb's behavior

These configuration variables control internal gitweb behavior.

Default mimetype for the blob_plain (raw) view, if mimetype checking doesn't result in some other type; by default "text/plain". Gitweb guesses mimetype of a file to display based on extension of its filename, using $mimetypes_file (if set and file exists) and /etc/mime.types files (see mime.types(5) manpage; only filename extension rules are supported by gitweb).
Default charset for text files. If this is not set, the web server configuration will be used. Unset by default.
Gitweb assumes this charset when a line contains non-UTF-8 characters. The fallback decoding is used without error checking, so it can be even "utf-8". The value must be a valid encoding; see the Encoding::Supported(3pm) man page for a list. The default is "latin1", aka. "iso-8859-1".

Rename detection options for git-diff and git-diff-tree. The default is ('-M'); set it to ('-C') or ('-C', '-C') to also detect copies, or set it to () i.e. empty list if you don't want to have renames detection.

Note that rename and especially copy detection can be quite CPU-intensive. Note also that non Git tools can have problems with patches generated with options mentioned above, especially when they involve file copies ('-C') or criss-cross renames ('-B').

6. Some optional features and policies

Most of features are configured via %feature hash; however some of extra gitweb features can be turned on and configured using variables described below. This list beside configuration variables that control how gitweb looks does contain variables configuring administrative side of gitweb (e.g. cross-site scripting prevention; admittedly this as side effect affects how "summary" pages look like, or load limiting).


List of Git base URLs. These URLs are used to generate URLs describing from where to fetch a project, which are shown on project summary page. The full fetch URL is "$git_base_url/$project", for each element of this list. You can set up multiple base URLs (for example one for git:// protocol, and one for http:// protocol).

Note that per repository configuration can be set in $GIT_DIR/cloneurl file, or as values of multi-value gitweb.url configuration variable in project config. Per-repository configuration takes precedence over value composed from @git_base_url_list elements and project name.

You can setup one single value (single entry/item in this list) at build time by setting the GITWEB_BASE_URL build-time configuration variable. By default it is set to (), i.e. an empty list. This means that gitweb would not try to create project URL (to fetch) from project name.

Whether to enable the grouping of projects by category on the project list page. The category of a project is determined by the $GIT_DIR/category file or the gitweb.category variable in each repository's configuration. Disabled by default (set to 0).
Default category for projects for which none is specified. If this is set to the empty string, such projects will remain uncategorized and listed at the top, above categorized projects. Used only if project categories are enabled, which means if $projects_list_group_categories is true. By default set to "" (empty string).
If true, some gitweb features are disabled to prevent content in repositories from launching cross-site scripting (XSS) attacks. Set this to true if you don't trust the content of your repositories. False by default (set to 0).

Used to set the maximum load that we will still respond to gitweb queries. If the server load exceeds this value then gitweb will return "503 Service Unavailable" error. The server load is taken to be 0 if gitweb cannot determine its value. Currently it works only on Linux, where it uses /proc/loadavg; the load there is the number of active tasks on the system -- processes that are actually running -- averaged over the last minute.

Set $maxload to undefined value (undef) to turn this feature off. The default value is 300.

If true, omit the column with date of the most current commit on the projects list page. It can save a bit of I/O and a fork per repository.
If true prevents displaying information about repository owner.

If this is set to code reference, it will be run once for each request. You can set parts of configuration that change per session this way. For example, one might use the following code in a gitweb configuration file

our $per_request_config = sub {
        $ENV{GL_USER} = $cgi->remote_user || "gitweb";

If $per_request_config is not a code reference, it is interpreted as boolean value. If it is true gitweb will process config files once per request, and if it is false gitweb will process config files only once, each time it is executed. True by default (set to 1).

NOTE: $my_url, $my_uri, and $base_url are overwritten with their default values before every request, so if you want to change them, be sure to set this variable to true or a code reference effecting the desired changes.

This variable matters only when using persistent web environments that serve multiple requests using single gitweb instance, like mod_perl, FastCGI or Plackup.

7. Other variables

Usually you should not need to change (adjust) any of configuration variables described below; they should be automatically set by gitweb to correct value.


Gitweb version, set automatically when creating gitweb.cgi from gitweb.perl. You might want to modify it if you are running modified gitweb, for example

our $version .= " with caching";

if you run modified version of gitweb with caching support. This variable is purely informational, used e.g. in the "generator" meta header in HTML header.

$my_url , $my_uri
Full URL and absolute URL of the gitweb script; in earlier versions of gitweb you might have need to set those variables, but now there should be no need to do it. See $per_request_config if you need to set them still.
Base URL for relative URLs in pages generated by gitweb, (e.g. $logo, $favicon, @stylesheets if they are relative URLs), needed and used <base href="$base_url"> only for URLs with nonempty PATH_INFO. Usually gitweb sets its value correctly, and there is no need to set this variable, e.g. to $my_uri or "/". See $per_request_config if you need to override it anyway.


Many gitweb features can be enabled (or disabled) and configured using the %feature hash. Names of gitweb features are keys of this hash.

Each %feature hash element is a hash reference and has the following structure:

"<feature_name>" => {
        "sub" => <feature-sub (subroutine)>,
        "override" => <allow-override (boolean)>,
        "default" => [ <options>... ]

Some features cannot be overridden per project. For those features the structure of appropriate %feature hash element has a simpler form:

"<feature_name>" => {
        "override" => 0,
        "default" => [ <options>... ]

As one can see it lacks the 'sub' element.

The meaning of each part of feature configuration is described below:


List (array reference) of feature parameters (if there are any), used also to toggle (enable or disable) given feature.

Note that it is currently always an array reference, even if feature doesn't accept any configuration parameters, and 'default' is used only to turn it on or off. In such case you turn feature on by setting this element to [1], and torn it off by setting it to [0]. See also the passage about the "blame" feature in the "Examples" section.

To disable features that accept parameters (are configurable), you need to set this element to empty list i.e. [].


If this field has a true value then the given feature is overridable, which means that it can be configured (or enabled/disabled) on a per-repository basis.

Usually given "<feature>" is configurable via the gitweb.<feature> config variable in the per-repository Git configuration file.

Note that no feature is overridable by default.


Internal detail of implementation. What is important is that if this field is not present then per-repository override for given feature is not supported.

You wouldn't need to ever change it in gitweb config file.

1. Features in %feature

The gitweb features that are configurable via %feature hash are listed below. This should be a complete list, but ultimately the authoritative and complete list is in gitweb.cgi source code, with features described in the comments.


Enable the "blame" and "blame_incremental" blob views, showing for each line the last commit that modified it; see Section G.3.9, “git-blame(1)”. This can be very CPU-intensive and is therefore disabled by default.

This feature can be configured on a per-repository basis via repository's gitweb.blame configuration variable (boolean).


Enable and configure the "snapshot" action, which allows user to download a compressed archive of any tree or commit, as produced by Section G.3.7, “git-archive(1)” and possibly additionally compressed. This can potentially generate high traffic if you have large project.

The value of 'default' is a list of names of snapshot formats, defined in %known_snapshot_formats hash, that you wish to offer. Supported formats include "tgz", "tbz2", "txz" (gzip/bzip2/xz compressed tar archive) and "zip"; please consult gitweb sources for a definitive list. By default only "tgz" is offered.

This feature can be configured on a per-repository basis via repository's gitweb.blame configuration variable, which contains a comma separated list of formats or "none" to disable snapshots. Unknown values are ignored.


Enable grep search, which lists the files in currently selected tree (directory) containing the given string; see Section G.3.55, “git-grep(1)”. This can be potentially CPU-intensive, of course. Enabled by default.

This feature can be configured on a per-repository basis via repository's gitweb.grep configuration variable (boolean).


Enable the so called pickaxe search, which will list the commits that introduced or removed a given string in a file. This can be practical and quite faster alternative to "blame" action, but it is still potentially CPU-intensive. Enabled by default.

The pickaxe search is described in Section G.3.68, “git-log(1)” (the description of -S<string> option, which refers to pickaxe entry in Section G.4.4, “gitdiffcore(7)” for more details).

This feature can be configured on a per-repository basis by setting repository's gitweb.pickaxe configuration variable (boolean).


Enable showing size of blobs (ordinary files) in a "tree" view, in a separate column, similar to what ls -l does; see description of -l option in Section G.3.71, “git-ls-tree(1)” manpage. This costs a bit of I/O. Enabled by default.

This feature can be configured on a per-repository basis via repository's gitweb.showSizes configuration variable (boolean).


Enable and configure "patches" view, which displays list of commits in email (plain text) output format; see also Section G.3.50, “git-format-patch(1)”. The value is the maximum number of patches in a patchset generated in "patches" view. Set the default field to a list containing single item of or to an empty list to disable patch view, or to a list containing a single negative number to remove any limit. Default value is 16.

This feature can be configured on a per-repository basis via repository's gitweb.patches configuration variable (integer).


Avatar support. When this feature is enabled, views such as "shortlog" or "commit" will display an avatar associated with the email of each committer and author.

Currently available providers are "gravatar" and "picon". Only one provider at a time can be selected (default is one element list). If an unknown provider is specified, the feature is disabled. Note that some providers might require extra Perl packages to be installed; see gitweb/INSTALL for more details.

This feature can be configured on a per-repository basis via repository's gitweb.avatar configuration variable.

See also %avatar_size with pixel sizes for icons and avatars ("default" is used for one-line like "log" and "shortlog", "double" is used for two-line like "commit", "commitdiff" or "tag"). If the default font sizes or lineheights are changed (e.g. via adding extra CSS stylesheet in @stylesheets), it may be appropriate to change these values.


Server-side syntax highlight support in "blob" view. It requires $highlight_bin program to be available (see the description of this variable in the "Configuration variables" section above), and therefore is disabled by default.

This feature can be configured on a per-repository basis via repository's gitweb.highlight configuration variable (boolean).


Enable displaying remote heads (remote-tracking branches) in the "heads" list. In most cases the list of remote-tracking branches is an unnecessary internal private detail, and this feature is therefore disabled by default. Section G.3.66, “git-instaweb(1)”, which is usually used to browse local repositories, enables and uses this feature.

This feature can be configured on a per-repository basis via repository's gitweb.remote_heads configuration variable (boolean).

The remaining features cannot be overridden on a per project basis.


Enable text search, which will list the commits which match author, committer or commit text to a given string; see the description of --author, --committer and --grep options in Section G.3.68, “git-log(1)” manpage. Enabled by default.

Project specific override is not supported.


If this feature is enabled, gitweb considers projects in subdirectories of project root (basename) to be forks of existing projects. For each project $projname.git, projects in the $projname/ directory and its subdirectories will not be shown in the main projects list. Instead, a '+' mark is shown next to $projname, which links to a "forks" view that lists all the forks (all projects in $projname/ subdirectory). Additionally a "forks" view for a project is linked from project summary page.

If the project list is taken from a file ($projects_list points to a file), forks are only recognized if they are listed after the main project in that file.

Project specific override is not supported.


Insert custom links to the action bar of all project pages. This allows you to link to third-party scripts integrating into gitweb.

The "default" value consists of a list of triplets in the form ("<label>", "<link>", "<position>")` where "position" is the label after which to insert the link, "link" is a format string where %n expands to the project name, %f to the project path within the filesystem (i.e. "$projectroot/$project"), %h to the current hash ('h gitweb parameter) and %b` to the current hash base ('hb gitweb parameter); %%` expands to '%.

For example, at the time this page was written, the http://repo.or.cz[] Git hosting site set it to the following to enable graphical log (using the third party tool git-browser):

$feature{'actions'}{'default'} =
        [ ('graphiclog', '/git-browser/by-commit.html?r=%n', 'summary')];

This adds a link titled "graphiclog" after the "summary" link, leading to git-browser script, passing r=<project> as a query parameter.

Project specific override is not supported.


Enable displaying how much time and how many Git commands it took to generate and display each page in the page footer (at the bottom of page). For example the footer might contain: "This page took 6.53325 seconds and 13 Git commands to generate." Disabled by default.

Project specific override is not supported.


Enable and configure the ability to change a common time zone for dates in gitweb output via JavaScript. Dates in gitweb output include authordate and committerdate in "commit", "commitdiff" and "log" views, and taggerdate in "tag" view. Enabled by default.

The value is a list of three values: a default time zone (for if the client hasn't selected some other time zone and saved it in a cookie), a name of cookie where to store selected time zone, and a CSS class used to mark up dates for manipulation. If you want to turn this feature off, set "default" to empty list: [].

Typical gitweb config files will only change starting (default) time zone, and leave other elements at their default values:

$feature{'javascript-timezone'}{'default'}[0] = "utc";

The example configuration presented here is guaranteed to be backwards and forward compatible.

Time zone values can be "local" (for local time zone that browser uses), "utc" (what gitweb uses when JavaScript or this feature is disabled), or numerical time zones in the form of "+/-HHMM", such as "+0200".

Project specific override is not supported.


List of additional directories under "refs" which are going to be used as branch refs. For example if you have a gerrit setup where all branches under refs/heads/ are official, push-after-review ones and branches under refs/sandbox/, refs/wip and refs/other are user ones where permissions are much wider, then you might want to set this variable as follows:

$feature{'extra-branch-refs'}{'default'} =
        ['sandbox', 'wip', 'other'];

This feature can be configured on per-repository basis after setting $feature{extra-branch-refs}{override} to true, via repository's gitweb.extraBranchRefs configuration variable, which contains a space separated list of refs. An example:

        extraBranchRefs = sandbox wip other

The gitweb.extraBranchRefs is actually a multi-valued configuration variable, so following example is also correct and the result is the same as of the snippet above:

        extraBranchRefs = sandbox
        extraBranchRefs = wip other

It is an error to specify a ref that does not pass "git check-ref-format" scrutiny. Duplicated values are filtered.


To enable blame, pickaxe search, and snapshot support (allowing "tar.gz" and "zip" snapshots), while allowing individual projects to turn them off, put the following in your GITWEB_CONFIG file:

$feature{'blame'}{'default'} = [1];
$feature{'blame'}{'override'} = 1;
$feature{'pickaxe'}{'default'} = [1];
$feature{'pickaxe'}{'override'} = 1;
$feature{'snapshot'}{'default'} = ['zip', 'tgz'];
$feature{'snapshot'}{'override'} = 1;

If you allow overriding for the snapshot feature, you can specify which snapshot formats are globally disabled. You can also add any command-line options you want (such as setting the compression level). For instance, you can disable Zip compressed snapshots and set gzip(1) to run at level 6 by adding the following lines to your gitweb configuration file:

$known_snapshot_formats{'zip'}{'disabled'} = 1;
$known_snapshot_formats{'tgz'}{'compressor'} = ['gzip','-6'];


Debugging would be easier if the fallback configuration file (/etc/gitweb.conf) and environment variable to override its location (GITWEB_CONFIG_SYSTEM) had names reflecting their "fallback" role. The current names are kept to avoid breaking working setups.


The location of per-instance and system-wide configuration files can be overridden using the following environment variables:

Sets location of per-instance configuration file.
Sets location of fallback system-wide configuration file. This file is read only if per-instance one does not exist.
Sets location of common system-wide configuration file.


This is default name of per-instance configuration file. The format of this file is described above.
This is default name of fallback system-wide configuration file. This file is used only if per-instance configuration variable is not found.
This is default name of common system-wide configuration file.


Part of the Section G.3.1, “git(1)” suite

G.4.15. gitworkflows(7)


gitworkflows - An overview of recommended workflows with Git


git *


This document attempts to write down and motivate some of the workflow elements used for git.git itself. Many ideas apply in general, though the full workflow is rarely required for smaller projects with fewer people involved.

We formulate a set of rules for quick reference, while the prose tries to motivate each of them. Do not always take them literally; you should value good reasons for your actions higher than manpages such as this one.


As a general rule, you should try to split your changes into small logical steps, and commit each of them. They should be consistent, working independently of any later commits, pass the test suite, etc. This makes the review process much easier, and the history much more useful for later inspection and analysis, for example with Section G.3.9, “git-blame(1)” and Section G.3.8, “git-bisect(1)”.

To achieve this, try to split your work into small steps from the very beginning. It is always easier to squash a few commits together than to split one big commit into several. Don't be afraid of making too small or imperfect steps along the way. You can always go back later and edit the commits with git rebase --interactive before you publish them. You can use git stash save --keep-index to run the test suite independent of other uncommitted changes; see the EXAMPLES section of Section G.3.128, “git-stash(1)”.


There are two main tools that can be used to include changes from one branch on another: Section G.3.79, “git-merge(1)” and Section G.3.19, “git-cherry-pick(1)”.

Merges have many advantages, so we try to solve as many problems as possible with merges alone. Cherry-picking is still occasionally useful; see "Merging upwards" below for an example.

Most importantly, merging works at the branch level, while cherry-picking works at the commit level. This means that a merge can carry over the changes from 1, 10, or 1000 commits with equal ease, which in turn means the workflow scales much better to a large number of contributors (and contributions). Merges are also easier to understand because a merge commit is a "promise" that all changes from all its parents are now included.

There is a tradeoff of course: merges require a more careful branch management. The following subsections discuss the important points.

1. Graduation

As a given feature goes from experimental to stable, it also "graduates" between the corresponding branches of the software. git.git uses the following integration branches:

  • maint tracks the commits that should go into the next "maintenance release", i.e., update of the last released stable version;
  • master tracks the commits that should go into the next release;
  • next is intended as a testing branch for topics being tested for stability for master.

There is a fourth official branch that is used slightly differently:

  • pu (proposed updates) is an integration branch for things that are not quite ready for inclusion yet (see "Integration Branches" below).

Each of the four branches is usually a direct descendant of the one above it.

Conceptually, the feature enters at an unstable branch (usually next or pu), and "graduates" to master for the next release once it is considered stable enough.

2. Merging upwards

The "downwards graduation" discussed above cannot be done by actually merging downwards, however, since that would merge all changes on the unstable branch into the stable one. Hence the following:

Example G.1. Merge upwards

Always commit your fixes to the oldest supported branch that require them. Then (periodically) merge the integration branches upwards into each other.

This gives a very controlled flow of fixes. If you notice that you have applied a fix to e.g. master that is also required in maint, you will need to cherry-pick it (using Section G.3.19, “git-cherry-pick(1)”) downwards. This will happen a few times and is nothing to worry about unless you do it very frequently.

3. Topic branches

Any nontrivial feature will require several patches to implement, and may get extra bugfixes or improvements during its lifetime.

Committing everything directly on the integration branches leads to many problems: Bad commits cannot be undone, so they must be reverted one by one, which creates confusing histories and further error potential when you forget to revert part of a group of changes. Working in parallel mixes up the changes, creating further confusion.

Use of "topic branches" solves these problems. The name is pretty self explanatory, with a caveat that comes from the "merge upwards" rule above:

Example G.2. Topic branches

Make a side branch for every topic (feature, bugfix, …). Fork it off at the oldest integration branch that you will eventually want to merge it into.

Many things can then be done very naturally:

  • To get the feature/bugfix into an integration branch, simply merge it. If the topic has evolved further in the meantime, merge again. (Note that you do not necessarily have to merge it to the oldest integration branch first. For example, you can first merge a bugfix to next, give it some testing time, and merge to maint when you know it is stable.)
  • If you find you need new features from the branch other to continue working on your topic, merge other to topic. (However, do not do this "just habitually", see below.)
  • If you find you forked off the wrong branch and want to move it "back in time", use Section G.3.99, “git-rebase(1)”.

Note that the last point clashes with the other two: a topic that has been merged elsewhere should not be rebased. See the section on RECOVERING FROM UPSTREAM REBASE in Section G.3.99, “git-rebase(1)”.

We should point out that "habitually" (regularly for no real reason) merging an integration branch into your topics -- and by extension, merging anything upstream into anything downstream on a regular basis -- is frowned upon:

Example G.3. Merge to downstream only at well-defined points

Do not merge to downstream except with a good reason: upstream API changes affect your branch; your branch no longer merges to upstream cleanly; etc.

Otherwise, the topic that was merged to suddenly contains more than a single (well-separated) change. The many resulting small merges will greatly clutter up history. Anyone who later investigates the history of a file will have to find out whether that merge affected the topic in development. An upstream might even inadvertently be merged into a "more stable" branch. And so on.

4. Throw-away integration

If you followed the last paragraph, you will now have many small topic branches, and occasionally wonder how they interact. Perhaps the result of merging them does not even work? But on the other hand, we want to avoid merging them anywhere "stable" because such merges cannot easily be undone.

The solution, of course, is to make a merge that we can undo: merge into a throw-away branch.

Example G.4. Throw-away integration branches

To test the interaction of several topics, merge them into a throw-away branch. You must never base any work on such a branch!

If you make it (very) clear that this branch is going to be deleted right after the testing, you can even publish this branch, for example to give the testers a chance to work with it, or other developers a chance to see if their in-progress work will be compatible. git.git has such an official throw-away integration branch called pu.

5. Branch management for a release

Assuming you are using the merge approach discussed above, when you are releasing your project you will need to do some additional branch management work.

A feature release is created from the master branch, since master tracks the commits that should go into the next feature release.

The master branch is supposed to be a superset of maint. If this condition does not hold, then maint contains some commits that are not included on master. The fixes represented by those commits will therefore not be included in your feature release.

To verify that master is indeed a superset of maint, use git log:

Example G.5. Verify master is a superset of maint

git log master..maint

This command should not list any commits. Otherwise, check out master and merge maint into it.

Now you can proceed with the creation of the feature release. Apply a tag to the tip of master indicating the release version:

Example G.6. Release tagging

git tag -s -m "Git X.Y.Z" vX.Y.Z master

You need to push the new tag to a public Git server (see "DISTRIBUTED WORKFLOWS" below). This makes the tag available to others tracking your project. The push could also trigger a post-update hook to perform release-related items such as building release tarballs and preformatted documentation pages.

Similarly, for a maintenance release, maint is tracking the commits to be released. Therefore, in the steps above simply tag and push maint rather than master.

6. Maintenance branch management after a feature release

After a feature release, you need to manage your maintenance branches.

First, if you wish to continue to release maintenance fixes for the feature release made before the recent one, then you must create another branch to track commits for that previous release.

To do this, the current maintenance branch is copied to another branch named with the previous release version number (e.g. maint-X.Y.(Z-1) where X.Y.Z is the current release).

Example G.7. Copy maint

git branch maint-X.Y.(Z-1) maint

The maint branch should now be fast-forwarded to the newly released code so that maintenance fixes can be tracked for the current release:

Example G.8. Update maint to new release

  • git checkout maint
  • git merge --ff-only master

If the merge fails because it is not a fast-forward, then it is possible some fixes on maint were missed in the feature release. This will not happen if the content of the branches was verified as described in the previous section.

7. Branch management for next and pu after a feature release

After a feature release, the integration branch next may optionally be rewound and rebuilt from the tip of master using the surviving topics on next:

Example G.9. Rewind and rebuild next

  • git checkout next
  • git reset --hard master
  • git merge ai/topic_in_next1
  • git merge ai/topic_in_next2

The advantage of doing this is that the history of next will be clean. For example, some topics merged into next may have initially looked promising, but were later found to be undesirable or premature. In such a case, the topic is reverted out of next but the fact remains in the history that it was once merged and reverted. By recreating next, you give another incarnation of such topics a clean slate to retry, and a feature release is a good point in history to do so.

If you do this, then you should make a public announcement indicating that next was rewound and rebuilt.

The same rewind and rebuild process may be followed for pu. A public announcement is not necessary since pu is a throw-away branch, as described above.


After the last section, you should know how to manage topics. In general, you will not be the only person working on the project, so you will have to share your work.

Roughly speaking, there are two important workflows: merge and patch. The important difference is that the merge workflow can propagate full history, including merges, while patches cannot. Both workflows can be used in parallel: in git.git, only subsystem maintainers use the merge workflow, while everyone else sends patches.

Note that the maintainer(s) may impose restrictions, such as "Signed-off-by" requirements, that all commits/patches submitted for inclusion must adhere to. Consult your project's documentation for more information.

1. Merge workflow

The merge workflow works by copying branches between upstream and downstream. Upstream can merge contributions into the official history; downstream base their work on the official history.

There are three main tools that can be used for this:

Note the last point. Do not use git pull unless you actually want to merge the remote branch.

Getting changes out is easy:

Example G.10. Push/pull: Publishing branches/topics

git push <remote> <branch> and tell everyone where they can fetch from.

You will still have to tell people by other means, such as mail. (Git provides the Section G.3.109, “git-request-pull(1)” to send preformatted pull requests to upstream maintainers to simplify this task.)

If you just want to get the newest copies of the integration branches, staying up to date is easy too:

Example G.11. Push/pull: Staying up to date

Use git fetch <remote> or git remote update to stay up to date.

Then simply fork your topic branches from the stable remotes as explained earlier.

If you are a maintainer and would like to merge other people's topic branches to the integration branches, they will typically send a request to do so by mail. Such a request looks like

Please pull from
    <url> <branch>

In that case, git pull can do the fetch and merge in one go, as follows.

Example G.12. Push/pull: Merging remote topics

git pull <url> <branch>

Occasionally, the maintainer may get merge conflicts when he tries to pull changes from downstream. In this case, he can ask downstream to do the merge and resolve the conflicts themselves (perhaps they will know better how to resolve them). It is one of the rare cases where downstream should merge from upstream.

2. Patch workflow

If you are a contributor that sends changes upstream in the form of emails, you should use topic branches as usual (see above). Then use Section G.3.50, “git-format-patch(1)” to generate the corresponding emails (highly recommended over manually formatting them because it makes the maintainer's life easier).

Example G.13. format-patch/am: Publishing branches/topics

  • git format-patch -M upstream..topic to turn them into preformatted patch files
  • git send-email --to=<recipient> <patches>

See the Section G.3.50, “git-format-patch(1)” and Section G.3.116, “git-send-email(1)” manpages for further usage notes.

If the maintainer tells you that your patch no longer applies to the current upstream, you will have to rebase your topic (you cannot use a merge because you cannot format-patch merges):

Example G.14. format-patch/am: Keeping topics up to date

git pull --rebase <url> <branch>

You can then fix the conflicts during the rebase. Presumably you have not published your topic other than by mail, so rebasing it is not a problem.

If you receive such a patch series (as maintainer, or perhaps as a reader of the mailing list it was sent to), save the mails to files, create a new topic branch and use git am to import the commits:

Example G.15. format-patch/am: Importing patches

git am < patch

One feature worth pointing out is the three-way merge, which can help if you get conflicts: git am -3 will use index information contained in patches to figure out the merge base. See Section G.3.3, “git-am(1)” for other options.


Part of the Section G.3.1, “git(1)” suite.

G.4.16. gitglossary(7)


gitglossary - A Git Glossary




alternate object database
Via the alternates mechanism, a repository can inherit part of its object database from another object database, which is called an "alternate".
bare repository
A bare repository is normally an appropriately named directory with a .git suffix that does not have a locally checked-out copy of any of the files under revision control. That is, all of the Git administrative and control files that would normally be present in the hidden .git sub-directory are directly present in the repository.git directory instead, and no other files are present and checked out. Usually publishers of public repositories make bare repositories available.
blob object
Untyped object, e.g. the contents of a file.
A "branch" is an active line of development. The most recent commit on a branch is referred to as the tip of that branch. The tip of the branch is referenced by a branch head, which moves forward as additional development is done on the branch. A single Git repository can track an arbitrary number of branches, but your working tree is associated with just one of them (the "current" or "checked out" branch), and HEAD points to that branch.
Obsolete for: index.
A list of objects, where each object in the list contains a reference to its successor (for example, the successor of a commit could be one of its parents).
BitKeeper/cvsps speak for "commit". Since Git does not store changes, but states, it really does not make sense to use the term "changesets" with Git.
The action of updating all or part of the working tree with a tree object or blob from the object database, and updating the index and HEAD if the whole working tree has been pointed at a new branch.
In SCM jargon, "cherry pick" means to choose a subset of changes out of a series of changes (typically commits) and record them as a new series of changes on top of a different codebase. In Git, this is performed by the "git cherry-pick" command to extract the change introduced by an existing commit and to record it based on the tip of the current branch as a new commit.
A working tree is clean, if it corresponds to the revision referenced by the current head. Also see "dirty".

As a noun: A single point in the Git history; the entire history of a project is represented as a set of interrelated commits. The word "commit" is often used by Git in the same places other revision control systems use the words "revision" or "version". Also used as a short hand for commit object.

As a verb: The action of storing a new snapshot of the project's state in the Git history, by creating a new commit representing the current state of the index and advancing HEAD to point at the new commit.

commit object
An object which contains the information about a particular revision, such as parents, committer, author, date and the tree object which corresponds to the top directory of the stored revision.
commit-ish (also committish)
A commit object or an object that can be recursively dereferenced to a commit object. The following are all commit-ishes: a commit object, a tag object that points to a commit object, a tag object that points to a tag object that points to a commit object, etc.
core Git
Fundamental data structures and utilities of Git. Exposes only limited source code management tools.
Directed acyclic graph. The commit objects form a directed acyclic graph, because they have parents (directed), and the graph of commit objects is acyclic (there is no chain which begins and ends with the same object).
dangling object
An unreachable object which is not reachable even from other unreachable objects; a dangling object has no references to it from any reference or object in the repository.
detached HEAD

Normally the HEAD stores the name of a branch, and commands that operate on the history HEAD represents operate on the history leading to the tip of the branch the HEAD points at. However, Git also allows you to check out an arbitrary commit that isn't necessarily the tip of any particular branch. The HEAD in such a state is called "detached".

Note that commands that operate on the history of the current branch (e.g. git commit to build a new history on top of it) still work while the HEAD is detached. They update the HEAD to point at the tip of the updated history without affecting any branch. Commands that update or inquire information about the current branch (e.g. git branch --set-upstream-to that sets what remote-tracking branch the current branch integrates with) obviously do not work, as there is no (real) current branch to ask about in this state.

The list you get with "ls" :-)
A working tree is said to be "dirty" if it contains modifications which have not been committed to the current branch.
evil merge
An evil merge is a merge that introduces changes that do not appear in any parent.
A fast-forward is a special type of merge where you have a revision and you are "merging" another branch's changes that happen to be a descendant of what you have. In such these cases, you do not make a new merge commit but instead just update to his revision. This will happen frequently on a remote-tracking branch of a remote repository.
Fetching a branch means to get the branch's head ref from a remote repository, to find out which objects are missing from the local object database, and to get them, too. See also Section G.3.46, “git-fetch(1)”.
file system
Linus Torvalds originally designed Git to be a user space file system, i.e. the infrastructure to hold files and directories. That ensured the efficiency and speed of Git.
Git archive
Synonym for repository (for arch people).
A plain file .git at the root of a working tree that points at the directory that is the real repository.

Grafts enables two otherwise different lines of development to be joined together by recording fake ancestry information for commits. This way you can make Git pretend the set of parents a commit has is different from what was recorded when the commit was created. Configured via the .git/info/grafts file.

Note that the grafts mechanism is outdated and can lead to problems transferring objects between repositories; see Section G.3.108, “git-replace(1)” for a more flexible and robust system to do the same thing.

In Git's context, synonym for object name.
A named reference to the commit at the tip of a branch. Heads are stored in a file in $GIT_DIR/refs/heads/ directory, except when using packed refs. (See Section G.3.90, “git-pack-refs(1)”.)
The current branch. In more detail: Your working tree is normally derived from the state of the tree referred to by HEAD. HEAD is a reference to one of the heads in your repository, except when using a detached HEAD, in which case it directly references an arbitrary commit.
head ref
A synonym for head.
During the normal execution of several Git commands, call-outs are made to optional scripts that allow a developer to add functionality or checking. Typically, the hooks allow for a command to be pre-verified and potentially aborted, and allow for a post-notification after the operation is done. The hook scripts are found in the $GIT_DIR/hooks/ directory, and are enabled by simply removing the .sample suffix from the filename. In earlier versions of Git you had to make them executable.
A collection of files with stat information, whose contents are stored as objects. The index is a stored version of your working tree. Truth be told, it can also contain a second, and even a third version of a working tree, which are used when merging.
index entry
The information regarding a particular file, stored in the index. An index entry can be unmerged, if a merge was started, but not yet finished (i.e. if the index contains multiple versions of that file).
The default development branch. Whenever you create a Git repository, a branch named "master" is created, and becomes the active branch. In most cases, this contains the local development, though that is purely by convention and is not required.

As a verb: To bring the contents of another branch (possibly from an external repository) into the current branch. In the case where the merged-in branch is from a different repository, this is done by first fetching the remote branch and then merging the result into the current branch. This combination of fetch and merge operations is called a pull. Merging is performed by an automatic process that identifies changes made since the branches diverged, and then applies all those changes together. In cases where changes conflict, manual intervention may be required to complete the merge.

As a noun: unless it is a fast-forward, a successful merge results in the creation of a new commit representing the result of the merge, and having as parents the tips of the merged branches. This commit is referred to as a "merge commit", or sometimes just a "merge".

The unit of storage in Git. It is uniquely identified by the SHA-1 of its contents. Consequently, an object can not be changed.
object database
Stores a set of "objects", and an individual object is identified by its object name. The objects usually live in $GIT_DIR/objects/.
object identifier
Synonym for object name.
object name
The unique identifier of an object. The object name is usually represented by a 40 character hexadecimal string. Also colloquially called SHA-1.
object type
One of the identifiers "commit", "tree", "tag" or "blob" describing the type of an object.
To merge more than two branches.
The default upstream repository. Most projects have at least one upstream project which they track. By default origin is used for that purpose. New upstream updates will be fetched into remote-tracking branches named origin/name-of-upstream-branch, which you can see using git branch -r.
A set of objects which have been compressed into one file (to save space or to transmit them efficiently).
pack index
The list of identifiers, and other information, of the objects in a pack, to assist in efficiently accessing the contents of a pack.

Pattern used to limit paths in Git commands.

Pathspecs are used on the command line of "git ls-files", "git ls-tree", "git add", "git grep", "git diff", "git checkout", and many other commands to limit the scope of operations to some subset of the tree or worktree. See the documentation of each command for whether paths are relative to the current directory or toplevel. The pathspec syntax is as follows:

  • any path matches itself
  • the pathspec up to the last slash represents a directory prefix. The scope of that pathspec is limited to that subtree.
  • the rest of the pathspec is a pattern for the remainder of the pathname. Paths relative to the directory prefix will be matched against that pattern using fnmatch(3); in particular, * and ? can match directory separators.

For example, Documentation/*.jpg will match all .jpg files in the Documentation subtree, including Documentation/chapter_1/figure_1.jpg.

A pathspec that begins with a colon : has special meaning. In the short form, the leading colon : is followed by zero or more "magic signature" letters (which optionally is terminated by another colon :), and the remainder is the pattern to match against the path. The "magic signature" consists of ASCII symbols that are neither alphanumeric, glob, regex special characters nor colon. The optional colon that terminates the "magic signature" can be omitted if the pattern begins with a character that does not belong to "magic signature" symbol set and is not a colon.

In the long form, the leading colon : is followed by a open parenthesis (, a comma-separated list of zero or more "magic words", and a close parentheses ), and the remainder is the pattern to match against the path.

A pathspec with only a colon means "there is no pathspec". This form should not be combined with other pathspec.

The magic word top (magic signature: /) makes the pattern match from the root of the working tree, even when you are running the command from inside a subdirectory.
Wildcards in the pattern such as * or ? are treated as literal characters.
Case insensitive match.

Git treats the pattern as a shell glob suitable for consumption by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the pattern will not match a / in the pathname. For example, "Documentation/*.html" matches "Documentation/git.html" but not "Documentation/ppc/ppc.html" or "tools/perf/Documentation/perf.html".

Two consecutive asterisks ("**") in patterns matched against full pathname may have special meaning:

  • A leading "**" followed by a slash means match in all directories. For example, "**/foo" matches file or directory "foo" anywhere, the same as pattern "foo". "**/foo/bar" matches file or directory "bar" anywhere that is directly under directory "foo".
  • A trailing "/**" matches everything inside. For example, "abc/**" matches all files inside directory "abc", relative to the location of the .gitignore file, with infinite depth.
  • A slash followed by two consecutive asterisks then a slash matches zero or more directories. For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on.
  • Other consecutive asterisks are considered invalid.

    Glob magic is incompatible with literal magic.

After a path matches any non-exclude pathspec, it will be run through all exclude pathspec (magic signature: !). If it matches, the path is ignored.
A commit object contains a (possibly empty) list of the logical predecessor(s) in the line of development, i.e. its parents.
The term pickaxe refers to an option to the diffcore routines that help select changes that add or delete a given text string. With the --pickaxe-all option, it can be used to view the full changeset that introduced or removed, say, a particular line of text. See Section G.3.41, “git-diff(1)”.
Cute name for core Git.
Cute name for programs and program suites depending on core Git, presenting a high level access to core Git. Porcelains expose more of a SCM interface than the plumbing.
per-worktree ref
Refs that are per-worktree, rather than global. This is presently only HEAD and any refs that start with refs/bisect/, but might later include other unusual refs.
Pseudorefs are a class of files under $GIT_DIR which behave like refs for the purposes of rev-parse, but which are treated specially by git. Pseudorefs both have names that are all-caps, and always start with a line consisting of a SHA-1 followed by whitespace. So, HEAD is not a pseudoref, because it is sometimes a symbolic ref. They might optionally contain some additional data. MERGE_HEAD and CHERRY_PICK_HEAD are examples. Unlike per-worktree refs, these files cannot be symbolic refs, and never have reflogs. They also cannot be updated through the normal ref update machinery. Instead, they are updated by directly writing to the files. However, they can be read as if they were refs, so git rev-parse MERGE_HEAD will work.
Pulling a branch means to fetch it and merge it. See also Section G.3.95, “git-pull(1)”.
Pushing a branch means to get the branch's head ref from a remote repository, find out if it is a direct ancestor to the branch's local head ref, and in that case, putting all objects, which are reachable from the local head ref, and which are missing from the remote repository, into the remote object database, and updating the remote head ref. If the remote head is not an ancestor to the local head, the push fails.
All of the ancestors of a given commit are said to be "reachable" from that commit. More generally, one object is reachable from another if we can reach the one from the other by a chain that follows tags to whatever they tag, commits to their parents or trees, and trees to the trees or blobs that they contain.
To reapply a series of changes from a branch to a different base, and reset the head of that branch to the result.

A name that begins with refs/ (e.g. refs/heads/master) that points to an object name or another ref (the latter is called a symbolic ref). For convenience, a ref can sometimes be abbreviated when used as an argument to a Git command; see Section G.4.12, “gitrevisions(7)” for details. Refs are stored in the repository.

The ref namespace is hierarchical. Different subhierarchies are used for different purposes (e.g. the refs/heads/ hierarchy is used to represent local branches).

There are a few special-purpose refs that do not begin with refs/. The most notable example is HEAD.

A reflog shows the local "history" of a ref. In other words, it can tell you what the 3rd last revision in this repository was, and what was the current state in this repository, yesterday 9:14pm. See Section G.3.101, “git-reflog(1)” for details.
A "refspec" is used by fetch and push to describe the mapping between remote ref and local ref.
remote repository
A repository which is used to track the same project but resides somewhere else. To communicate with remotes, see fetch or push.
remote-tracking branch
A ref that is used to follow changes from another repository. It typically looks like refs/remotes/foo/bar (indicating that it tracks a branch named bar in a remote named foo), and matches the right-hand-side of a configured fetch refspec. A remote-tracking branch should not contain direct modifications or have local commits made to it.
A collection of refs together with an object database containing all objects which are reachable from the refs, possibly accompanied by meta data from one or more porcelains. A repository can share an object database with other repositories via alternates mechanism.
The action of fixing up manually what a failed automatic merge left behind.
Synonym for commit (the noun).
To throw away part of the development, i.e. to assign the head to an earlier revision.
Source code management (tool).
"Secure Hash Algorithm 1"; a cryptographic hash function. In the context of Git used as a synonym for object name.
shallow clone
Mostly a synonym to shallow repository but the phrase makes it more explicit that it was created by running git clone --depth=... command.
shallow repository
A shallow repository has an incomplete history some of whose commits have parents cauterized away (in other words, Git is told to pretend that these commits do not have the parents, even though they are recorded in the commit object). This is sometimes useful when you are interested only in the recent history of a project even though the real history recorded in the upstream is much larger. A shallow repository is created by giving the --depth option to Section G.3.23, “git-clone(1)”, and its history can be later deepened with Section G.3.46, “git-fetch(1)”.
A repository that holds the history of a separate project inside another repository (the latter of which is called superproject).
A repository that references repositories of other projects in its working tree as submodules. The superproject knows about the names of (but does not hold copies of) commit objects of the contained submodules.
Symbolic reference: instead of containing the SHA-1 id itself, it is of the format ref: refs/some/thing and when referenced, it recursively dereferences to this reference. HEAD is a prime example of a symref. Symbolic references are manipulated with the Section G.3.133, “git-symbolic-ref(1)” command.
A ref under refs/tags/ namespace that points to an object of an arbitrary type (typically a tag points to either a tag or a commit object). In contrast to a head, a tag is not updated by the commit command. A Git tag has nothing to do with a Lisp tag (which would be called an object type in Git's context). A tag is most typically used to mark a particular point in the commit ancestry chain.
tag object
An object containing a ref pointing to another object, which can contain a message just like a commit object. It can also contain a (PGP) signature, in which case it is called a "signed tag object".
topic branch
A regular Git branch that is used by a developer to identify a conceptual line of development. Since branches are very easy and inexpensive, it is often desirable to have several small branches that each contain very well defined concepts or small incremental yet related changes.
Either a working tree, or a tree object together with the dependent blob and tree objects (i.e. a stored representation of a working tree).
tree object
An object containing a list of file names and modes along with refs to the associated blob and/or tree objects. A tree is equivalent to a directory.
tree-ish (also treeish)
A tree object or an object that can be recursively dereferenced to a tree object. Dereferencing a commit object yields the tree object corresponding to the revision's top directory. The following are all tree-ishes: a commit-ish, a tree object, a tag object that points to a tree object, a tag object that points to a tag object that points to a tree object, etc.
unmerged index
An index which contains unmerged index entries.
unreachable object
An object which is not reachable from a branch, tag, or any other reference.
upstream branch
The default branch that is merged into the branch in question (or the branch in question is rebased onto). It is configured via branch.<name>.remote and branch.<name>.merge. If the upstream branch of A is origin/B sometimes we say "A is tracking origin/B".
working tree
The tree of actual checked out files. The working tree normally contains the contents of the HEAD commit's tree, plus any local changes that you have made but not yet committed.


Part of the Section G.3.1, “git(1)” suite.