Misc

This Git documentation is based on Git 2.53. The up to date Git reference can be found on https://git-scm.com/docs/

gitcli(7)

NAME

gitcli - Git command-line interface and conventions

SYNOPSIS

gitcli

DESCRIPTION

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:

  • Options come first and then args. A subcommand may take dashed options (which may take their own arguments, e.g. "--max-parents 2") and arguments. You SHOULD give dashed options first and then arguments. Some commands may accept dashed options after you have already given non-option arguments (which may make the command ambiguous), but you should not rely on it (because eventually we may find a way to fix these ambiguities by enforcing the "options then args" rule).
  • 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 the 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 asks 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.
  • Because -- disambiguates revisions and paths in some commands, it cannot be used for those commands to separate options and revisions. You can use --end-of-options for this (it also works for commands that do not distinguish between revisions in paths, in which case it is simply an alias for --).

    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 restore *.c
    $ git restore \*.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:

  • 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.
  • Despite the above suggestion, when Arg is a path relative to the home directory of a user, e.g. ~/directory/file or ~u/d/f, you may want to use the separate form, e.g. git foo --file ~/mine, not git foo --file=~/mine. The shell will expand ~/ in the former to your home directory, but most shells keep the tilde in the latter. Some of our commands know how to tilde-expand the option value even when given in the stuck form, but not all of them do.
  • 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.

ENHANCED OPTION PARSER

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.

Magic Options

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

-h

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

Note that some subcommand (e.g. git grep) may behave differently when there are things on the command line other than -h, but git subcmd -h without anything else on the command line is meant to consistently give the usage.

--help-all
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.

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.

Options trump configuration and environment

When there is a configuration variable or an environment variable that tweak the behaviour of an aspect of a Git command, and also a command line option that tweaks the same, the command line option overrides what the configuration and/or environment variable say.

For example, the user.name configuration variable is used to specify the human-readable name used by the git commit command to record the author and the committer name in a newly created commit. The GIT_AUTHOR_NAME environment variable, if set, takes precedence when deciding what author name to record. The --author=<author> command line option of the git commit command, when given, takes precedence over these two sources of information.

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.

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.

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

Magic filename options

Options that take a filename allow a prefix :(optional). For example:

git commit -F :(optional)COMMIT_EDITMSG
# if COMMIT_EDITMSG does not exist, the above is equivalent to
git commit

Like with configuration values, if the named file is missing Git behaves as if the option was not given at all. See "Values" in the section called “git-config(1)”.

NOTES ON FREQUENTLY CONFUSED OPTIONS

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 entry 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 https://lore.kernel.org/git/7v64clg5u9.fsf@assigned-by-dhcp.cox.net/ and https://lore.kernel.org/git/7vy7ej9g38.fsf@gitster.siamese.dyndns.org/ for further information.

Some other commands that also work on files in the working tree and/or in the index can take --staged and/or --worktree.

  • --staged is exactly like --cached, which is used to ask a command to only work on the index, not the working tree.
  • --worktree is the opposite, to ask a command to work on the working tree only, not the index.
  • The two options can be specified together to ask a command to work on both the index and the working tree.

GIT

Part of the the section called “git(1)” suite

gitattributes(5)

NAME

gitattributes - Defining attributes per path

SYNOPSIS

$GIT_DIR/info/attributes, .gitattributes

DESCRIPTION

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. Leading and trailing whitespaces are ignored. Lines that begin with # are ignored. Patterns that begin with a double quote are quoted in C style. 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:

Set
The path has the attribute with special value "true"; this is specified by listing only the name of the attribute in the attribute list.
Unset
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.
Unspecified
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 by which the pattern matches paths are the same as in .gitignore files (see the section called “gitignore(5)”), with a few exceptions:

  • negative patterns are forbidden
  • patterns that match a directory do not recursively match paths inside that directory (so using the trailing-slash path/ syntax is pointless in an attributes file; use path/** instead)

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 the section called “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 a 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 !.

RESERVED BUILTIN_* ATTRIBUTES

builtin_* is a reserved namespace for builtin attribute values. Any user defined attributes under this namespace will be ignored and trigger a warning.

builtin_objectmode

This attribute is for filtering files by their file bit modes (40000, 120000, 160000, 100755, 100644). e.g. :(attr:builtin_objectmode=160000). You may also check these values with git check-attr builtin_objectmode -- <file>. If the object is not in the index git check-attr --cached will return unspecified.

EFFECTS

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

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 switch, 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.

text

This attribute marks the path as a text file, which enables end-of-line conversion: When a matching file is added to the index, the file's line endings are normalized to LF in the index. Conversely, when the file is copied from the index to the working directory, its line endings may be converted from LF to CRLF depending on the eol attribute, the Git config, and the platform (see explanation of eol below).

Set
Setting the text attribute on a path enables end-of-line conversion on checkin and checkout as described above. Line endings are normalized to LF in the index every time the file is checked in, even if the file was previously added to Git with CRLF line endings.
Unset
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", Git decides by itself whether the file is text or binary. If it is text and the file was not already in Git with CRLF endings, line endings are converted on checkin and checkout as described above. Otherwise, no conversion is done on checkin or checkout.
Unspecified
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.

eol

This attribute marks a path to use a specific line-ending style in the working tree when it is checked out. It has effect only if text or text=auto is set (see above), but specifying eol automatically sets text if text was left unspecified.

Set to string value "crlf"
This setting converts the file's line endings in the working directory to CRLF when the file is checked out.
Set to string value "lf"
This setting uses the same line endings in the working directory as in the index when the file is checked out.
Unspecified
If the eol attribute is unspecified for a file, its line endings in the working directory are determined by the core.autocrlf or core.eol configuration variable (see the definitions of those options in the section called “git-config(1)”). If text is set but neither of those variables is, the default is eol=crlf on Windows and eol=lf on all other platforms.

Backwards compatibility with crlf attribute

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

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

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.

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 using any attributes.

[core]
        autocrlf = true

This does not force normalization of 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 ensure that text files that any contributor introduces to the repository have their line endings normalized, you can set the text attribute to "auto" for all files.

*       text=auto

The attributes allow a fine-grained control, how the line endings are converted. 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.

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

Note

When text=auto conversion is enabled in a cross-platform project using push and pull to a central repository the text files containing CRLFs should be normalized.

From a clean working directory:

$ echo "* text=auto" >.gitattributes
$ git add --renormalize .
$ git status        # Show files that will be normalized
$ 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.

working-tree-encoding

Git recognizes files encoded in ASCII or one of its supersets (e.g. UTF-8, ISO-8859-1, …) as text files. Files encoded in certain other encodings (e.g. UTF-16) are interpreted as binary and consequently built-in Git text processing tools (e.g. git diff) as well as most Git web front ends do not visualize the contents of these files by default.

In these cases you can tell Git the encoding of a file in the working directory with the working-tree-encoding attribute. If a file with this attribute is added to Git, then Git re-encodes the content from the specified encoding to UTF-8. Finally, Git stores the UTF-8 encoded content in its internal data structure (called "the index"). On checkout the content is re-encoded back to the specified encoding.

Please note that using the working-tree-encoding attribute may have a number of pitfalls:

  • Alternative Git implementations (e.g. JGit or libgit2) and older Git versions (as of March 2018) do not support the working-tree-encoding attribute. If you decide to use the working-tree-encoding attribute in your repository, then it is strongly recommended to ensure that all clients working with the repository support it.

    For example, Microsoft Visual Studio resources files (*.rc) or PowerShell script files (*.ps1) are sometimes encoded in UTF-16. If you declare *.ps1 as files as UTF-16 and you add foo.ps1 with a working-tree-encoding enabled Git client, then foo.ps1 will be stored as UTF-8 internally. A client without working-tree-encoding support will checkout foo.ps1 as UTF-8 encoded file. This will typically cause trouble for the users of this file.

    If a Git client that does not support the working-tree-encoding attribute adds a new file bar.ps1, then bar.ps1 will be stored "as-is" internally (in this example probably as UTF-16). A client with working-tree-encoding support will interpret the internal contents as UTF-8 and try to convert it to UTF-16 on checkout. That operation will fail and cause an error.

  • Reencoding content to non-UTF encodings can cause errors as the conversion might not be UTF-8 round trip safe. If you suspect your encoding to not be round trip safe, then add it to core.checkRoundtripEncoding to make Git check the round trip encoding (see the section called “git-config(1)”). SHIFT-JIS (Japanese character set) is known to have round trip issues with UTF-8 and is checked by default.
  • Reencoding content requires resources that might slow down certain Git operations (e.g git checkout or git add).

Use the working-tree-encoding attribute only if you cannot store a file in UTF-8 encoding and if you want Git to be able to process the content as text.

As an example, use the following attributes if your *.ps1 files are UTF-16 encoded with byte order mark (BOM) and you want Git to perform automatic line ending conversion based on your platform.

*.ps1           text working-tree-encoding=UTF-16

Use the following attributes if your *.ps1 files are UTF-16 little endian encoded without BOM and you want Git to use Windows line endings in the working directory (use UTF-16LE-BOM instead of UTF-16LE if you want UTF-16 little endian with BOM). Please note, it is highly recommended to explicitly define the line endings with eol if the working-tree-encoding attribute is used to avoid ambiguity.

*.ps1           text working-tree-encoding=UTF-16LE eol=crlf

You can get a list of all available encodings on your platform with the following command:

iconv --list

If you do not know the encoding of a file, then you can use the file command to guess the encoding:

file foo.ps1

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.

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. By default these commands process only a single blob and terminate. If a long running process filter is used in place of clean and/or smudge filters, then Git can process all blobs with a single filter command invocation for the entire life of a single Git command, for example git add --all. If a long running process filter is configured then it always takes precedence over a configured single blob filter. See section below for the description of the protocol used to communicate with a process filter.

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.

Note: Whenever the clean filter is changed, the repo should be renormalized: $ git add --renormalize .

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 ...
        required

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

Note that "%f" is the name of the path that is being worked on. Depending on the version that is being filtered, the corresponding file on disk may not exist, or may have different contents. So, smudge and clean commands should not try to access the file on disk, but only act as filters on the content provided to them on standard input.

Long Running Filter Process

If the filter command (a string value) is defined via filter.<driver>.process then Git can process all blobs with a single filter invocation for the entire life of a single Git command. This is achieved by using the long-running process protocol (described in Documentation/technical/long-running-process-protocol.adoc).

When Git encounters the first file that needs to be cleaned or smudged, it starts the filter and performs the handshake. In the handshake, the welcome message sent by Git is "git-filter-client", only version 2 is supported, and the supported capabilities are "clean", "smudge", and "delay".

Afterwards Git sends a list of "key=value" pairs terminated with a flush packet. The list will contain at least the filter command (based on the supported capabilities) and the pathname of the file to filter relative to the repository root. Right after the flush packet Git sends the content split in zero or more pkt-line packets and a flush packet to terminate content. Please note, that the filter must not send any response before it received the content and the final flush packet. Also note that the "value" of a "key=value" pair can contain the "=" character whereas the key would never contain that character.

packet:          git> command=smudge
packet:          git> pathname=path/testfile.dat
packet:          git> 0000
packet:          git> CONTENT
packet:          git> 0000

The filter is expected to respond with a list of "key=value" pairs terminated with a flush packet. If the filter does not experience problems then the list must contain a "success" status. Right after these packets the filter is expected to send the content in zero or more pkt-line packets and a flush packet at the end. Finally, a second list of "key=value" pairs terminated with a flush packet is expected. The filter can change the status in the second list or keep the status as is with an empty list. Please note that the empty list must be terminated with a flush packet regardless.

packet:          git< status=success
packet:          git< 0000
packet:          git< SMUDGED_CONTENT
packet:          git< 0000
packet:          git< 0000  # empty list, keep "status=success" unchanged!

If the result content is empty then the filter is expected to respond with a "success" status and a flush packet to signal the empty content.

packet:          git< status=success
packet:          git< 0000
packet:          git< 0000  # empty content!
packet:          git< 0000  # empty list, keep "status=success" unchanged!

In case the filter cannot or does not want to process the content, it is expected to respond with an "error" status.

packet:          git< status=error
packet:          git< 0000

If the filter experiences an error during processing, then it can send the status "error" after the content was (partially or completely) sent.

packet:          git< status=success
packet:          git< 0000
packet:          git< HALF_WRITTEN_ERRONEOUS_CONTENT
packet:          git< 0000
packet:          git< status=error
packet:          git< 0000

In case the filter cannot or does not want to process the content as well as any future content for the lifetime of the Git process, then it is expected to respond with an "abort" status at any point in the protocol.

packet:          git< status=abort
packet:          git< 0000

Git neither stops nor restarts the filter process in case the "error"/"abort" status is set. However, Git sets its exit code according to the filter.<driver>.required flag, mimicking the behavior of the filter.<driver>.clean / filter.<driver>.smudge mechanism.

If the filter dies during the communication or does not adhere to the protocol then Git will stop the filter process and restart it with the next file that needs to be processed. Depending on the filter.<driver>.required flag Git will interpret that as error.

Delay

If the filter supports the "delay" capability, then Git can send the flag "can-delay" after the filter command and pathname. This flag denotes that the filter can delay filtering the current blob (e.g. to compensate network latencies) by responding with no content but with the status "delayed" and a flush packet.

packet:          git> command=smudge
packet:          git> pathname=path/testfile.dat
packet:          git> can-delay=1
packet:          git> 0000
packet:          git> CONTENT
packet:          git> 0000
packet:          git< status=delayed
packet:          git< 0000

If the filter supports the "delay" capability then it must support the "list_available_blobs" command. If Git sends this command, then the filter is expected to return a list of pathnames representing blobs that have been delayed earlier and are now available. The list must be terminated with a flush packet followed by a "success" status that is also terminated with a flush packet. If no blobs for the delayed paths are available, yet, then the filter is expected to block the response until at least one blob becomes available. The filter can tell Git that it has no more delayed blobs by sending an empty list. As soon as the filter responds with an empty list, Git stops asking. All blobs that Git has not received at this point are considered missing and will result in an error.

packet:          git> command=list_available_blobs
packet:          git> 0000
packet:          git< pathname=path/testfile.dat
packet:          git< pathname=path/otherfile.dat
packet:          git< 0000
packet:          git< status=success
packet:          git< 0000

After Git received the pathnames, it will request the corresponding blobs again. These requests contain a pathname and an empty content section. The filter is expected to respond with the smudged content in the usual way as explained above.

packet:          git> command=smudge
packet:          git> pathname=path/testfile.dat
packet:          git> 0000
packet:          git> 0000  # empty content!
packet:          git< status=success
packet:          git< 0000
packet:          git< SMUDGED_CONTENT
packet:          git< 0000
packet:          git< 0000  # empty list, keep "status=success" unchanged!

Example

A long running filter demo implementation can be found in contrib/long-running-filter/example.pl located in the Git core repository. If you develop your own long running filter process then the GIT_TRACE_PACKET environment variables can be very helpful for debugging (see the section called “git(1)”).

Please note that you cannot use an existing filter.<driver>.clean or filter.<driver>.smudge command with filter.<driver>.process because the former two use a different inter process communication protocol than the latter one.

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.

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 each file that needs a three-way content 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.

Generating diff text

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.

Set
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.
Unset
A path to which the diff attribute is unset will generate Binary files differ (or a binary patch, if binary patches are enabled).
Unspecified
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.
String
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.

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 the section called “git(1)” for details.

If the program is able to ignore certain changes (similar to git diff --ignore-space-change), then also set the option trustExitCode to true. It is then expected to return exit code 1 if it finds significant changes and 0 if it doesn't.

Setting the internal diff algorithm

The diff algorithm can be set through the diff.algorithm config key, but sometimes it may be helpful to set the diff algorithm per path. For example, one may want to use the minimal diff algorithm for .json files, and the histogram for .c files, and so on without having to pass in the algorithm through the command line each time.

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

*.json diff=<name>

Then, define a "diff.<name>.algorithm" configuration to specify the diff algorithm, choosing from myers, patience, minimal, or histogram.

[diff "<name>"]
  algorithm = histogram

This diff algorithm applies to user facing diff output like git-diff(1), git-show(1) and is used for the --stat output as well. The merge machinery will not use the diff algorithm set through this method.

Note

If diff.<name>.command is defined for path with the diff=<name> attribute, it is executed as an external diff driver (see above), and adding diff.<name>.algorithm has no effect, as the algorithm is not passed to the external diff driver.

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.
  • bash suitable for source code in the Bourne-Again SHell language. Covers a superset of POSIX shell function definitions.
  • 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.
  • css suitable for cascading style sheets.
  • dts suitable for devicetree (DTS) files.
  • elixir suitable for source code in the Elixir language.
  • fortran suitable for source code in the Fortran language.
  • fountain suitable for Fountain documents.
  • golang suitable for source code in the Go language.
  • html suitable for HTML/XHTML documents.
  • java suitable for source code in the Java language.
  • kotlin suitable for source code in the Kotlin language.
  • markdown suitable for Markdown documents.
  • matlab suitable for source code in the MATLAB and Octave languages.
  • 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.
  • rust suitable for source code in the Rust language.
  • scheme suitable for source code in the Scheme language.
  • tex suitable for source code for LaTeX documents.

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.

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

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).

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.

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

Performing a three-way merge

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.

Set
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.
Unset
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.
Unspecified
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.
String
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".

Built-in merge drivers

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

text
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.
binary
Keep the version from your branch in the work tree, but leave the path in the conflicted state for the user to sort out.
union
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.

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 common 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. When the driver crashes (e.g. killed by SEGV), it is expected to exit with non-zero status that are higher than 128, and in such a case, the merge results in a failure (which is different from producing a conflict).

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. The conflict labels to be used for the common ancestor, local head and other head can be passed by using %S, %X and %Y respectively.

conflict-marker-size

This attribute controls the length of conflict markers left in the work tree file during a conflicted merge. Only a positive integer has a 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.adoc results in a conflict.

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

Checking whitespace errors

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 the section called “git-config(1)”). This attribute gives you finer control per path.

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

Creating an archive

export-ignore

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

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 the section called “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 the section called “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. However, only one %(describe) placeholder is expanded per archive to avoid denial-of-service attacks.

Packing objects

delta

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

Viewing files in GUI tools

encoding

The value of this attribute specifies the character encoding that should be used by GUI tools (e.g. the section called “gitk(1)” and the section called “git-gui(1)”) to display the contents of the relevant file. Note that due to performance considerations the section called “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 the section called “git-config(1)”).

USING MACRO ATTRIBUTES

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.

DEFINING MACRO ATTRIBUTES

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

NOTES

Git does not follow symbolic links when accessing a .gitattributes file in the working tree. This keeps behavior consistent when the file is accessed from the index or a tree versus from the filesystem.

EXAMPLES

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

GIT

Part of the the section called “git(1)” suite

gitcredentials(7)

NAME

gitcredentials - Providing usernames and passwords to Git

SYNOPSIS

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

DESCRIPTION

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. Some remotes accept a personal access token or OAuth access token as a password. This manual describes the mechanisms Git uses to request these credentials, as well as some features to avoid inputting these credentials repeatedly.

REQUESTING CREDENTIALS

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.

AVOIDING REPETITION

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. Alternatively, a credential-generating helper might generate credentials for certain servers via some API.

To use a helper, you must first select one to use (see below for a list).

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-
    credential-foo
  2. Read its description.

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

    $ git config --global credential.helper foo

Available helpers

Git currently includes the following helpers:

cache
Cache credentials in memory for a short period of time. See the section called “git-credential-cache(1)” for details.
store
Store credentials indefinitely on disk. See the section called “git-credential-store(1)” for details.

Popular helpers with secure persistent storage include:

  • git-credential-libsecret (Linux)
  • git-credential-osxkeychain (macOS)
  • git-credential-wincred (Windows)
  • Git Credential Manager (cross platform, included in Git for Windows)

The community maintains a comprehensive list of Git credential helpers at https://git-scm.com/doc/credential-helpers.

OAuth

An alternative to inputting passwords or personal access tokens is to use an OAuth credential helper. Initial authentication opens a browser window to the host. Subsequent authentication happens in the background. Many popular Git hosts support OAuth.

Popular helpers with OAuth support include:

CREDENTIAL CONTEXTS

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 and both hosts are the same. 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. However, you may use wildcards in the domain name and other pattern matching techniques as with the http.<URL>.* options.

If the "pattern" URL does include a path component, then this must match as a prefix path: the context https://example.com/bar will match a config entry for https://example.com/bar/baz.git but will not match a config entry for https://example.com/other/repo.git or https://example.com/barry/repo.git (even though it is a string prefix).

CONFIGURATION OPTIONS

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:

helper

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.

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 non-expired 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).

username
A default username, if one is not provided in the URL.
useHttpPath
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.

CUSTOM HELPERS

You can write your own custom helpers to interface with any system in which you keep credentials.

Credential helpers are programs executed by Git to fetch or save credentials from and to long-term storage (where "long-term" is simply longer than a single Git process; e.g., credentials may be stored in-memory for a few minutes, or indefinitely on disk).

Each helper is specified by a single string in the configuration variable credential.helper (and others, see the section called “git-config(1)”). The string is transformed by Git into a command to be executed using these rules:

  1. If the helper string begins with "!", it is considered a shell snippet, and everything after the "!" becomes the command.
  2. Otherwise, if the helper string begins with an absolute path, the verbatim helper string becomes the command.
  3. Otherwise, the string "git credential-" is prepended to the helper string, and the result becomes the command.

The resulting command then has an "operation" argument appended to it (see below for details), and the result is executed by the shell.

Here are some example specifications:

# run "git credential-foo"
[credential]
        helper = foo

# same as above, but pass an argument to the helper
[credential]
        helper = "foo --bar=baz"

# the arguments are parsed by the shell, so use shell
# quoting if necessary
[credential]
        helper = "foo --bar='whitespace arg'"

# store helper (discouraged) with custom location for the db file;
# use `--file ~/.git-secret.txt`, rather than `--file=~/.git-secret.txt`,
# to allow the shell to expand tilde to the home directory.
[credential]
        helper = "store --file ~/.git-secret.txt"

# you can also use an absolute path, which will not use the git wrapper
[credential]
        helper = "/path/to/my/helper --with-arguments"

# or you can specify your own shell snippet
[credential "https://example.com"]
        username = your_user
        helper = "!f() { test \"$1\" = get && echo \"password=$(cat $HOME/.secret)\"; }; f"

Generally speaking, rule (3) above is the simplest for users to specify. Authors of credential helpers should make an effort to assist their users by naming their program "git-credential-$NAME", and putting it in the $PATH or $GIT_EXEC_PATH during installation, which will allow a user to enable it with git config credential.helper $NAME.

When a helper is executed, it will have one "operation" argument appended to its command line, which is one of:

get
Return a matching credential, if any exists.
store
Store the credential, if applicable to the helper.
erase
Remove matching credentials, if any, from the helper's storage.

The details of the credential will be provided on the helper's stdin stream. The exact format is the same as the input/output format of the git credential plumbing command (see the section INPUT/OUTPUT FORMAT in the section called “git-credential(1)” for a detailed specification).

For a get operation, the helper should produce a list of attributes on stdout in the same format (see the section called “git-credential(1)” for common attributes). A helper is free to produce a subset, or even no values at all if it has nothing useful to provide. Any provided attributes will overwrite those already known about by Git's credential subsystem. Unrecognised attributes are silently discarded.

While it is possible to override all attributes, well behaving helpers should refrain from doing so for any attribute other than username and password.

If a helper outputs a quit attribute with a value of true or 1, no further helpers will be consulted, nor will the user be prompted (if no credential has been provided, the operation will then fail).

Similarly, no more helpers will be consulted once both username and password had been provided.

For a store or erase operation, the helper's output is ignored.

If a helper fails to perform the requested operation or needs to notify the user of a potential issue, it may write to stderr.

If it does not support the requested operation (e.g., a read-only store or generator), it should silently ignore the request.

If a helper receives any other operation, it should silently ignore the request. This leaves room for future operations to be added (older helpers will just ignore the new requests).

GIT

Part of the the section called “git(1)” suite

gitdiffcore(7)

NAME

gitdiffcore - Tweaking diff output

SYNOPSIS

git diff *

DESCRIPTION

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
  • diffcore-rotate

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 Detecting 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 that when rename detection is on but both copy and break detection are off, rename detection adds a preliminary step that first checks if files are moved across directories while keeping their filename the same. If there is a file added to a directory whose contents are sufficiently similar to a file with the same name that got deleted from a different directory, it will mark them as renames and exclude them from the later quadratic step (the one that pairwise compares all unmatched files to find the "best" matches, determined by the highest content similarity). So, for example, if a deleted docs/ext.txt and an added docs/config/ext.txt are similar enough, they will be marked as a rename and prevent an added docs/ext.md that may be even more similar to the deleted docs/ext.txt from being considered as the rename destination in the later step. For this reason, the preliminary "match same filename" step uses a bit higher threshold to mark a file pair as a rename and stop considering other candidates for better matches. At most, one comparison is done per file in this preliminary pass; so if there are several remaining ext.txt files throughout the directory hierarchy after exact rename detection, this preliminary step may be skipped for those files.

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 a 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 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 the old version prefixed with -, followed by the entire contents of the 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. To speed things up, binary files without textconv filters will be ignored.

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:

README
Makefile
Documentation
*.h
*.c
t

diffcore-rotate: For Changing At Which Path Output Starts

This transformation takes one pathname, and rotates the set of filepairs so that the filepair for the given pathname comes first, optionally discarding the paths that come before it. This is used to implement the --skip-to and the --rotate-to options. It is an error when the specified pathname is not in the set of filepairs, but it is not useful to error out when used with "git log" family of commands, because it is unreasonable to expect that a given path would be modified by each and every commit shown by the "git log" command. For this reason, when used with "git log", the filepair that sorts the same as, or the first one that sorts after, the given pathname is where the output starts.

Use of this transformation combined with diffcore-order will produce unexpected results, as the input to this transformation is likely not sorted when diffcore-order is in effect.

GIT

Part of the the section called “git(1)” suite

gitignore(5)

NAME

gitignore - Specifies intentionally untracked files to ignore

SYNOPSIS

$XDG_CONFIG_HOME/git/ignore, $GIT_DIR/info/exclude, .gitignore

DESCRIPTION

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 (up to the top-level of the working tree), with patterns in the higher level files 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.

PATTERN FORMAT

  • 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".
  • The slash "/" is used as the directory separator. Separators may occur at the beginning, middle or end of the .gitignore search pattern.
  • If there is a separator at the beginning or middle (or both) of the pattern, then the pattern is relative to the directory level of the particular .gitignore file itself. Otherwise the pattern may also match at any level below the .gitignore level.
  • If there is a separator at the end of the pattern then the pattern will only match directories, otherwise the pattern can match both files and directories.
  • For example, a pattern doc/frotz/ matches doc/frotz directory, but not a/doc/frotz directory; however frotz/ matches frotz and a/frotz that is a directory (all paths are relative from the .gitignore file).
  • An asterisk "*" matches anything except a slash. The character "?" matches any one character except "/". The range notation, e.g. [a-zA-Z], can be used to match one of the characters in a range. See fnmatch(3) and the FNM_PATHNAME flag for a more detailed description.
  • A backslash ("\") can be used to escape any character. E.g., "\*" matches a literal asterisk (and "\a" matches "a", even though there is no need for escaping there). As with fnmatch(3), a backslash at the end of a pattern is an invalid pattern that never matches.

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 regular asterisks and will match according to the previous rules.

CONFIGURATION

The optional configuration variable core.excludesFile indicates a path to a file containing patterns of file names to exclude, similar to $GIT_DIR/info/exclude. Patterns in the exclude file are used in addition to those in $GIT_DIR/info/exclude.

NOTES

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 to remove the file from the index. The filename can then be added to the .gitignore file to stop the file from being reintroduced in later commits.

Git does not follow symbolic links when accessing a .gitignore file in the working tree. This keeps behavior consistent when the file is accessed from the index or a tree versus from the filesystem.

EXAMPLES

  • The pattern hello.* matches any file or directory whose name begins with hello.. If one wants to restrict this only to the directory and not in its subdirectories, one can prepend the pattern with a slash, i.e. /hello.*; the pattern now matches hello.txt, hello.c but not a/hello.java.
  • The pattern 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)
  • The pattern doc/frotz and /doc/frotz have the same effect in any .gitignore file. In other words, a leading slash is not relevant if there is already a middle slash in the pattern.
  • The pattern foo/*, matches foo/test.json (a regular file), foo/bar (a directory), but it does not match foo/bar/hello.c (a regular file), as the asterisk in the pattern does not match bar/hello.c which has a slash in it.
    $ 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.
    *.[oa]
    $ cat Documentation/.gitignore
    # ignore generated html files,
    *.html
    # except foo.html which is maintained by hand
    !foo.html
    $ git status
    [...]
    # Untracked files:
    [...]
    #       Documentation/foo.html
    [...]

Another example:

    $ cat .gitignore
    vmlinux*
    $ ls arch/foo/kernel/vm*
    arch/foo/kernel/vmlinux.lds.S
    $ 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
    /*
    !/foo
    /foo/*
    !/foo/bar

GIT

Part of the the section called “git(1)” suite

gitfaq(7)

NAME

gitfaq - Frequently asked questions about using Git

SYNOPSIS

gitfaq

DESCRIPTION

The examples in this FAQ assume a standard POSIX shell, like bash or dash, and a user, A U Thor, who has the account author on the hosting provider git.example.org.

Configuration

What should I put in user.name?

You should put your personal name, generally a form using a given name and family name. For example, the current maintainer of Git uses "Junio C Hamano". This will be the name portion that is stored in every commit you make.

This configuration doesn't have any effect on authenticating to remote services; for that, see credential.username in the section called “git-config(1)”.

What does http.postBuffer really do?

This option changes the size of the buffer that Git uses when pushing data to a remote over HTTP or HTTPS. If the data is larger than this size, libcurl, which handles the HTTP support for Git, will use chunked transfer encoding since it isn't known ahead of time what the size of the pushed data will be.

Leaving this value at the default size is fine unless you know that either the remote server or a proxy in the middle doesn't support HTTP/1.1 (which introduced the chunked transfer encoding) or is known to be broken with chunked data. This is often (erroneously) suggested as a solution for generic push problems, but since almost every server and proxy supports at least HTTP/1.1, raising this value usually doesn't solve most push problems. A server or proxy that didn't correctly support HTTP/1.1 and chunked transfer encoding wouldn't be that useful on the Internet today, since it would break lots of traffic.

Note that increasing this value will increase the memory used on every relevant push that Git does over HTTP or HTTPS, since the entire buffer is allocated regardless of whether or not it is all used. Thus, it's best to leave it at the default unless you are sure you need a different value.

How do I configure a different editor?

If you haven't specified an editor specifically for Git, it will by default use the editor you've configured using the VISUAL or EDITOR environment variables, or if neither is specified, the system default (which is usually vi). Since some people find vi difficult to use or prefer a different editor, it may be desirable to change the editor used.

If you want to configure a general editor for most programs which need one, you can edit your shell configuration (e.g., ~/.bashrc or ~/.zshenv) to contain a line setting the EDITOR or VISUAL environment variable to an appropriate value. For example, if you prefer the editor nano, then you could write the following:

export VISUAL=nano

If you want to configure an editor specifically for Git, you can either set the core.editor configuration value or the GIT_EDITOR environment variable. You can see the section called “git-var(1)” for details on the order in which these options are consulted.

Note that in all cases, the editor value will be passed to the shell, so any arguments containing spaces should be appropriately quoted. Additionally, if your editor normally detaches from the terminal when invoked, you should specify it with an argument that makes it not do that, or else Git will not see any changes. An example of a configuration addressing both of these issues on Windows would be the configuration "C:\Program Files\Vim\gvim.exe" --nofork, which quotes the filename with spaces and specifies the --nofork option to avoid backgrounding the process.

Why not have commit.signoff and other configuration variables?

Git intentionally does not (and will not) provide a configuration variable, such as commit.signoff, to automatically add --signoff by default. The reason is to protect the legal and intentional significance of a sign-off. If there were more automated and widely publicized ways for sign-offs to be appended, it would become easier for someone to argue later that a "Signed-off-by" trailer was just added out of habit or by automation, without the committer's full awareness or intent to certify their agreement with the Developer Certificate of Origin (DCO) or a similar statement. This could undermine the sign-off’s credibility in legal or contractual situations.

There exists format.signoff, but that is a historical mistake, and it is not an excuse to add more mistakes of the same kind on top.

Credentials

How do I specify my credentials when pushing over HTTP?

The easiest way to do this is to use a credential helper via the credential.helper configuration. Most systems provide a standard choice to integrate with the system credential manager. For example, Git for Windows provides the wincred credential manager, macOS has the osxkeychain credential manager, and Unix systems with a standard desktop environment can use the libsecret credential manager. All of these store credentials in an encrypted store to keep your passwords or tokens secure.

In addition, you can use the store credential manager which stores in a file in your home directory, or the cache credential manager, which does not permanently store your credentials, but does prevent you from being prompted for them for a certain period of time.

You can also just enter your password when prompted. While it is possible to place the password (which must be percent-encoded) in the URL, this is not particularly secure and can lead to accidental exposure of credentials, so it is not recommended.

How do I read a password or token from an environment variable?

The credential.helper configuration option can also take an arbitrary shell command that produces the credential protocol on standard output. This is useful when passing credentials into a container, for example.

Such a shell command can be specified by starting the option value with an exclamation point. If your password or token were stored in the GIT_TOKEN, you could run the following command to set your credential helper:

$ git config credential.helper \
        '!f() { echo username=author; echo "password=$GIT_TOKEN"; };f'
How do I change the password or token I've saved in my credential manager?

Usually, if the password or token is invalid, Git will erase it and prompt for a new one. However, there are times when this doesn't always happen. To change the password or token, you can erase the existing credentials and then Git will prompt for new ones. To erase credentials, use a syntax like the following (substituting your username and the hostname):

$ echo url=https://author@git.example.org | git credential reject
How do I use multiple accounts with the same hosting provider using HTTP?
Usually the easiest way to distinguish between these accounts is to use the username in the URL. For example, if you have the accounts author and committer on git.example.org, you can use the URLs https://author@git.example.org/org1/project1.git and https://committer@git.example.org/org2/project2.git. This way, when you use a credential helper, it will automatically try to look up the correct credentials for your account. If you already have a remote set up, you can change the URL with something like git remote set-url origin https://author@git.example.org/org1/project1.git (see the section called “git-remote(1)” for details).
How do I use multiple accounts with the same hosting provider using SSH?

With most hosting providers that support SSH, a single key pair uniquely identifies a user. Therefore, to use multiple accounts, it's necessary to create a key pair for each account. If you're using a reasonably modern OpenSSH version, you can create a new key pair with something like ssh-keygen -t ed25519 -f ~/.ssh/id_committer. You can then register the public key (in this case, ~/.ssh/id_committer.pub; note the .pub) with the hosting provider.

Most hosting providers use a single SSH account for pushing; that is, all users push to the git account (e.g., git@git.example.org). If that's the case for your provider, you can set up multiple aliases in SSH to make it clear which key pair to use. For example, you could write something like the following in ~/.ssh/config, substituting the proper private key file:

# This is the account for author on git.example.org.
Host example_author
        HostName git.example.org
        User git
        # This is the key pair registered for author with git.example.org.
        IdentityFile ~/.ssh/id_author
        IdentitiesOnly yes
# This is the account for committer on git.example.org.
Host example_committer
        HostName git.example.org
        User git
        # This is the key pair registered for committer with git.example.org.
        IdentityFile ~/.ssh/id_committer
        IdentitiesOnly yes

Then, you can adjust your push URL to use git@example_author or git@example_committer instead of git@example.org (e.g., git remote set-url git@example_author:org1/project1.git).

Transfers

How do I sync a working tree across systems?

First, decide whether you want to do this at all. Git works best when you push or pull your work using the typical git push and git fetch commands and isn't designed to share a working tree across systems. This is potentially risky and in some cases can cause repository corruption or data loss.

Usually, doing so will cause git status to need to re-read every file in the working tree. Additionally, Git's security model does not permit sharing a working tree across untrusted users, so it is only safe to sync a working tree if it will only be used by a single user across all machines.

It is important not to use a cloud syncing service to sync any portion of a Git repository, since this can cause corruption, such as missing objects, changed or added files, broken refs, and a wide variety of other problems. These services tend to sync file by file on a continuous basis and don't understand the structure of a Git repository. This is especially bad if they sync the repository in the middle of it being updated, since that is very likely to cause incomplete or partial updates and therefore data loss.

An example of the kind of corruption that can occur is conflicts over the state of refs, such that both sides end up with different commits on a branch that the other doesn't have. This can result in important objects becoming unreferenced and possibly pruned by git gc, causing data loss.

Therefore, it's better to push your work to either the other system or a central server using the normal push and pull mechanism. In Git 2.51, Git learned to import and export stashes, so it's possible to synchronize the state of the working tree by stashing it with git stash, then exporting either all stashes with git stash export --to-ref refs/heads/stashes (assuming you want to export to the stashes branch) or selecting stashes by adding their numbers to the end of that command. It's also possible to include untracked files by using the --include-untracked argument when stashing the data in the first place, but be careful not to do this if any of these contain sensitive information.

You can then push the stashes branch (or whatever branch you've exported to), fetch them to the local system (such as with git fetch origin +stashes:stashes), and import the stashes on the other system with git stash import stashes (again, changing the name as necessary). Applying the changes to the working tree can be done with git stash pop or git stash apply. This is the approach that is most robust and most likely to avoid unintended problems.

Having said that, there are some cases where people nevertheless prefer to share a working tree across systems. If you do this, the recommended approach is to use rsync -a --delete-after (ideally with an encrypted connection such as with ssh) on the root of repository. You should ensure several things when you do this:

  • If you have additional worktrees or a separate Git directory, they must be synced at the same time as the main working tree and repository.
  • You are comfortable with the destination directory being an exact copy of the source directory, deleting any data that is already there.
  • The repository (including all worktrees and the Git directory) is in a quiescent state for the duration of the transfer (that is, no operations of any sort are taking place on it, including background operations like git gc and operations invoked by your editor).

    Be aware that even with these recommendations, syncing working trees in this way has some risk since it bypasses Git's normal integrity checking for repositories, so having backups is advised. You may also wish to do a git fsck to verify the integrity of your data on the destination system after syncing.

Common Issues

I've made a mistake in the last commit. How do I change it?
You can make the appropriate change to your working tree, run git add <file> or git rm <file>, as appropriate, to stage it, and then git commit --amend. Your change will be included in the commit, and you'll be prompted to edit the commit message again; if you wish to use the original message verbatim, you can use the --no-edit option to git commit in addition, or just save and quit when your editor opens.
I've made a change with a bug and it's been included in the main branch. How should I undo it?
The usual way to deal with this is to use git revert. This preserves the history that the original change was made and was a valuable contribution, but also introduces a new commit that undoes those changes because the original had a problem. The commit message of the revert indicates the commit which was reverted and is usually edited to include an explanation as to why the revert was made.
How do I ignore changes to a tracked file?

Git doesn't provide a way to do this. The reason is that if Git needs to overwrite this file, such as during a checkout, it doesn't know whether the changes to the file are precious and should be kept, or whether they are irrelevant and can safely be destroyed. Therefore, it has to take the safe route and always preserve them.

It's tempting to try to use certain features of git update-index, namely the assume-unchanged and skip-worktree bits, but these don't work properly for this purpose and shouldn't be used this way.

If your goal is to modify a configuration file, it can often be helpful to have a file checked into the repository which is a template or set of defaults which can then be copied alongside and modified as appropriate. This second, modified file is usually ignored to prevent accidentally committing it.

I asked Git to ignore various files, yet they are still tracked
A gitignore file ensures that certain file(s) which are not tracked by Git remain untracked. However, sometimes particular file(s) may have been tracked before adding them into the .gitignore, hence they still remain tracked. To untrack and ignore files/patterns, use git rm --cached <file/pattern> and add a pattern to .gitignore that matches the <file>. See the section called “gitignore(5)” for details.
How do I know if I want to do a fetch or a pull?
A fetch stores a copy of the latest changes from the remote repository, without modifying the working tree or current branch. You can then at your leisure inspect, merge, rebase on top of, or ignore the upstream changes. A pull consists of a fetch followed immediately by either a merge or rebase. See the section called “git-pull(1)”.
Can I use a proxy with Git?

Yes, Git supports the use of proxies. Git honors the standard http_proxy, https_proxy, and no_proxy environment variables commonly used on Unix, and it also can be configured with http.proxy and similar options for HTTPS (see the section called “git-config(1)”). The http.proxy and related options can be customized on a per-URL pattern basis. In addition, Git can in theory function normally with transparent proxies that exist on the network.

For SSH, Git can support a proxy using OpenSSH's ProxyCommand. Commonly used tools include netcat and socat. However, they must be configured not to exit when seeing EOF on standard input, which usually means that netcat will require -q and socat will require a timeout with something like -t 10. This is required because the way the Git SSH server knows that no more requests will be made is an EOF on standard input, but when that happens, the server may not have yet processed the final request, so dropping the connection at that point would interrupt that request.

An example configuration entry in ~/.ssh/config with an HTTP proxy might look like this:

Host git.example.org
    User git
    ProxyCommand socat -t 10 - PROXY:proxy.example.org:%h:%p,proxyport=8080

Note that in all cases, for Git to work properly, the proxy must be completely transparent. The proxy cannot modify, tamper with, or buffer the connection in any way, or Git will almost certainly fail to work. Note that many proxies, including many TLS middleboxes, Windows antivirus and firewall programs other than Windows Defender and Windows Firewall, and filtering proxies fail to meet this standard, and as a result end up breaking Git. Because of the many reports of problems and their poor security history, we recommend against the use of these classes of software and devices.

Merging and Rebasing

What kinds of problems can occur when merging long-lived branches with squash merges?

In general, there are a variety of problems that can occur when using squash merges to merge two branches multiple times. These can include seeing extra commits in git log output, with a GUI, or when using the ... notation to express a range, as well as the possibility of needing to re-resolve conflicts again and again.

When Git does a normal merge between two branches, it considers exactly three points: the two branches and a third commit, called the merge base, which is usually the common ancestor of the commits. The result of the merge is the sum of the changes between the merge base and each head. When you merge two branches with a regular merge commit, this results in a new commit which will end up as a merge base when they're merged again, because there is now a new common ancestor. Git doesn't have to consider changes that occurred before the merge base, so you don't have to re-resolve any conflicts you resolved before.

When you perform a squash merge, a merge commit isn't created; instead, the changes from one side are applied as a regular commit to the other side. This means that the merge base for these branches won't have changed, and so when Git goes to perform its next merge, it considers all of the changes that it considered the last time plus the new changes. That means any conflicts may need to be re-resolved. Similarly, anything using the ... notation in git diff, git log, or a GUI will result in showing all of the changes since the original merge base.

As a consequence, if you want to merge two long-lived branches repeatedly, it's best to always use a regular merge commit.

If I make a change on two branches but revert it on one, why does the merge of those branches include the change?

By default, when Git does a merge, it uses a strategy called the ort strategy, which does a fancy three-way merge. In such a case, when Git performs the merge, it considers exactly three points: the two heads and a third point, called the merge base, which is usually the common ancestor of those commits. Git does not consider the history or the individual commits that have happened on those branches at all.

As a result, if both sides have a change and one side has reverted that change, the result is to include the change. This is because the code has changed on one side and there is no net change on the other, and in this scenario, Git adopts the change.

If this is a problem for you, you can do a rebase instead, rebasing the branch with the revert onto the other branch. A rebase in this scenario will revert the change, because a rebase applies each individual commit, including the revert. Note that rebases rewrite history, so you should avoid rebasing published branches unless you're sure you're comfortable with that. See the NOTES section in the section called “git-rebase(1)” for more details.

Hooks

How do I use hooks to prevent users from making certain changes?

The only safe place to make these changes is on the remote repository (i.e., the Git server), usually in the pre-receive hook or in a continuous integration (CI) system. These are the locations in which policy can be enforced effectively.

It's common to try to use pre-commit hooks (or, for commit messages, commit-msg hooks) to check these things, which is great if you're working as a solo developer and want the tooling to help you. However, using hooks on a developer machine is not effective as a policy control because a user can bypass these hooks with --no-verify without being noticed (among various other ways). Git assumes that the user is in control of their local repositories and doesn't try to prevent this or tattle on the user.

In addition, some advanced users find pre-commit hooks to be an impediment to workflows that use temporary commits to stage work in progress or that create fixup commits, so it's better to push these kinds of checks to the server anyway.

Cross-Platform Issues

I'm on Windows and my text files are detected as binary.

Git works best when you store text files as UTF-8. Many programs on Windows support UTF-8, but some do not and only use the little-endian UTF-16 format, which Git detects as binary. If you can't use UTF-8 with your programs, you can specify a working tree encoding that indicates which encoding your files should be checked out with, while still storing these files as UTF-8 in the repository. This allows tools like the section called “git-diff(1)” to work as expected, while still allowing your tools to work.

To do so, you can specify a the section called “gitattributes(5)” pattern with the working-tree-encoding attribute. For example, the following pattern sets all C files to use UTF-16LE-BOM, which is a common encoding on Windows:

*.c     working-tree-encoding=UTF-16LE-BOM

You will need to run git add --renormalize to have this take effect. Note that if you are making these changes on a project that is used across platforms, you'll probably want to make it in a per-user configuration file or in the one in $GIT_DIR/info/attributes, since making it in a .gitattributes file in the repository will apply to all users of the repository.

See the following entry for information about normalizing line endings as well, and see the section called “gitattributes(5)” for more information about attribute files.

I'm on Windows and git diff shows my files as having a ^M at the end.

By default, Git expects files to be stored with Unix line endings. As such, the carriage return (^M) that is part of a Windows line ending is shown because it is considered to be trailing whitespace. Git defaults to showing trailing whitespace only on new lines, not existing ones.

You can store the files in the repository with Unix line endings and convert them automatically to your platform's line endings. To do that, set the configuration option core.eol to native and see the question on recommended storage settings for information about how to configure files as text or binary.

You can also control this behavior with the core.whitespace setting if you don't wish to remove the carriage returns from your line endings.

Why do I have a file that's always modified?

Internally, Git always stores file names as sequences of bytes and doesn't perform any encoding or case folding. However, Windows and macOS by default both perform case folding on file names. As a result, it's possible to end up with multiple files or directories whose names differ only in case. Git can handle this just fine, but the file system can store only one of these files, so when Git reads the other file to see its contents, it looks modified.

It's best to remove one of the files such that you only have one file. You can do this with commands like the following (assuming two files AFile.txt and afile.txt) on an otherwise clean working tree:

$ git rm --cached AFile.txt
$ git commit -m 'Remove files conflicting in case'
$ git checkout .

This avoids touching the disk, but removes the additional file. Your project may prefer to adopt a naming convention, such as all-lowercase names, to avoid this problem from occurring again; such a convention can be checked using a pre-receive hook or as part of a continuous integration (CI) system.

It is also possible for perpetually modified files to occur on any platform if a smudge or clean filter is in use on your system but a file was previously committed without running the smudge or clean filter. To fix this, run the following on an otherwise clean working tree:

$ git add --renormalize .
What's the recommended way to store files in Git?

While Git can store and handle any file of any type, there are some settings that work better than others. In general, we recommend that text files be stored in UTF-8 without a byte-order mark (BOM) with LF (Unix-style) endings. We also recommend the use of UTF-8 (again, without BOM) in commit messages. These are the settings that work best across platforms and with tools such as git diff and git merge.

Additionally, if you have a choice between storage formats that are text based or non-text based, we recommend storing files in the text format and, if necessary, transforming them into the other format. For example, a text-based SQL dump with one record per line will work much better for diffing and merging than an actual database file. Similarly, text-based formats such as Markdown and AsciiDoc will work better than binary formats such as Microsoft Word and PDF.

Similarly, storing binary dependencies (e.g., shared libraries or JAR files) or build products in the repository is generally not recommended. Dependencies and build products are best stored on an artifact or package server with only references, URLs, and hashes stored in the repository.

We also recommend setting a the section called “gitattributes(5)” file to explicitly mark which files are text and which are binary. If you want Git to guess, you can set the attribute text=auto.

With text files, Git will generally ensure that LF endings are used in the repository. The core.autocrlf and core.eol configuration variables specify what line-ending convention is followed when any text file is checked out. You can also use the eol attribute (e.g., eol=crlf) to override which files get what line-ending treatment.

For example, generally shell files must have LF endings and batch files must have CRLF endings, so the following might be appropriate in some projects:

# By default, guess.
*       text=auto
# Mark all C files as text.
*.c     text
# Ensure all shell files have LF endings and all batch files have CRLF
# endings in the working tree and both have LF in the repo.
*.sh text eol=lf
*.bat text eol=crlf
# Mark all JPEG files as binary.
*.jpg   binary

These settings help tools pick the right format for output such as patches and result in files being checked out in the appropriate line ending for the platform.

GIT

Part of the the section called “git(1)” suite

githooks(5)

NAME

githooks - Hooks used by Git

SYNOPSIS

$GIT_DIR/hooks/* (or `git config core.hooksPath`/*)

DESCRIPTION

Hooks are programs you can place in a hooks directory to trigger actions at certain points in git's execution. Hooks that don't have the executable bit set are ignored.

By default the hooks directory is $GIT_DIR/hooks, but that can be changed via the core.hooksPath configuration variable (see the section called “git-config(1)”).

Before Git invokes a hook, it changes its working directory to either $GIT_DIR in a bare repository or the root of the working tree in a non-bare repository. An exception are hooks triggered during a push (pre-receive, update, post-receive, post-update, push-to-checkout) which are always executed in $GIT_DIR.

Environment variables, such as GIT_DIR, GIT_WORK_TREE, etc., are exported so that Git commands run by the hook can correctly locate the repository. If your hook needs to invoke Git commands in a foreign repository or in a different working tree of the same repository, then it should clear these environment variables so they do not interfere with Git operations at the foreign location. For example:

local_desc=$(git describe)
foreign_desc=$(unset $(git rev-parse --local-env-vars); git -C ../foreign-repo describe)

Hooks can get their arguments via the environment, command-line arguments, and stdin. See the documentation for each hook below for details.

git init may copy hooks to the new repository, depending on its configuration. See the "TEMPLATE DIRECTORY" section in the section called “git-init(1)” for details. When the rest of this document refers to "default hooks" it's talking about the default template shipped with Git.

The currently supported hooks are described below.

HOOKS

applypatch-msg

This hook is invoked by the section called “git-am(1)”. It takes a single parameter, the name of the file that holds the proposed commit log message. Exiting with a 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. 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.

pre-applypatch

This hook is invoked by the section called “git-am(1)”. 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 tests.

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

post-applypatch

This hook is invoked by the section called “git-am(1)”. 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.

pre-commit

This hook is invoked by the section called “git-commit(1)”, and can be bypassed with the --no-verify option. It takes no parameters, and is invoked before obtaining the proposed commit log message and making a commit. Exiting with a non-zero status from this script causes the git commit command to abort before creating a commit.

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.

The default pre-commit hook, when enabled, prevents the introduction of non-ASCII filenames and lines with trailing whitespace. The non-ASCII check can be turned off by setting the hooks.allownonascii config option to true.

pre-merge-commit

This hook is invoked by the section called “git-merge(1)”, and can be bypassed with the --no-verify option. It takes no parameters, and is invoked after the merge has been carried out successfully and before obtaining the proposed commit log message to make a commit. Exiting with a non-zero status from this script causes the git merge command to abort before creating a commit.

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

This hook is invoked with the environment variable GIT_EDITOR=: if the command will not bring up an editor to modify the commit message.

If the merge cannot be carried out automatically, the conflicts need to be resolved and the result committed separately (see the section called “git-merge(1)”). At that point, this hook will not be executed, but the pre-commit hook will, if it is enabled.

prepare-commit-msg

This hook is invoked by the section called “git-commit(1)” 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 object name (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 a replacement for the pre-commit hook.

The sample prepare-commit-msg hook that comes with Git removes the help message found in the commented portion of the commit template.

commit-msg

This hook is invoked by the section called “git-commit(1)” and the section called “git-merge(1)”, and can be bypassed with the --no-verify option. It takes a single parameter, the name of the file that holds the proposed commit log message. Exiting with a non-zero status causes the command 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. 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 trailers, and aborts the commit if one is found.

post-commit

This hook is invoked by the section called “git-commit(1)”. It takes no parameters, and is invoked after a commit is made.

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

pre-rebase

This hook is called by the section called “git-rebase(1)” 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.

post-checkout

This hook is invoked when a the section called “git-checkout(1)” or the section called “git-switch(1)” 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 switch or git checkout, other than that the hook's exit status becomes the exit status of these two commands.

It is also run after the section called “git-clone(1)”, 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. Likewise for git worktree add unless --no-checkout is used.

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.

post-merge

This hook is invoked by the section called “git-merge(1)”, 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.

pre-push

This hook is called by the section called “git-push(1)” 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-object-name> SP <remote-ref> SP <remote-object-name> 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 object name would be supplied. If the foreign ref does not yet exist the <remote-object-name> will be the all-zeroes object name. If a ref is to be deleted, the <local-ref> will be supplied as (delete) and the <local-object-name> will be the all-zeroes object name. If the local commit was specified by something other than a name which could be expanded (such as HEAD~, or an object name) 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.

pre-receive

This hook is invoked by the section called “git-receive-pack(1)” when it reacts to git push and updates reference(s) in its 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-oid> SP <new-oid> SP <ref-name> LF

where <old-oid> is the old object name stored in the ref, <new-oid> 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-oid> is the all-zeroes object name.

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.

The number of push options given on the command line of git push --push-option=... can be read from the environment variable GIT_PUSH_OPTION_COUNT, and the options themselves are found in GIT_PUSH_OPTION_0, GIT_PUSH_OPTION_1,… If it is negotiated to not use the push options phase, the environment variables will not be set. If the client selects to use push options, but doesn't transmit any, the count variable will be set to zero, GIT_PUSH_OPTION_COUNT=0.

See the section on "Quarantine Environment" in the section called “git-receive-pack(1)” for some caveats.

update

This hook is invoked by the section called “git-receive-pack(1)” when it reacts to git push and updates reference(s) in its 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.

In an environment that restricts the users' access only to git commands over the wire, this hook can be used to implement access control without relying on filesystem ownership and group membership. See the section called “git-shell(1)” for how you might use the login shell to restrict the user's access to only git commands.

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 from being pushed.

proc-receive

This hook is invoked by the section called “git-receive-pack(1)”. If the server has set the multi-valued config variable receive.procReceiveRefs, and the commands sent to receive-pack have matching reference names, these commands will be executed by this hook, instead of by the internal execute_commands() function. This hook is responsible for updating the relevant references and reporting the results back to receive-pack.

This hook executes once for the receive operation. It takes no arguments, but uses a pkt-line format protocol to communicate with receive-pack to read commands, push-options and send results. In the following example for the protocol, the letter S stands for receive-pack and the letter H stands for this hook.

# Version and features negotiation.
S: PKT-LINE(version=1\0push-options atomic...)
S: flush-pkt
H: PKT-LINE(version=1\0push-options...)
H: flush-pkt
# Send commands from server to the hook.
S: PKT-LINE(<old-oid> <new-oid> <ref>)
S: ... ...
S: flush-pkt
# Send push-options only if the 'push-options' feature is enabled.
S: PKT-LINE(push-option)
S: ... ...
S: flush-pkt
# Receive results from the hook.
# OK, run this command successfully.
H: PKT-LINE(ok <ref>)
# NO, I reject it.
H: PKT-LINE(ng <ref> <reason>)
# Fall through, let 'receive-pack' execute it.
H: PKT-LINE(ok <ref>)
H: PKT-LINE(option fall-through)
# OK, but has an alternate reference.  The alternate reference name
# and other status can be given in option directives.
H: PKT-LINE(ok <ref>)
H: PKT-LINE(option refname <refname>)
H: PKT-LINE(option old-oid <old-oid>)
H: PKT-LINE(option new-oid <new-oid>)
H: PKT-LINE(option forced-update)
H: ... ...
H: flush-pkt

Each command for the proc-receive hook may point to a pseudo-reference and always has a zero-old as its old-oid, while the proc-receive hook may update an alternate reference and the alternate reference may exist already with a non-zero old-oid. For this case, this hook will use "option" directives to report extended attributes for the reference given by the leading "ok" directive.

The report of the commands of this hook should have the same order as the input. The exit status of the proc-receive hook only determines the success or failure of the group of commands sent to it, unless atomic push is in use.

post-receive

This hook is invoked by the section called “git-receive-pack(1)” when it reacts to git push and updates reference(s) in its repository. The hook executes on the remote repository once after all the proposed ref updates are processed and if at least one ref is updated as the result.

The hook takes no arguments. It receives one line on standard input for each ref that is successfully updated following the same format as the pre-receive hook.

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.

The number of push options given on the command line of git push --push-option=... can be read from the environment variable GIT_PUSH_OPTION_COUNT, and the options themselves are found in GIT_PUSH_OPTION_0, GIT_PUSH_OPTION_1,… If it is negotiated to not use the push options phase, the environment variables will not be set. If the client selects to use push options, but doesn't transmit any, the count variable will be set to zero, GIT_PUSH_OPTION_COUNT=0.

See the "post-receive" section in the section called “git-receive-pack(1)” for additional details.

post-update

This hook is invoked by the section called “git-receive-pack(1)” when it reacts to git push and updates reference(s) in its 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.

reference-transaction

This hook is invoked by any Git command that performs reference updates. It executes whenever a reference transaction is prepared, committed or aborted and may thus get called multiple times. The hook also supports symbolic reference updates.

The hook takes exactly one argument, which is the current state the given reference transaction is in:

  • "prepared": All reference updates have been queued to the transaction and references were locked on disk.
  • "committed": The reference transaction was committed and all references now have their respective new value.
  • "aborted": The reference transaction was aborted, no changes were performed and the locks have been released.

For each reference update that was added to the transaction, the hook 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 passed into the reference transaction, <new-value> is the new object name to be stored in the ref and <ref-name> is the full name of the ref. When force updating the reference regardless of its current value or when the reference is to be created anew, <old-value> is the all-zeroes object name. To distinguish these cases, you can inspect the current value of <ref-name> via git rev-parse.

For symbolic reference updates the <old_value> and <new-value> fields could denote references instead of objects. A reference will be denoted with a ref: prefix, like ref:<ref-target>.

The exit status of the hook is ignored for any state except for the "prepared" state. In the "prepared" state, a non-zero exit status will cause the transaction to be aborted. The hook will not be called with "aborted" state in that case.

push-to-checkout

This hook is invoked by the section called “git-receive-pack(1)” when it reacts to git push and updates reference(s) in its repository, and 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 git read-tree -u -m is essentially the same as git switch or git checkout that switches branches while keeping the local changes in the working tree that do not interfere with the difference between the branches.

pre-auto-gc

This hook is invoked by git gc --auto (see the section called “git-gc(1)”). It takes no parameter, and exiting with non-zero status from this script causes the git gc --auto to abort.

post-rewrite

This hook is invoked by commands that rewrite commits (the section called “git-commit(1)” when called with --amend and the section called “git-rebase(1)”; however, full-history (re)writing tools like the section called “git-fast-import(1)” or git-filter-repo typically do 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-object-name> SP <new-object-name> [ 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 the section called “git-config(1)”) has happened, and thus has access to these notes.

The following command-specific comments apply:

rebase

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-object-name.

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

sendemail-validate

This hook is invoked by the section called “git-send-email(1)”.

It takes these command line arguments. They are, 1. the name of the file which holds the contents of the email to be sent. 2. The name of the file which holds the SMTP headers of the email.

The SMTP headers are passed in the exact same way as they are passed to the user's Mail Transport Agent (MTA). In effect, the email given to the user's MTA, is the contents of $2 followed by the contents of $1.

An example of a few common headers is shown below. Take notice of the capitalization and multi-line tab structure.

From: Example <from@example.com>
To: to@example.com
Cc: cc@example.com,
        A <author@example.com>,
        One <one@example.com>,
        two@example.com
Subject: PATCH-STRING

Exiting with a non-zero status causes git send-email to abort before sending any e-mails.

The following environment variables are set when executing the hook.

GIT_SENDEMAIL_FILE_COUNTER
A 1-based counter incremented by one for every file holding an e-mail to be sent (excluding any FIFOs). This counter does not follow the patch series counter scheme. It will always start at 1 and will end at GIT_SENDEMAIL_FILE_TOTAL.
GIT_SENDEMAIL_FILE_TOTAL
The total number of files that will be sent (excluding any FIFOs). This counter does not follow the patch series counter scheme. It will always be equal to the number of files being sent, whether there is a cover letter or not.

These variables may for instance be used to validate patch series.

The sample sendemail-validate hook that comes with Git checks that all sent patches (excluding the cover letter) can be applied on top of the upstream repository default branch without conflicts. Some placeholders are left for additional validation steps to be performed after all patches of a given series have been applied.

fsmonitor-watchman

This hook is invoked when the configuration option core.fsmonitor is set to .git/hooks/fsmonitor-watchman or .git/hooks/fsmonitor-watchmanv2 depending on the version of the hook to use.

Version 1 takes two arguments, a version (1) and the time in elapsed nanoseconds since midnight, January 1, 1970.

Version 2 takes two arguments, a version (2) and a token that is used for identifying changes since the token. For watchman this would be a clock id. This version must output to stdout the new token followed by a NUL before the list of files.

The hook should output to stdout the list of all files in the working directory that may have changed since the requested time. The logic should be inclusive so that it does not miss any potential changes. The paths should be relative to the root of the working directory and be separated by a single NUL.

It is OK to include files which have not actually changed. All changes including newly-created and deleted files should be included. When files are renamed, both the old and the new name should be included.

Git will limit what files it checks for changes as well as which directories are checked for untracked files based on the path names given.

An optimized way to tell git "all files have changed" is to return the filename /.

The exit status determines whether git will use the data from the hook to limit its search. On error, it will fall back to verifying all files and folders.

p4-changelist

This hook is invoked by git-p4 submit.

The p4-changelist hook is executed after the changelist message has been edited by the user. It can be bypassed with the --no-verify option. It takes a single parameter, the name of the file that holds the proposed changelist text. Exiting with a non-zero status causes the command to abort.

The hook is allowed to edit the changelist file and can be used to normalize the text into some project standard format. It can also be used to refuse the Submit after inspect the message file.

Run git-p4 submit --help for details.

p4-prepare-changelist

This hook is invoked by git-p4 submit.

The p4-prepare-changelist hook is executed right after preparing the default changelist message and before the editor is started. It takes one parameter, the name of the file that contains the changelist text. Exiting with a non-zero status from the script will abort the process.

The purpose of the hook is to edit the message file in place, and it is not suppressed by the --no-verify option. This hook is called even if --prepare-p4-only is set.

Run git-p4 submit --help for details.

p4-post-changelist

This hook is invoked by git-p4 submit.

The p4-post-changelist hook is invoked after the submit has successfully occurred in P4. It takes no parameters and is meant primarily for notification and cannot affect the outcome of the git p4 submit action.

Run git-p4 submit --help for details.

p4-pre-submit

This hook is invoked by git-p4 submit. It takes no parameters and nothing from standard input. Exiting with non-zero status from this script prevent git-p4 submit from launching. It can be bypassed with the --no-verify command line option. Run git-p4 submit --help for details.

post-index-change

This hook is invoked when the index is written in read-cache.c do_write_locked_index.

The first parameter passed to the hook is the indicator for the working directory being updated. "1" meaning working directory was updated or "0" when the working directory was not updated.

The second parameter passed to the hook is the indicator for whether or not the index was updated and the skip-worktree bit could have changed. "1" meaning skip-worktree bits could have been updated and "0" meaning they were not.

Only one parameter should be set to "1" when the hook runs. The hook running passing "1", "1" should not be possible.

GIT

Part of the the section called “git(1)” suite

gitk(1)

NAME

gitk - The Git repository browser

SYNOPSIS

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

DESCRIPTION

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.

OPTIONS

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 stuck form (see the section called “gitcli(7)”) due to limitations in the command-line parser.

rev-list options and arguments

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

--all
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.
--since=<date>
Show commits more recent than a specific date.
--until=<date>
Show commits older than a specific date.
--date-order
Sort commits by date when possible.
--merge
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.
--left-right
Mark which side of a symmetric difference a commit is reachable from. Commits from the left side are prefixed with a < symbol and those from the right with a > symbol.
--full-history
When filtering history with <path>…, does not prune some history. (See "History simplification" in the section called “git-log(1)” for a more detailed explanation.)
--simplify-merges
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 the section called “git-log(1)” for a more detailed explanation.)
--ancestry-path
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 the section called “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 by 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, and <start> and <end> (or <funcname>) must exist in the starting revision. You can specify this option more than once. Implies --patch. Patch output can be suppressed using --no-patch, but other diff formats (namely --raw, --numstat, --shortstat, --dirstat, --summary, --name-only, --name-status, --check) are not currently implemented.

<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. The function names are determined in the same way as git diff works out patch hunk headers (see Defining a custom hunk-header in the section called “gitattributes(5)”).

<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 the section called “gitrevisions(7)”.
<path>…
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.

gitk-specific options

--argscmd=<command>
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-commit=<ref>
Select the specified commit after loading the graph. Default behavior is equivalent to specifying --select-commit=HEAD.

Examples

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.

Files

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.

History

Gitk was the first graphical repository browser, written by Paul Mackerras in Tcl/Tk.

gitk is actually maintained as an independent project, but stable versions are distributed as part of the Git suite for the convenience of end users.

gitk-git/ comes from Johannes Sixt's gitk project:

https://github.com/j6t/gitk

SEE ALSO

qgit(1)
A repository browser written in C++ using Qt.
tig(1)
A minimal repository browser and Git tool output highlighter written in C using Ncurses.

GIT

Part of the the section called “git(1)” suite

gitmailmap(5)

NAME

gitmailmap - Map author/committer names and/or E-Mail addresses

SYNOPSIS

$GIT_WORK_TREE/.mailmap

DESCRIPTION

If the file .mailmap exists at the toplevel of the repository, or at the location pointed to by the mailmap.file or mailmap.blob configuration options (see the section called “git-config(1)”), it is used to map author and committer names and email addresses to canonical real names and email addresses.

SYNTAX

The # character begins a comment to the end of line, blank lines are ignored.

In the simple form, each line in the file consists of the canonical real name of an author, whitespace, and an email address used in the commit (enclosed by < and >) to map to the name. For example:

Proper Name <commit@email.xx>

The more complex forms are:

<proper@email.xx> <commit@email.xx>

which allows mailmap to replace only the email part of a commit, and:

Proper Name <proper@email.xx> <commit@email.xx>

which allows mailmap to replace both the name and the email of a commit matching the specified commit email address, and:

Proper Name <proper@email.xx> Commit Name <commit@email.xx>

which allows mailmap to replace both the name and the email of a commit matching both the specified commit name and email address.

Both E-Mails and names are matched case-insensitively. For example this would also match the Commit Name <commit@email.xx> above:

Proper Name <proper@email.xx> CoMmIt NaMe <CoMmIt@EmAiL.xX>

NOTES

Git does not follow symbolic links when accessing a .mailmap file in the working tree. This keeps behavior consistent when the file is accessed from the index or a tree versus from the filesystem.

EXAMPLES

Your history contains commits by two authors, Jane and Joe, whose names appear in the repository under several forms:

Joe Developer <joe@example.com>
Joe R. Developer <joe@example.com>
Jane Doe <jane@example.com>
Jane Doe <jane@laptop.(none)>
Jane D. <jane@desktop.(none)>

Now suppose that Joe wants his middle name initial used, and Jane prefers her family name fully spelled out. A .mailmap file to correct the names would look like:

Joe R. Developer <joe@example.com>
Jane Doe <jane@example.com>
Jane Doe <jane@desktop.(none)>

Note that there's no need to map the name for <jane@laptop.(none)> to only correct the names. However, leaving the obviously broken <jane@laptop.(none)> and <jane@desktop.(none)> E-Mails as-is is usually not what you want. A .mailmap file which also corrects those is:

Joe R. Developer <joe@example.com>
Jane Doe <jane@example.com> <jane@laptop.(none)>
Jane Doe <jane@example.com> <jane@desktop.(none)>

Finally, let's say that Joe and Jane shared an E-Mail address, but not a name, e.g. by having these two commits in the history generated by a bug reporting system. I.e. names appearing in history as:

Joe <bugs@example.com>
Jane <bugs@example.com>

A full .mailmap file which also handles those cases (an addition of two lines to the above example) would be:

Joe R. Developer <joe@example.com>
Jane Doe <jane@example.com> <jane@laptop.(none)>
Jane Doe <jane@example.com> <jane@desktop.(none)>
Joe R. Developer <joe@example.com> Joe <bugs@example.com>
Jane Doe <jane@example.com> Jane <bugs@example.com>

GIT

Part of the the section called “git(1)” suite

gitmodules(5)

NAME

gitmodules - Defining submodule properties

SYNOPSIS

$GIT_WORK_TREE/.gitmodules

DESCRIPTION

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 the section called “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:

submodule.<name>.path
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.
submodule.<name>.url
Defines a URL from which the submodule repository can be cloned. This may be either an absolute URL ready to be passed to the section called “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:

submodule.<name>.update
Defines the default update procedure for the named submodule, i.e. how the submodule is updated by the 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, but not !command (for security reasons). See the description of the update command in the section called “git-submodule(1)” for more details.
submodule.<name>.branch
A remote branch name for tracking updates in the upstream submodule. If the option is not specified, it defaults to the remote HEAD. A special value of . is used to indicate that the name of the branch in the submodule should be the same name as the current branch in the current repository. See the --remote documentation in the section called “git-submodule(1)” for details.
submodule.<name>.fetchRecurseSubmodules
This option can be used to control recursive fetching of this submodule. If this option is also present in the submodule's 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.
submodule.<name>.ignore

Defines under what circumstances git status and the diff family show a submodule as modified. The following values are supported:

all
The submodule will never be considered modified (but will nonetheless show up in the output of status and commit when it has been staged).
dirty
All changes to the submodule's work tree will be ignored, only committed differences between the HEAD of the submodule and its recorded state in the superproject are taken into account.
untracked
Only untracked files in submodules will be ignored. Committed differences and modifications to tracked files will show up.
none
No modifications to submodules are ignored, all of committed differences, and modifications to tracked and untracked files are shown. This is the default option.

If this option is also present in the submodule's 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-submodules option. The git submodule commands are not affected by this setting.

submodule.<name>.shallow
When set to true, a clone of this submodule will be performed as a shallow clone (with a history depth of 1) unless the user explicitly asks for a non-shallow clone.

NOTES

Git does not allow the .gitmodules file within a working tree to be a symbolic link, and will refuse to check out such a tree entry. This keeps behavior consistent when the file is accessed from the index or a tree versus from the filesystem, and helps Git reliably enforce security checks of the file contents.

EXAMPLES

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.

GIT

Part of the the section called “git(1)” suite

gitnamespaces(7)

NAME

gitnamespaces - Git namespaces

SYNOPSIS

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

DESCRIPTION

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 the section called “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 the section called “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.

the section called “git-upload-pack(1)” and the section called “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, the section called “git-http-backend(1)”, will pass GIT_NAMESPACE through to the backend programs; see the section called “git-http-backend(1)” for sample configuration to expose repository namespaces as repositories.

For a simple local test, you can use the section called “git-remote-ext(1)”:

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

SECURITY

The fetch and push protocols are not designed to prevent one side from stealing data from the other repository that was not intended to be shared. If you have private data that you need to protect from a malicious peer, your best option is to store it in another repository. This applies to both clients and servers. In particular, namespaces on a server are not effective for read access control; you should only grant read access to a namespace to clients that you would trust with read access to the entire repository.

The known attack vectors are as follows:

  1. The victim sends "have" lines advertising the IDs of objects it has that are not explicitly intended to be shared but can be used to optimize the transfer if the peer also has them. The attacker chooses an object ID X to steal and sends a ref to X, but isn't required to send the content of X because the victim already has it. Now the victim believes that the attacker has X, and it sends the content of X back to the attacker later. (This attack is most straightforward for a client to perform on a server, by creating a ref to X in the namespace the client has access to and then fetching it. The most likely way for a server to perform it on a client is to "merge" X into a public branch and hope that the user does additional work on this branch and pushes it back to the server without noticing the merge.)
  2. As in #1, the attacker chooses an object ID X to steal. The victim sends an object Y that the attacker already has, and the attacker falsely claims to have X and not Y, so the victim sends Y as a delta against X. The delta reveals regions of X that are similar to Y to the attacker.

GIT

Part of the the section called “git(1)” suite

gitremote-helpers(7)

NAME

gitremote-helpers - Helper programs to interact with remote repositories

SYNOPSIS

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

DESCRIPTION

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.

INVOCATION

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.

INPUT FORMAT

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.

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.

Capabilities for Pushing

connect

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.

stateless-connect

Experimental; for internal use only. Can attempt to connect to a remote server for communication using git's wire-protocol version 2. See the documentation for the stateless-connect command for more information.

Supported commands: stateless-connect.

push

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.

export

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.

no-private-update
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.

Capabilities for Fetching

connect

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.

stateless-connect

Experimental; for internal use only. Can attempt to connect to a remote server for communication using git's wire-protocol version 2. See the documentation for the stateless-connect command for more information.

Supported commands: stateless-connect.

fetch

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

Supported commands: list, fetch.

import

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

Supported commands: list, import.

check-connectivity
Can guarantee that when a clone is requested, the received pack is self contained and is connected.
get
Can use the get command to download a file from a given URI.

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.

Miscellaneous capabilities

option
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.

bidi-import
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 the section called “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 the section called “git-fast-export(1)”.
signed-tags
This modifies the export capability, instructing Git to pass --signed-tags=verbatim to the section called “git-fast-export(1)”. In the absence of this capability, Git will use --signed-tags=warn-strip.
object-format
This indicates that the helper is able to interact with the remote side using an explicit hash algorithm extension.

COMMANDS

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

capabilities

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.

list

Lists the refs, one per line, in the format "<value> <name> [<attr> …]". The value may be a hex sha1 hash, "@<dest>" for a symref, ":<keyword> <value>" for a key-value pair, 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. See REF LIST KEYWORDS for a list of currently defined keywords.

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 the full path of a file under $GIT_DIR/objects/pack which is keeping a pack until refs can be suitably updated. The path must end with .keep. This is a mechanism to name a <pack,idx,keep> tuple by giving only the keep component. The kept pack will not be deleted by a concurrent repack, even though its objects may not be referenced until the fetch completes. The .keep file will be deleted at the conclusion of the fetch.

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
\n
push +refs/heads/foo:refs/heads/bar
\n

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.

export

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.

stateless-connect <service>

Experimental; for internal use only. Connects to the given remote service for communication using git's wire-protocol version 2. 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 the service starts. Messages (both request and response) must consist of zero or more PKT-LINEs, terminating in a flush packet. Response messages will then have a response end packet after the flush packet to indicate the end of a response. The client must not expect the server to store any state in between request-response pairs. After the connection ends, the remote helper exits.

Supported if the helper has the "stateless-connect" capability.

get <uri> <path>
Downloads the file from the given <uri> to the given <path>. If <path>.temp exists, then Git assumes that the .temp file is a partial download from a previous attempt and will resume the download from that position.

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.

REF LIST ATTRIBUTES

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.

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

REF LIST KEYWORDS

The list command may produce a list of key-value pairs. The following keys are defined.

object-format
The refs are using the given hash algorithm. This keyword is only used if the server and client both support the object-format extension.

OPTIONS

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 deepen-since <timestamp>
Deepens the history of a shallow repository based on time.
option deepen-not <ref>
Deepens the history of a shallow repository excluding ref. Multiple options add up.
option deepen-relative {true|false}
Deepens the history of a shallow repository relative to current boundary. Only valid when used with "option depth".
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.
option push-option <string>
Transmit <string> as a push option. As the push option must not contain LF or NUL characters, the string is not encoded.
option from-promisor {true|false}
Indicate that these objects are being fetched from a promisor.
option no-dependents {true|false}
Indicate that only the objects wanted need to be fetched, not their dependents.
option atomic {true|false}
When pushing, request the remote server to update refs in a single atomic transaction. If successful, all refs will be updated, or none will. If the remote side does not support this capability, the push will fail.
option object-format true
Indicate that the caller wants hash algorithm information to be passed back from the remote. This mode is used when fetching refs.

GIT

Part of the the section called “git(1)” suite

gitrepository-layout(5)

NAME

gitrepository-layout - Git Repository Layout

SYNOPSIS

$GIT_DIR/*

DESCRIPTION

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 called a gitfile and is usually managed via the git submodule and git worktree commands. It 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.

objects

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 the section called “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.

objects/[0-9a-f][0-9a-f]
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.
objects/pack
Packs (files that store many objects in compressed form, along with index files to allow them to be randomly accessed) are found in this directory.
objects/info
Additional information about the object store is recorded in this directory.
objects/info/packs
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.
objects/info/alternates
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.
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.
refs
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 (except refs/bisect, refs/rewritten and refs/worktree) if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/refs" will be used instead.
refs/heads/name
records tip-of-the-tree commit objects of branch name
refs/tags/name
records any object name (not necessarily a commit object, or a tag object that points at a commit object).
refs/remotes/name
records tip-of-the-tree commit objects of branches copied from a remote repository.
refs/replace/<obj-sha1>
records the SHA-1 of the object that replaces <obj-sha1>. This is similar to info/grafts and is internally used and maintained by the section called “git-replace(1)”. Such refs can be exchanged between repositories while grafts are not.
packed-refs
records the same information as refs/heads/, refs/tags/, and friends record in a more efficient way. See the section called “git-pack-refs(1)”. This file is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/packed-refs" will be used instead.
HEAD

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 the section called “git-checkout(1)” for details.

config
Repository specific configuration file. This file is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/config" will be used instead.
config.worktree
Working directory specific configuration file for the main working directory in multiple working directory setup (see the section called “git-worktree(1)”).
branches

A 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 the section called “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.

Git will stop reading remotes from this directory in Git 3.0.

hooks
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 the section called “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.
common
When multiple working trees are used, most of files in $GIT_DIR are per-worktree with a few known exceptions. All files under common however will be shared between all working trees.
index
The current index file for the repository. It is usually not found in a bare repository.
sharedindex.<SHA-1>
The shared index part, to be referenced by $GIT_DIR/index and other temporary index files. Only valid in split index mode.
info
Additional information about the repository is recorded in this directory. This directory is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/info" will be used instead.
info/refs
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.
info/grafts

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 the section called “git-replace(1)” for a more flexible and robust system to do the same thing.

info/exclude
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: the section called “gitignore(5)”.
info/attributes
Defines which attributes to assign to a path, similar to per-directory .gitattributes files. See also: the section called “gitattributes(5)”.
info/sparse-checkout
This file stores sparse checkout patterns. See also: the section called “git-read-tree(1)”.
remotes

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 the section called “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.

Git will stop reading remotes from this directory in Git 3.0.

logs
Records of changes made to refs are stored in this directory. See the section called “git-update-ref(1)” for more information. This directory is ignored (except logs/HEAD) if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/logs" will be used instead.
logs/refs/heads/name
Records all changes made to the branch tip named name.
logs/refs/tags/name
Records all changes made to the tag named name.
shallow
This is similar to info/grafts but is internally used and maintained by shallow clone mechanism. See --depth option to the section called “git-clone(1)” and the section called “git-fetch(1)”. This file is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/shallow" will be used instead.
commondir
If this file exists, $GIT_COMMON_DIR (see the section called “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".
modules
Contains the git-repositories of the submodules.
worktrees
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.
worktrees/<id>/gitdir
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.
worktrees/<id>/locked
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.
worktrees/<id>/config.worktree
Working directory specific configuration file.

Git Repository Format Versions

Every git repository is marked with a numeric version in the core.repositoryformatversion key of its config file. This version specifies the rules for operating on the on-disk repository data. An implementation of git which does not understand a particular version advertised by an on-disk repository MUST NOT operate on that repository; doing so risks not only producing wrong results, but actually losing data.

Because of this rule, version bumps should be kept to an absolute minimum. Instead, we generally prefer these strategies:

  • bumping format version numbers of individual data files (e.g., index, packfiles, etc). This restricts the incompatibilities only to those files.
  • introducing new data that gracefully degrades when used by older clients (e.g., pack bitmap files are ignored by older clients, which simply do not take advantage of the optimization they provide).

A whole-repository format version bump should only be part of a change that cannot be independently versioned. For instance, if one were to change the reachability rules for objects, or the rules for locking refs, that would require a bump of the repository format version.

Note that this applies only to accessing the repository's disk contents directly. An older client which understands only format 0 may still connect via git:// to a repository using format 1, as long as the server process understands format 1.

The preferred strategy for rolling out a version bump (whether whole repository or for a single file) is to teach git to read the new format, and allow writing the new format with a config switch or command line option (for experimentation or for those who do not care about backwards compatibility with older gits). Then after a long period to allow the reading capability to become common, we may switch to writing the new format by default.

The currently defined format versions are:

Version 0

This is the format defined by the initial version of git, including but not limited to the format of the repository directory, the repository configuration file, and the object and ref storage. Specifying the complete behavior of git is beyond the scope of this document.

Version 1

This format is identical to version 0, with the following exceptions:

  1. When reading the core.repositoryformatversion variable, a git implementation which supports version 1 MUST also read any configuration keys found in the extensions section of the configuration file.
  2. If a version-1 repository specifies any extensions.* keys that the running git has not implemented, the operation MUST NOT proceed. Similarly, if the value of any known key is not understood by the implementation, the operation MUST NOT proceed.

Note that if no extensions are specified in the config file, then core.repositoryformatversion SHOULD be set to 0 (setting it to 1 provides no benefit, and makes the repository incompatible with older implementations of git).

The defined extensions are given in the extensions.* section of the section called “git-config(1)”. Any implementation wishing to define a new extension should make a note of it there, in order to claim the name.

GIT

Part of the the section called “git(1)” suite

gitrevisions(7)

NAME

gitrevisions - Specifying revisions and ranges for Git

SYNOPSIS

gitrevisions

DESCRIPTION

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 the section called “git-log(1)”), all commits which are reachable from that commit. For commands that walk the revision graph one can also specify a range of revisions explicitly.

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

SPECIFYING REVISIONS

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.

Note

This document shows the "raw" syntax as seen by git. The shell and other UIs might require additional quoting to protect special characters and to avoid word splitting.

<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, REBASE_HEAD, REVERT_HEAD, CHERRY_PICK_HEAD, BISECT_HEAD and AUTO_MERGE);
  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 (git am, git merge, git rebase, git reset), 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.
REBASE_HEAD
during a rebase, records the commit at which the operation is currently stopped, either because of conflicts or an edit command in an interactive rebase.
REVERT_HEAD
records the commit which you are reverting when you run git revert.
CHERRY_PICK_HEAD
records the commit which you are cherry-picking when you run git cherry-pick.
BISECT_HEAD
records the current commit to be tested when you run git bisect --no-checkout.
AUTO_MERGE
records a tree object corresponding to the state the ort merge strategy wrote to the working tree when a merge operation resulted in conflicts.

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}
A branch B may be set up to build on top of a branch X (configured with branch.<name>.merge) at a remote R (configured with the branch X taken from remote R, typically found at refs/remotes/R/X.
[<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). Like for @{upstream}, we report the remote-tracking branch that corresponds to that branch at the remote.

Here's an example to make it more clear:

$ git config push.default current
$ git config remote.pushdefault myfork
$ git switch -c mybranch origin/master

$ git rev-parse --symbolic-full-name @{upstream}
refs/remotes/origin/master

$ git rev-parse --symbolic-full-name @{push}
refs/remotes/myfork/mybranch

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.

This suffix is also accepted when spelled in uppercase, and means the same thing no matter the case.

<rev>^[<n>], 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. HEAD~, master~3
A suffix ~ to a revision parameter means the first parent of that commit object. 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, including HEAD. 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. Depending on the given text, the shell's word splitting rules might require additional quoting.
<rev>:<path>, e.g. HEAD: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. 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 =      = A^0
B = A^   = A^1     = A~1
C =      = 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

SPECIFYING RANGES

History traversing commands such as git log operate on a set of commits, not just a single commit.

For these commands, specifying a single revision, using the notation described in the previous section, means the set of commits reachable from the given commit.

Specifying several revisions means the set of commits reachable from any of the given commits.

A commit's reachable set is the commit itself and the commits in its ancestry chain.

There are several notations to specify a set of connected commits (called a "revision range"), illustrated below.

Commit Exclusions

^<rev> (caret) Notation
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 (i.e. r1 and its ancestors).

Dotted Range Notations

The .. (two-dot) Range Notation
The ^r1 r2 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.
The ... (three-dot) Symmetric Difference Notation
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 (left side) or r2 (right side) but not from both.

In these two shorthand notations, 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.

Commands that are specifically designed to take two distinct ranges (e.g. "git range-diff R1 R2" to compare two ranges) do exist, but they are exceptions. Unless otherwise noted, all "git" commands that operate on a set of commits work on a single revision range. In other words, writing two "two-dot range notation" next to each other, e.g.

$ git log A..B C..D

does not specify two revision ranges for most commands. Instead it will name a single connected set of commits, i.e. those that are reachable from either B or D but are reachable from neither A or C. In a linear history like this:

---A---B---o---o---C---D

because A and B are reachable from C, the revision range specified by these two dotted ranges is a single commit D.

Other <rev>^ Parent Shorthand Notations

Three other shorthands exist, particularly useful for merge commits, for naming a set that is formed by a commit and its parent commits.

The r1^@ notation means all parents of r1.

The r1^! notation includes commit r1 but excludes all of its parents. By itself, this notation denotes the single commit r1.

The <rev>^-[<n>] notation includes <rev> but excludes the <n>th parent (i.e. a shorthand for <rev>^<n>..<rev>), with <n> = 1 if not given. This is typically useful for merge commits where you can just pass <commit>^- to get all the commits in the branch that was merged in merge commit <commit> (including <commit> itself).

While <rev>^<n> was about specifying a single commit parent, these three notations also consider its parents. For example you can say HEAD^2^@, however you cannot say HEAD^@^2.

Revision Range Summary

<rev>
Include commits that are reachable from <rev> (i.e. <rev> and its ancestors).
^<rev>
Exclude commits that are reachable from <rev> (i.e. <rev> and its ancestors).
<rev1>..<rev2>
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.
<rev1>...<rev2>
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 all its parents prefixed with ^ to exclude them (and their ancestors).
<rev>^-<n>, e.g. HEAD^-, HEAD^-2
Equivalent to <rev>^<n>..<rev>, with <n> = 1 if not given.

Here are a handful of examples using the Loeliger illustration above, with each step in the notation's expansion and selection carefully spelt out:

   Args   Expanded arguments    Selected commits
   D                            G H D
   D F                          G H I J D F
   ^G D                         H D
   ^D B                         E I J F B
   ^D B C                       E I J F B C
   C                            I J F C
   B..C   = ^B C                C
   B...C  = B ^F C              G H D E B C
   B^-    = B^..B
          = ^B^1 B              E I J F B
   C^@    = C^1
          = F                   I J F
   B^@    = B^1 B^2 B^3
          = D E F               D G H E F I J
   C^!    = C ^C^@
          = C ^C^1
          = C ^F                C
   B^!    = B ^B^@
          = B ^B^1 ^B^2 ^B^3
          = B ^D ^E ^F          B
   F^! D  = F ^I ^J D           G H D F

GIT

Part of the the section called “git(1)” suite

gitsubmodules(7)

NAME

gitsubmodules - Mounting one repository inside another

SYNOPSIS

.gitmodules, $GIT_DIR/config
git submodule
git <command> --recurse-submodules

DESCRIPTION

A submodule is a repository embedded inside another repository. The submodule has its own history; the repository it is embedded in is called a superproject.

On the filesystem, a submodule usually (but not always - see FORMS below) consists of (i) a Git directory located under the $GIT_DIR/modules/ directory of its superproject, (ii) a working directory inside the superproject's working directory, and a .git file at the root of the submodule's working directory pointing to (i).

Assuming the submodule has a Git directory at $GIT_DIR/modules/foo/ and a working directory at path/to/bar/, the superproject tracks the submodule via a gitlink entry in the tree at path/to/bar and an entry in its .gitmodules file (see the section called “gitmodules(5)”) of the form submodule.foo.path = path/to/bar.

The gitlink entry contains the object name of the commit that the superproject expects the submodule's working directory to be at.

The section submodule.foo.* in the .gitmodules file gives additional hints to Git's porcelain layer. For example, the submodule.foo.url setting specifies where to obtain the submodule.

Submodules can be used for at least two different use cases:

  1. Using another project while maintaining independent history. Submodules allow you to contain the working tree of another project within your own working tree while keeping the history of both projects separate. Also, since submodules are fixed to an arbitrary version, the other project can be independently developed without affecting the superproject, allowing the superproject project to fix itself to new versions only when desired.
  2. Splitting a (logically single) project into multiple repositories and tying them back together. This can be used to overcome current limitations of Git's implementation to have finer grained access:

    • Size of the Git repository: In its current form Git scales up poorly for large repositories containing content that is not compressed by delta computation between trees. For example, you can use submodules to hold large binary assets and these repositories can be shallowly cloned such that you do not have a large history locally.
    • Transfer size: In its current form Git requires the whole working tree present. It does not allow partial trees to be transferred in fetch or clone. If the project you work on consists of multiple repositories tied together as submodules in a superproject, you can avoid fetching the working trees of the repositories you are not interested in.
    • Access control: By restricting user access to submodules, this can be used to implement read/write policies for different users.

The configuration of submodules

Submodule operations can be configured using the following mechanisms (from highest to lowest precedence):

  • The command line for those commands that support taking submodules as part of their pathspecs. Most commands have a boolean flag --recurse-submodules which specifies whether to recurse into submodules. Examples are grep and checkout. Some commands take enums, such as fetch and push, where you can specify how submodules are affected.
  • The configuration inside the submodule. This includes $GIT_DIR/config in the submodule, but also settings in the tree such as a .gitattributes or .gitignore files that specify behavior of commands inside the submodule.

    For example an effect from the submodule's .gitignore file would be observed when you run git status --ignore-submodules=none in the superproject. This collects information from the submodule's working directory by running status in the submodule while paying attention to the .gitignore file of the submodule.

    The submodule's $GIT_DIR/config file would come into play when running git push --recurse-submodules=check in the superproject, as this would check if the submodule has any changes not published to any remote. The remotes are configured in the submodule as usual in the $GIT_DIR/config file.

  • The configuration file $GIT_DIR/config in the superproject. Git only recurses into active submodules (see "ACTIVE SUBMODULES" section below).

    If the submodule is not yet initialized, then the configuration inside the submodule does not exist yet, so where to obtain the submodule from is configured here for example.

  • The .gitmodules file inside the superproject. A project usually uses this file to suggest defaults for the upstream collection of repositories for the mapping that is required between a submodule's name and its path.

    This file mainly serves as the mapping between the name and path of submodules in the superproject, such that the submodule's Git directory can be located.

    If the submodule has never been initialized, this is the only place where submodule configuration is found. It serves as the last fallback to specify where to obtain the submodule from.

FORMS

Submodules can take the following forms:

  • The basic form described in DESCRIPTION with a Git directory, a working directory, a gitlink, and a .gitmodules entry.
  • "Old-form" submodule: A working directory with an embedded .git directory, and the tracking gitlink and .gitmodules entry in the superproject. This is typically found in repositories generated using older versions of Git.

    It is possible to construct these old form repositories manually.

    When deinitialized or deleted (see below), the submodule's Git directory is automatically moved to $GIT_DIR/modules/<name>/ of the superproject.

  • Deinitialized submodule: A gitlink, and a .gitmodules entry, but no submodule working directory. The submodule's Git directory may be there as after deinitializing the Git directory is kept around. The directory which is supposed to be the working directory is empty instead.

    A submodule can be deinitialized by running git submodule deinit. Besides emptying the working directory, this command only modifies the superproject's $GIT_DIR/config file, so the superproject's history is not affected. This can be undone using git submodule init.

  • Deleted submodule: A submodule can be deleted by running git rm <submodule-path> && git commit. This can be undone using git revert.

    The deletion removes the superproject's tracking data, which are both the gitlink entry and the section in the .gitmodules file. The submodule's working directory is removed from the file system, but the Git directory is kept around as it to make it possible to checkout past commits without requiring fetching from another repository.

    To completely remove a submodule, manually delete $GIT_DIR/modules/<name>/.

ACTIVE SUBMODULES

A submodule is considered active,

  1. if submodule.<name>.active is set to true

    or

  2. if the submodule's path matches the pathspec in submodule.active

    or

  3. if submodule.<name>.url is set.

and these are evaluated in this order.

For example:

[submodule "foo"]
  active = false
  url = https://example.org/foo
[submodule "bar"]
  active = true
  url = https://example.org/bar
[submodule "baz"]
  url = https://example.org/baz

In the above config only the submodules bar and baz are active, bar due to (1) and baz due to (3). foo is inactive because (1) takes precedence over (3)

Note that (3) is a historical artefact and will be ignored if the (1) and (2) specify that the submodule is not active. In other words, if we have a submodule.<name>.active set to false or if the submodule's path is excluded in the pathspec in submodule.active, the url doesn't matter whether it is present or not. This is illustrated in the example that follows.

[submodule "foo"]
  active = true
  url = https://example.org/foo
[submodule "bar"]
  url = https://example.org/bar
[submodule "baz"]
  url = https://example.org/baz
[submodule "bob"]
  ignore = true
[submodule]
  active = b*
  active = :(exclude) baz

In here all submodules except baz (foo, bar, bob) are active. foo due to its own active flag and all the others due to the submodule active pathspec, which specifies that any submodule starting with b except baz are also active, regardless of the presence of the .url field.

Workflow for a third party library

# Add a submodule
git submodule add <URL> <path>
# Occasionally update the submodule to a new version:
git -C <path> checkout <new-version>
git add <path>
git commit -m "update submodule to new version"
# See the list of submodules in a superproject
git submodule status
# See FORMS on removing submodules

Workflow for an artificially split repo

# Enable recursion for relevant commands, such that
# regular commands recurse into submodules by default
git config --global submodule.recurse true
# Unlike most other commands below, clone still needs
# its own recurse flag:
git clone --recurse <URL> <directory>
cd <directory>
# Get to know the code:
git grep foo
git ls-files --recurse-submodules

Note

git ls-files also requires its own --recurse-submodules flag.

# Get new code
git fetch
git pull --rebase
# Change worktree
git checkout
git reset

Implementation details

When cloning or pulling a repository containing submodules the submodules will not be checked out by default; you can instruct clone to recurse into submodules. The init and update subcommands of git submodule will maintain submodules checked out and at an appropriate revision in your working tree. Alternatively you can set submodule.recurse to have checkout recurse into submodules (note that submodule.recurse also affects other Git commands, see the section called “git-config(1)” for a complete list).

GIT

Part of the the section called “git(1)” suite

gitweb(1)

NAME

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

SYNOPSIS

To get started with gitweb, run the section called “git-instaweb(1)” from a Git repository. This will configure and start your web server, and run a web browser pointing to gitweb.

DESCRIPTION

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, seeing what was changed, when, and by whom.
  • 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 stepping through revisions one at a time, viewing the history of the repository.
  • Finding commits whose commit messages match a given search term.

See https://repo.or.cz/w/git.git/tree/HEAD:/gitweb/ for gitweb source code, browsed using gitweb itself.

CONFIGURATION

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

Repositories

Gitweb can show information from one or more Git repositories. These repositories have to be all on local filesystem, and have to share a common repository root, i.e. be all under a single parent repository (but see also the "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 the 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".

Projects list file format

Instead of having gitweb find repositories by scanning the 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 https://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+<owner@example.org>

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 the section called “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).

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:

read_config_file("gitweb_config.perl");
$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):

#!/bin/sh

export GITWEB_CONFIG="gitweb_make_index.perl"
export GATEWAY_INTERFACE="CGI/1.1"
export HTTP_ACCEPT="*/*"
export REQUEST_METHOD="GET"
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.

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 the section called “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 the section called “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;
    };

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 the section called “git-config(1)”).

You can use the following files in repository:

README.html
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 the section called “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 the section called “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)

Single 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 the section called “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 the section called “gitweb.conf(5)”).

gitweb.owner

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 the section called “gitweb.conf(5)”

ACTIONS, AND URLS

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:

.../gitweb.cgi/<repo>/<action>/<revision>:/<path>?<arguments>
repo

The repository the action will be performed on.

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

action
The action that will be run. Defaults to projects_list if repo is not set, and to summary otherwise.
revision
Revision shown. Defaults to HEAD.
path
The path within the <repository> that the action is performed on, for those actions that require it.
arguments
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:

.../gitweb.cgi/<repo>/<action>/<revision-from>:/<path-from>..<revision-to>:/<path-to>?<arguments>

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];

Actions:

The standard actions are:

project_list
Lists the available Git repositories. This is the default command if no repository is specified in the URL.
summary
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.

tags
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.
blob_plain
Returns the raw data for the file in given repository, at given path and revision. Links to this action are marked raw.
blobdiff
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.
patch
Returns the commit in plain text mail format, suitable for applying with the section called “git-am(1)”.
tag
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.

history

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.

WEBSERVER CONFIGURATION

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.

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
</Directory>

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

http://server/cgi-bin/gitweb.cgi

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
</Directory>

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

http://server/perl/gitweb.cgi

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
</Directory>

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

http://server/gitweb

ADVANCED WEB SERVER SETUP

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

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]
</VirtualHost>

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 browsable gitweb interface. If you then start your the section called “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 the section called “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.

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 directory in unix users' home
    # http://git.example.org/~<user>/
    RewriteRule ^/\~([^\/]+)(/|/gitweb.cgi)?$   /cgi-bin/gitweb.cgi \
                [QSA,E=GITWEB_PROJECTROOT:/home/$1/public_git/,L,PT]

    # http://git.example.org/+<user>/
    #RewriteRule ^/\+([^\/]+)(/|/gitweb.cgi)?$  /cgi-bin/gitweb.cgi \
                 [QSA,E=GITWEB_PROJECTROOT:/home/$1/public_git/,L,PT]

    # http://git.example.org/user/<user>/
    #RewriteRule ^/user/([^\/]+)/(gitweb.cgi)?$ /cgi-bin/gitweb.cgi \
                 [QSA,E=GITWEB_PROJECTROOT:/home/$1/public_git/,L,PT]

    # defined list of project roots
    RewriteRule ^/scm(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi \
                [QSA,E=GITWEB_PROJECTROOT:/pub/scm/,L,PT]
    RewriteRule ^/var(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi \
                [QSA,E=GITWEB_PROJECTROOT:/var/git/,L,PT]

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

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:

http://git.example.org/~<user>/

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.

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

http://git.example.com/project.git/shortlog/sometag

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]
        </Directory>
</VirtualHost>

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]
        </Directory>
</VirtualHost>

The additional AliasMatch makes it so that

http://git.example.com/project.git

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

http://git.example.com/project

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

http://git.example.com/project/command/abranch..git/abranch

will fail with a 404 error.

BUGS

Please report any bugs or feature requests to git@vger.kernel.org, putting "gitweb" in the subject of email.

GIT

Part of the the section called “git(1)” suite

gitweb.conf(5)

NAME

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

SYNOPSIS

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

DESCRIPTION

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 the section called “gitweb(1)” manpage.

DISCUSSION

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 exist 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

read_config_file("/etc/gitweb-gitolite.conf");

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).

CONFIGURATION VARIABLES

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.

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 the section called “gitweb(1)” manpage.

$projectroot

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";

then

http://git.example.com/gitweb.cgi?p=foo/bar.git

and its path_info based equivalent

http://git.example.com/gitweb.cgi/foo/bar.git

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

$projects_list

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.

$project_maxdepth

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.

$export_ok
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. the section called “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.
$export_auth_hook

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 the section called “gitweb(1)” manpage.

$strict_export
Only allow viewing of repositories also shown on the overview page. This for example makes $export_ok file decide if repository is available and not only if it is shown. If $projects_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).

Finding files

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

$GIT
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.
$mimetypes_file
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.
$highlight_bin

Path to the highlight executable to use (it must be the one from http://andre-simon.de/zip/download.php 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: for a file to be highlighted, its syntax type must be detected and that syntax must be supported by "highlight". The default syntax detection is minimal, and there are many supported syntax types with no detection by default. There are three options for adding syntax detection. The first and second priority are %highlight_basename and %highlight_ext, which detect based on basename (the full filename, for example "Makefile") and extension (for example "sh"). The keys of these hashes are the basename and extension, respectively, and the value for a given key is the name of the syntax to be passed via --syntax <syntax> to "highlight". The last priority is the "highlight" configuration of Shebang regular expressions to detect the language based on the first line in the file, (for example, matching the line "#!/bin/bash"). See the highlight documentation and the default config at /etc/highlight/filetypes.conf for more details.

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';

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.

@stylesheets

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.

$logo
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.
$favicon
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.
$javascript

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".

$home_link
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).
$home_link_str
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.
@extra_breadcrumbs

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, https://git-scm.com; in the past, they pointed to Git documentation at https://www.kernel.org.

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.

$site_name

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.

$site_html_head_string
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.
$site_header
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.
$site_footer
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.
$home_text
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.
$projects_list_description_width
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_projects_order

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.

Changing gitweb's behavior

These configuration variables control internal gitweb behavior.

$default_blob_plain_mimetype
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_text_plain_charset
Default charset for text files. If this is not set, the web server configuration will be used. Unset by default.
$fallback_encoding
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".
@diff_opts

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').

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).

@git_base_url_list

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.

$projects_list_group_categories
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).
$project_list_default_category
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).
$prevent_xss
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).
$maxload

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.

$omit_age_column
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.
$omit_owner
If true prevents displaying information about repository owner.
$per_request_config

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.

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.

$version

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
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.

CONFIGURING GITWEB FEATURES

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:

default

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. [].

override

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.

sub

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.

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.

blame

Enable the "blame" and "blame_incremental" blob views, showing for each line the last commit that modified it; see the section called “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).

snapshot

Enable and configure the "snapshot" action, which allows user to download a compressed archive of any tree or commit, as produced by the section called “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.snapshot configuration variable, which contains a comma separated list of formats or "none" to disable snapshots. Unknown values are ignored.

grep

Enable grep search, which lists the files in currently selected tree (directory) containing the given string; see the section called “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).

pickaxe

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 the section called “git-log(1)” (the description of -S<string> option, which refers to pickaxe entry in the section called “gitdiffcore(7)” for more details).

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

show-sizes

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 the section called “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).

patches

Enable and configure "patches" view, which displays list of commits in email (plain text) output format; see also the section called “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

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.

email-privacy
Redact e-mail addresses from the generated HTML, etc. content. This obscures e-mail addresses retrieved from the author/committer and comment sections of the Git log. It is meant to hinder web crawlers that harvest and abuse addresses. Such crawlers may not respect robots.txt. Note that users and user tools also see the addresses as redacted. If Gitweb is not the final step in a workflow then subsequent steps may misbehave because of the redacted information they receive. Disabled by default.
highlight

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).

remote_heads

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. the section called “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.

search

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 the section called “git-log(1)” manpage. Enabled by default.

Project specific override is not supported.

forks

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.

actions

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 https://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.

timed

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.

javascript-timezone

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.

extra-branch-refs

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:

[gitweb]
        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:

[gitweb]
        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.

EXAMPLES

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'];

BUGS

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.

ENVIRONMENT

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

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

FILES

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

GIT

Part of the the section called “git(1)” suite

gitworkflows(7)

NAME

gitworkflows - An overview of recommended workflows with Git

SYNOPSIS

git *

DESCRIPTION

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.

SEPARATE CHANGES

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 the section called “git-blame(1)” and the section called “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 push --keep-index to run the test suite independent of other uncommitted changes; see the EXAMPLES section of the section called “git-stash(1)”.

MANAGING BRANCHES

There are two main tools that can be used to include changes from one branch on another: the section called “git-merge(1)” and the section called “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.

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:

  • seen (patches seen by the maintainer) 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 seen), and "graduates" to master for the next release once it is considered stable enough.

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 requires 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 the section called “git-cherry-pick(1)”) downwards. This will happen a few times and is nothing to worry about unless you do it very frequently.

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 the section called “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 the section called “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.

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 seen.

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.

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.

Branch management for next and seen 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 switch -C next 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 seen. A public announcement is not necessary since seen is a throw-away branch, as described above.

DISTRIBUTED WORKFLOWS

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.

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 the section called “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 they try to pull changes from downstream. In this case, they 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.

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 the section called “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 the section called “git-format-patch(1)” and the section called “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 the section called “git-am(1)” for other options.

GIT

Part of the the section called “git(1)” suite

gitglossary(7)

NAME

gitglossary - A Git Glossary

SYNOPSIS

*

DESCRIPTION

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.
branch
A "branch" is a 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.
cache
Obsolete for: index.
chain
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).
changeset
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.
checkout
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.
cherry-picking
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.
clean
A working tree is clean, if it corresponds to the revision referenced by the current head. Also see "dirty".
commit

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 graph concept, representations and usage
A synonym for the DAG structure formed by the commits in the object database, referenced by branch tips, using their chain of linked commits. This structure is the definitive commit graph. The graph can be represented in other ways, e.g. the "commit-graph" file.
commit-graph file
The "commit-graph" (normally hyphenated) file is a supplemental representation of the commit graph which accelerates commit graph walks. The "commit-graph" file is stored either in the .git/objects/info directory or in the info directory of an alternate object database.
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.
DAG
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.
dereference

Referring to a symbolic ref: the action of accessing the reference pointed at by a symbolic ref. Recursive dereferencing involves repeating the aforementioned process on the resulting ref until a non-symbolic reference is found.

Referring to a tag object: the action of accessing the object a tag points at. Tags are recursively dereferenced by repeating the operation on the result object until the result has either a specified object type (where applicable) or any non-"tag" object type. A synonym for "recursive dereference" in the context of tags is "peel".

Referring to a commit object: the action of accessing the commit's tree object. Commits cannot be dereferenced recursively.

Unless otherwise specified, "dereferencing" as it used in the context of Git commands or protocols is implicitly recursive.

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.

directory
The list you get with "ls" :-)
dirty
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.
fast-forward
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 a case, you do not make a new merge commit but instead just update your branch to point at the same revision as the branch you are merging. This will happen frequently on a remote-tracking branch of a remote repository.
fetch
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 the section called “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).
gitfile
A plain file .git at the root of a working tree that points at the directory that is the real repository. For proper use see the section called “git-worktree(1)” or the section called “git-submodule(1)”. For syntax see the section called “gitrepository-layout(5)”.
grafts

Grafts enable 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 the section called “git-replace(1)” for a more flexible and robust system to do the same thing.

hash
In Git's context, synonym for object name.
head
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 the section called “git-pack-refs(1)”.)
HEAD
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.
hook
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.
index
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).
master
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.
merge

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".

object
The unit of storage in Git. It is uniquely identified by the SHA-1 of its contents. Consequently, an object cannot 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, object ID, oid
Synonyms 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.
octopus
To merge more than two branches.
orphan
The act of getting on a branch that does not exist yet (i.e., an unborn branch). After such an operation, the commit first created becomes a commit without a parent, starting a new history.
origin
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.
overlay
Only update and add files to the working directory, but don't delete them, similar to how cp -R would update the contents in the destination directory. This is the default mode in a checkout when checking out files from the index or a tree-ish. In contrast, no-overlay mode also deletes tracked files not present in the source, similar to rsync --delete.
pack
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.
pathspec

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 working tree. 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 an 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.

top
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.
literal
Wildcards in the pattern such as * or ? are treated as literal characters.
icase
Case insensitive match.
glob

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. "**/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.

attr

After attr: comes a space separated list of "attribute requirements", all of which must be met in order for the path to be considered a match; this is in addition to the usual non-magic pathspec pattern matching. See the section called “gitattributes(5)”.

Each of the attribute requirements for the path takes one of these forms:

  • "ATTR" requires that the attribute ATTR be set.
  • "-ATTR" requires that the attribute ATTR be unset.
  • "ATTR=VALUE" requires that the attribute ATTR be set to the string VALUE.
  • "!ATTR" requires that the attribute ATTR be unspecified.

    Note that when matching against a tree object, attributes are still obtained from working tree, not from the given tree object.

exclude
After a path matches any non-exclude pathspec, it will be run through all exclude pathspecs (magic signature: ! or its synonym ^). If it matches, the path is ignored. When there is no non-exclude pathspec, the exclusion is applied to the result set as if invoked without any pathspec.
parent
A commit object contains a (possibly empty) list of the logical predecessor(s) in the line of development, i.e. its parents.
peel
The action of recursively dereferencing a tag object.
pickaxe
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 the section called “git-diff(1)”.
plumbing
Cute name for core Git.
porcelain
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.
pseudoref

A ref that has different semantics than normal refs. These refs can be read via normal Git commands, but cannot be written to by commands like the section called “git-update-ref(1)”.

The following pseudorefs are known to Git:

pull
Pulling a branch means to fetch it and merge it. See also the section called “git-pull(1)”.
push
Pushing a branch means to get the branch's head ref from a remote repository, find out if it is an 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.
reachable
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.
reachability bitmaps
Reachability bitmaps store information about the reachability of a selected set of commits in a packfile, or a multi-pack index (MIDX), to speed up object search. The bitmaps are stored in a ".bitmap" file. A repository may have at most one bitmap file in use. The bitmap file may belong to either one pack, or the repository's multi-pack index (if it exists).
rebase
To reapply a series of changes from a branch to a different base, and reset the head of that branch to the result.
ref

A name 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 the section called “gitrevisions(7)” for details. Refs are stored in the repository.

The ref namespace is hierarchical. Ref names must either start with refs/ or be located in the root of the hierarchy. For the latter, their name must follow these rules:

  • The name consists of only upper-case characters or underscores.
  • The name ends with "_HEAD" or is equal to "HEAD".

    There are some irregular refs in the root of the hierarchy that do not match these rules. The following list is exhaustive and shall not be extended in the future:

  • AUTO_MERGE
  • BISECT_EXPECTED_REV
  • NOTES_MERGE_PARTIAL
  • NOTES_MERGE_REF
  • MERGE_AUTOSTASH

    Different subhierarchies are used for different purposes. For example, the refs/heads/ hierarchy is used to represent local branches whereas the refs/tags/ hierarchy is used to represent local tags..

reflog
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 the section called “git-reflog(1)” for details.
refspec
A "refspec" is used by fetch and push to describe the mapping between remote ref and local ref. See the section called “git-fetch(1)” or the section called “git-push(1)” for details.
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.
repository
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.
resolve
The action of fixing up manually what a failed automatic merge left behind.
revision
Synonym for commit (the noun).
rewind
To throw away part of the development, i.e. to assign the head to an earlier revision.
SCM
Source code management (tool).
SHA-1
"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 the section called “git-clone(1)”, and its history can be later deepened with the section called “git-fetch(1)”.
stash entry
An object used to temporarily store the contents of a dirty working directory and the index for future reuse.
submodule
A repository that holds the history of a separate project inside another repository (the latter of which is called superproject).
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.
symref
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 the section called “git-symbolic-ref(1)” command.
tag
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.
trailer
Key-value metadata. Trailers are optionally found at the end of a commit message. Might be called "footers" or "tags" in other communities. See the section called “git-interpret-trailers(1)”.
tree
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.
unborn
The HEAD can point at a branch that does not yet exist and that does not have any commit on it yet, and such a branch is called an unborn branch. The most typical way users encounter an unborn branch is by creating a repository anew without cloning from elsewhere. The HEAD would point at the main (or master, depending on your configuration) branch that is yet to be born. Also some operations can get you on an unborn branch with their orphan option.
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.
worktree
A repository can have zero (i.e. bare repository) or one or more worktrees attached to it. One "worktree" consists of a "working tree" and repository metadata, most of which are shared among other worktrees of a single repository, and some of which are maintained separately per worktree (e.g. the index, HEAD and pseudorefs like MERGE_HEAD, per-worktree refs and per-worktree configuration file).

GIT

Part of the the section called “git(1)” suite