Git and libgit2

Low-Level Git Commands

Published 2023-03-13. Last modified 2023-05-15.
Time to read: 4 minutes.

This page is part of the git collection.

This article discusses low-level git commands. It builds on the material presented in Git Concepts. The commands are presented in alphabetical order.

Unfortunately, I do not say much of interest in this page between git-cat-file (next), and git-rev-parse. This page will be updated.

The version of git used in this article is:

Shell
$ git --version
git version 2.37.2 

Git-Cat-File

Here is the help information for git-cat-file.

Obtain Reference Type

This example obtains the type of a reference for .gitignore at HEAD:

Shell
$ exec git cat-file -t HEAD:.gitignore
blob 

Remember, a git blob is just a stored file, and a git tree is just a stored directory.

Display File From SHA

Two syntaxes are possible to display the contents of a file, given its SHA:

Shell
$ git cat-file -p a997766
Shell
$ git cat-file a997766^{blob}

Display File by Commit and Name

This example lists the first 10 lines of the contents of the version of the .gitignore file at the HEAD commit:

Shell
$ echo HEAD:.gitignore | git cat-file --batch | head
6e11c49ab69e6d2ca5109dffd269b0ce3e97f767 blob 583
.yarn/*
!.yarn/cache
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
.bsp/
exe/ 

Git-Commit-Tree

Shell
$ git help commit-tree
GIT-COMMIT-TREE(1)            Git Manual            GIT-COMMIT-TREE(1)
NAME git‐commit‐tree - Create a new commit object
SYNOPSIS git commit-tree <tree> [(-p <parent>)...] git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] [(-F <file>)...] <tree>
DESCRIPTION This is usually not what an end user wants to run directly. See git‐commit(1) instead.
Creates a new commit object based on the provided tree object and emits the new commit object id on stdout. The log message is read from the standard input, unless -m or -F options are given.
The -m and -F options can be given any number of times, in any order. The commit log message will be composed in the order in which the options are given.
A commit object may have any number of parents. With exactly one parent, it is an ordinary commit. Having more than one parent makes the commit a merge between several lines of history. Initial (root) commits have no parents.
While a tree represents a particular directory state of a working directory, a commit represents that state in "time", and explains how to get there.
Normally a commit would identify a new "HEAD" state, and while Git doesn’t care where you save the note about that state, in practice we tend to just write the result to the file that is pointed at by .git/HEAD, so that we can always see what the last committed state was.
OPTIONS <tree> An existing tree object.
-p <parent> Each -p indicates the id of a parent commit object.
-m <message> A paragraph in the commit log message. This can be given more than once and each <message> becomes its own paragraph.
-F <file> Read the commit log message from the given file. Use - to read from the standard input. This can be given more than once and the content of each file becomes its own paragraph.
-S[<keyid>], --gpg-sign[=<keyid>], --no-gpg-sign GPG-sign commits. The keyid argument is optional and defaults to the committer identity; if specified, it must be stuck to the option without a space. --no-gpg-sign is useful to countermand a --gpg-sign option given earlier on the command line.
COMMIT INFORMATION A commit encapsulates:
• all parent object ids
• author name, email and date
• committer name and email and the commit time.
A commit comment is read from stdin. If a changelog entry is not provided via "<" redirection, git commit-tree will just wait for one to be entered and terminated with ^D.
DATE FORMATS The GIT_AUTHOR_DATE and GIT_COMMITTER_DATE environment variables support the following date formats:
Git internal format It is <unix-timestamp> <time-zone-offset>, where <unix-timestamp> is the number of seconds since the UNIX epoch. <time-zone-offset> is a positive or negative offset from UTC. For example CET (which is 1 hour ahead of UTC) is +0100.
RFC 2822 The standard email format as described by RFC 2822, for example Thu, 07 Apr 2005 22:13:13 +0200.
ISO 8601 Time and date specified by the ISO 8601 standard, for example 2005-04-07T22:13:13. The parser accepts a space instead of the T character as well. Fractional parts of a second will be ignored, for example 2005-04-07T22:13:13.019 will be treated as 2005-04-07T22:13:13.
Note In addition, the date part is accepted in the following formats: YYYY.MM.DD, MM/DD/YYYY and DD.MM.YYYY.
DISCUSSION Git is to some extent character encoding agnostic.
• The contents of the blob objects are uninterpreted sequences of bytes. There is no encoding translation at the core level.
• Path names are encoded in UTF-8 normalization form C. This applies to tree objects, the index file, ref names, as well as path names in command line arguments, environment variables and config files (.git/config (see git‐ config(1)), gitignore(5), gitattributes(5) and gitmodules(5)).
Note that Git at the core level treats path names simply as sequences of non-NUL bytes, there are no path name encoding conversions (except on Mac and Windows). Therefore, using non-ASCII path names will mostly work even on platforms and file systems that use legacy extended ASCII encodings. However, repositories created on such systems will not work properly on UTF-8-based systems (e.g. Linux, Mac, Windows) and vice versa. Additionally, many Git-based tools simply assume path names to be UTF-8 and will fail to display other encodings correctly.
• Commit log messages are typically encoded in UTF-8, but other extended ASCII encodings are also supported. This includes ISO-8859-x, CP125x and many others, but not UTF-16/32, EBCDIC and CJK multi-byte encodings (GBK, Shift-JIS, Big5, EUC-x, CP9xx etc.).
Although we encourage that the commit log messages are encoded in UTF-8, both the core and Git Porcelain are designed not to force UTF-8 on projects. If all participants of a particular project find it more convenient to use legacy encodings, Git does not forbid it. However, there are a few things to keep in mind.
1. git commit and git commit-tree issues a warning if the commit log message given to it does not look like a valid UTF-8 string, unless you explicitly say your project uses a legacy encoding. The way to say this is to have i18n.commitEncoding in .git/config file, like this:
[i18n] commitEncoding = ISO-8859-1
Commit objects created with the above setting record the value of i18n.commitEncoding in its encoding header. This is to help other people who look at them later. Lack of this header implies that the commit log message is encoded in UTF-8.
2. git log, git show, git blame and friends look at the encoding header of a commit object, and try to re-code the log message into UTF-8 unless otherwise specified. You can specify the desired output encoding with i18n.logOutputEncoding in .git/config file, like this:
[i18n] logOutputEncoding = ISO-8859-1
If you do not have this configuration variable, the value of i18n.commitEncoding is used instead.
Note that we deliberately chose not to re-code the commit log message when a commit is made to force UTF-8 at the commit object level, because re-coding to UTF-8 is not necessarily a reversible operation.
FILES /etc/mailname
SEE ALSO git‐write‐tree(1) git‐commit(1)
GIT Part of the git(1) suite
Git 2.40.1 05/18/2023 GIT-COMMIT-TREE(1)

Git-Describe

The help information is:

Shell
$ git help describe
GIT-DESCRIBE(1)               Git Manual               GIT-DESCRIBE(1)
NAME git‐describe - Give an object a human readable name based on an available ref
SYNOPSIS git describe [--all] [--tags] [--contains] [--abbrev=<n>] [<commit-ish>...] git describe [--all] [--tags] [--contains] [--abbrev=<n>] --dirty[=<mark>] git describe <blob>
DESCRIPTION The command finds the most recent tag that is reachable from a commit. If the tag points to the commit, then only the tag is shown. Otherwise, it suffixes the tag name with the number of additional commits on top of the tagged object and the abbreviated object name of the most recent commit. The result is a "human-readable" object name which can also be used to identify the commit to other git commands.
By default (without --all or --tags) git describe only shows annotated tags. For more information about creating annotated tags see the -a and -s options to git‐tag(1).
If the given object refers to a blob, it will be described as <commit-ish>:<path>, such that the blob can be found at <path> in the <commit-ish>, which itself describes the first commit in which this blob occurs in a reverse revision walk from HEAD.
OPTIONS <commit-ish>... Commit-ish object names to describe. Defaults to HEAD if omitted.
--dirty[=<mark>], --broken[=<mark>] Describe the state of the working tree. When the working tree matches HEAD, the output is the same as "git describe HEAD". If the working tree has local modification "-dirty" is appended to it. If a repository is corrupt and Git cannot determine if there is local modification, Git will error out, unless ‘--broken’ is given, which appends the suffix "-broken" instead.
--all Instead of using only the annotated tags, use any ref found in refs/ namespace. This option enables matching any known branch, remote-tracking branch, or lightweight tag.
--tags Instead of using only the annotated tags, use any tag found in refs/tags namespace. This option enables matching a lightweight (non-annotated) tag.
--contains Instead of finding the tag that predates the commit, find the tag that comes after the commit, and thus contains it. Automatically implies --tags.
--abbrev=<n> Instead of using the default number of hexadecimal digits (which will vary according to the number of objects in the repository with a default of 7) of the abbreviated object name, use <n> digits, or as many digits as needed to form a unique object name. An <n> of 0 will suppress long format, only showing the closest tag.
--candidates=<n> Instead of considering only the 10 most recent tags as candidates to describe the input commit-ish consider up to <n> candidates. Increasing <n> above 10 will take slightly longer but may produce a more accurate result. An <n> of 0 will cause only exact matches to be output.
--exact-match Only output exact matches (a tag directly references the supplied commit). This is a synonym for --candidates=0.
--debug Verbosely display information about the searching strategy being employed to standard error. The tag name will still be printed to standard out.
--long Always output the long format (the tag, the number of commits and the abbreviated commit name) even when it matches a tag. This is useful when you want to see parts of the commit object name in "describe" output, even when the commit in question happens to be a tagged version. Instead of just emitting the tag name, it will describe such a commit as v1.2-0-gdeadbee (0th commit since tag v1.2 that points at object deadbee....).
--match <pattern> Only consider tags matching the given glob(7) pattern, excluding the "refs/tags/" prefix. If used with --all, it also considers local branches and remote-tracking references matching the pattern, excluding respectively "refs/heads/" and "refs/remotes/" prefix; references of other types are never considered. If given multiple times, a list of patterns will be accumulated, and tags matching any of the patterns will be considered. Use --no-match to clear and reset the list of patterns.
--exclude <pattern> Do not consider tags matching the given glob(7) pattern, excluding the "refs/tags/" prefix. If used with --all, it also does not consider local branches and remote-tracking references matching the pattern, excluding respectively "refs/heads/" and "refs/remotes/" prefix; references of other types are never considered. If given multiple times, a list of patterns will be accumulated and tags matching any of the patterns will be excluded. When combined with --match a tag will be considered when it matches at least one --match pattern and does not match any of the --exclude patterns. Use --no-exclude to clear and reset the list of patterns.
--always Show uniquely abbreviated commit object as fallback.
--first-parent Follow only the first parent commit upon seeing a merge commit. This is useful when you wish to not match tags on branches merged in the history of the target commit.
EXAMPLES With something like git.git current tree, I get:
[torvalds@g5 git]$ git describe parent v1.0.4-14-g2414721
i.e. the current head of my "parent" branch is based on v1.0.4, but since it has a few commits on top of that, describe has added the number of additional commits ("14") and an abbreviated object name for the commit itself ("2414721") at the end.
The number of additional commits is the number of commits which would be displayed by "git log v1.0.4..parent". The hash suffix is "-g" + an unambigous abbreviation for the tip commit of parent (which was 2414721b194453f058079d897d13c4e377f92dc6). The length of the abbreviation scales as the repository grows, using the approximate number of objects in the repository and a bit of math around the birthday paradox, and defaults to a minimum of 7. The "g" prefix stands for "git" and is used to allow describing the version of a software depending on the SCM the software is managed with. This is useful in an environment where people may use different SCMs.
Doing a git describe on a tag-name will just show the tag name:
[torvalds@g5 git]$ git describe v1.0.4 v1.0.4
With --all, the command can use branch heads as references, so the output shows the reference path as well:
[torvalds@g5 git]$ git describe --all --abbrev=4 v1.0.5^2 tags/v1.0.0-21-g975b
[torvalds@g5 git]$ git describe --all --abbrev=4 HEAD^ heads/lt/describe-7-g975b
With --abbrev set to 0, the command can be used to find the closest tagname without any suffix:
[torvalds@g5 git]$ git describe --abbrev=0 v1.0.5^2 tags/v1.0.0
Note that the suffix you get if you type these commands today may be longer than what Linus saw above when he ran these commands, as your Git repository may have new commits whose object names begin with 975b that did not exist back then, and "-g975b" suffix alone may not be sufficient to disambiguate these commits.
SEARCH STRATEGY For each commit-ish supplied, git describe will first look for a tag which tags exactly that commit. Annotated tags will always be preferred over lightweight tags, and tags with newer dates will always be preferred over tags with older dates. If an exact match is found, its name will be output and searching will stop.
If an exact match was not found, git describe will walk back through the commit history to locate an ancestor commit which has been tagged. The ancestor’s tag will be output along with an abbreviation of the input commit-ish’s SHA-1. If --first-parent was specified then the walk will only consider the first parent of each commit.
If multiple tags were found during the walk then the tag which has the fewest commits different from the input commit-ish will be selected and output. Here fewest commits different is defined as the number of commits which would be shown by git log tag..input will be the smallest number of commits possible.
BUGS Tree objects as well as tag objects not pointing at commits, cannot be described. When describing blobs, the lightweight tags pointing at blobs are ignored, but the blob is still described as <committ-ish>:<path> despite the lightweight tag being favorable.
GIT Part of the git(1) suite
Git 2.40.1 05/18/2023 GIT-DESCRIBE(1)

Here is an example:

Shell
$ cd="$jekyll_pre" git describe HEAD~3
v1.3.0-4-g3325b45 

Git-Diff

Git-Diff can create patches between two refs. Here is the help message:

Shell
$ git help diff
GIT-DIFF(1)                   Git Manual                   GIT-DIFF(1)
NAME git‐diff - Show changes between commits, commit and working tree, etc
SYNOPSIS git diff [<options>] [<commit>] [--] [<path>...] git diff [<options>] --cached [--merge-base] [<commit>] [--] [<path>...] git diff [<options>] [--merge-base] <commit> [<commit>...] <commit> [--] [<path>...] git diff [<options>] <commit>...<commit> [--] [<path>...] git diff [<options>] <blob> <blob> git diff [<options>] --no-index [--] <path> <path>
DESCRIPTION Show changes between the working tree and the index or a tree, changes between the index and a tree, changes between two trees, changes resulting from a merge, changes between two blob objects, or changes between two files on disk.
git diff [<options>] [--] [<path>...] This form is to view the changes you made relative to the index (staging area for the next commit). In other words, the differences are what you could tell Git to further add to the index but you still haven’t. You can stage these changes by using git‐add(1).
git diff [<options>] --no-index [--] <path> <path> This form is to compare the given two paths on the filesystem. You can omit the --no-index option when running the command in a working tree controlled by Git and at least one of the paths points outside the working tree, or when running the command outside a working tree controlled by Git. This form implies --exit-code.
git diff [<options>] --cached [--merge-base] [<commit>] [--] [<path>...] This form is to view the changes you staged for the next commit relative to the named <commit>. Typically you would want comparison with the latest commit, so if you do not give <commit>, it defaults to HEAD. If HEAD does not exist (e.g. unborn branches) and <commit> is not given, it shows all staged changes. --staged is a synonym of --cached.
If --merge-base is given, instead of using <commit>, use the merge base of <commit> and HEAD. git diff --cached --merge-base A is equivalent to git diff --cached $(git merge-base A HEAD).
git diff [<options>] [--merge-base] <commit> [--] [<path>...] This form is to view the changes you have in your working tree relative to the named <commit>. You can use HEAD to compare it with the latest commit, or a branch name to compare with the tip of a different branch.
If --merge-base is given, instead of using <commit>, use the merge base of <commit> and HEAD. git diff --merge-base A is equivalent to git diff $(git merge-base A HEAD).
git diff [<options>] [--merge-base] <commit> <commit> [--] [<path>...] This is to view the changes between two arbitrary <commit>.
If --merge-base is given, use the merge base of the two commits for the "before" side. git diff --merge-base A B is equivalent to git diff $(git merge-base A B) B.
git diff [<options>] <commit> <commit>... <commit> [--] [<path>...] This form is to view the results of a merge commit. The first listed <commit> must be the merge itself; the remaining two or more commits should be its parents. Convenient ways to produce the desired set of revisions are to use the suffixes ^@ and ^!. If A is a merge commit, then git diff A A^@, git diff A^! and git show A all give the same combined diff.
git diff [<options>] <commit>..<commit> [--] [<path>...] This is synonymous to the earlier form (without the ..) for viewing the changes between two arbitrary <commit>. If <commit> on one side is omitted, it will have the same effect as using HEAD instead.
git diff [<options>] <commit>...<commit> [--] [<path>...] This form is to view the changes on the branch containing and up to the second <commit>, starting at a common ancestor of both <commit>. git diff A...B is equivalent to git diff $(git merge-base A B) B. You can omit any one of <commit>, which has the same effect as using HEAD instead.
Just in case you are doing something exotic, it should be noted that all of the <commit> in the above description, except in the --merge-base case and in the last two forms that use .. notations, can be any <tree>.
For a more complete list of ways to spell <commit>, see "SPECIFYING REVISIONS" section in gitrevisions(7). However, "diff" is about comparing two endpoints, not ranges, and the range notations (<commit>..<commit> and <commit>...<commit>) do not mean a range as defined in the "SPECIFYING RANGES" section in gitrevisions(7).
git diff [<options>] <blob> <blob> This form is to view the differences between the raw contents of two blob objects.
OPTIONS -p, -u, --patch Generate patch (see section titled "Generating patch text with -p"). This is the default.
-s, --no-patch Suppress diff output. Useful for commands like git show that show the patch by default, or to cancel the effect of --patch.
-U<n>, --unified=<n> Generate diffs with <n> lines of context instead of the usual three. Implies --patch.
--output=<file> Output to a specific file instead of stdout.
--output-indicator-new=<char>, --output-indicator-old=<char>, --output-indicator-context=<char> Specify the character used to indicate new, old or context lines in the generated patch. Normally they are +, - and ' ' respectively.
--raw Generate the diff in raw format.
--patch-with-raw Synonym for -p --raw.
--indent-heuristic Enable the heuristic that shifts diff hunk boundaries to make patches easier to read. This is the default.
--no-indent-heuristic Disable the indent heuristic.
--minimal Spend extra time to make sure the smallest possible diff is produced.
--patience Generate a diff using the "patience diff" algorithm.
--histogram Generate a diff using the "histogram diff" algorithm.
--anchored=<text> Generate a diff using the "anchored diff" algorithm.
This option may be specified more than once.
If a line exists in both the source and destination, exists only once, and starts with this text, this algorithm attempts to prevent it from appearing as a deletion or addition in the output. It uses the "patience diff" algorithm internally.
--diff-algorithm={patience|minimal|histogram|myers} Choose a diff algorithm. The variants are as follows:
default, myers The basic greedy diff algorithm. Currently, this is the default.
minimal Spend extra time to make sure the smallest possible diff is produced.
patience Use "patience diff" algorithm when generating patches.
histogram This algorithm extends the patience algorithm to "support low-occurrence common elements".
For instance, if you configured the diff.algorithm variable to a non-default value and want to use the default one, then you have to use --diff-algorithm=default option.
--stat[=<width>[,<name-width>[,<count>]]] Generate a diffstat. By default, as much space as necessary will be used for the filename part, and the rest for the graph part. Maximum width defaults to terminal width, or 80 columns if not connected to a terminal, and can be overridden by <width>. The width of the filename part can be limited by giving another width <name-width> after a comma. The width of the graph part can be limited by using --stat-graph-width=<width> (affects all commands generating a stat graph) or by setting diff.statGraphWidth=<width> (does not affect git format-patch). By giving a third parameter <count>, you can limit the output to the first <count> lines, followed by ... if there are more.
These parameters can also be set individually with --stat-width=<width>, --stat-name-width=<name-width> and --stat-count=<count>.
--compact-summary Output a condensed summary of extended header information such as file creations or deletions ("new" or "gone", optionally "+l" if it’s a symlink) and mode changes ("+x" or "-x" for adding or removing executable bit respectively) in diffstat. The information is put between the filename part and the graph part. Implies --stat.
--numstat Similar to --stat, but shows number of added and deleted lines in decimal notation and pathname without abbreviation, to make it more machine friendly. For binary files, outputs two - instead of saying 0 0.
--shortstat Output only the last line of the --stat format containing total number of modified files, as well as number of added and deleted lines.
-X[<param1,param2,...>], --dirstat[=<param1,param2,...>] Output the distribution of relative amount of changes for each sub-directory. The behavior of --dirstat can be customized by passing it a comma separated list of parameters. The defaults are controlled by the diff.dirstat configuration variable (see git‐config(1)). The following parameters are available:
changes Compute the dirstat numbers by counting the lines that have been removed from the source, or added to the destination. This ignores the amount of pure code movements within a file. In other words, rearranging lines in a file is not counted as much as other changes. This is the default behavior when no parameter is given.
lines Compute the dirstat numbers by doing the regular line-based diff analysis, and summing the removed/added line counts. (For binary files, count 64-byte chunks instead, since binary files have no natural concept of lines). This is a more expensive --dirstat behavior than the changes behavior, but it does count rearranged lines within a file as much as other changes. The resulting output is consistent with what you get from the other --*stat options.
files Compute the dirstat numbers by counting the number of files changed. Each changed file counts equally in the dirstat analysis. This is the computationally cheapest --dirstat behavior, since it does not have to look at the file contents at all.
cumulative Count changes in a child directory for the parent directory as well. Note that when using cumulative, the sum of the percentages reported may exceed 100%. The default (non-cumulative) behavior can be specified with the noncumulative parameter.
<limit> An integer parameter specifies a cut-off percent (3% by default). Directories contributing less than this percentage of the changes are not shown in the output.
Example: The following will count changed files, while ignoring directories with less than 10% of the total amount of changed files, and accumulating child directory counts in the parent directories: --dirstat=files,10,cumulative.
--cumulative Synonym for --dirstat=cumulative
--dirstat-by-file[=<param1,param2>...] Synonym for --dirstat=files,param1,param2...
--summary Output a condensed summary of extended header information such as creations, renames and mode changes.
--patch-with-stat Synonym for -p --stat.
-z When --raw, --numstat, --name-only or --name-status has been given, do not munge pathnames and use NULs as output field terminators.
Without this option, pathnames with "unusual" characters are quoted as explained for the configuration variable core.quotePath (see git‐config(1)).
--name-only Show only names of changed files. The file names are often encoded in UTF-8. For more information see the discussion about encoding in the git‐log(1) manual page.
--name-status Show only names and status of changed files. See the description of the --diff-filter option on what the status letters mean. Just like --name-only the file names are often encoded in UTF-8.
--submodule[=<format>] Specify how differences in submodules are shown. When specifying --submodule=short the short format is used. This format just shows the names of the commits at the beginning and end of the range. When --submodule or --submodule=log is specified, the log format is used. This format lists the commits in the range like git‐submodule(1) summary does. When --submodule=diff is specified, the diff format is used. This format shows an inline diff of the changes in the submodule contents between the commit range. Defaults to diff.submodule or the short format if the config option is unset.
--color[=<when>] Show colored diff. --color (i.e. without =<when>) is the same as --color=always. <when> can be one of always, never, or auto. It can be changed by the color.ui and color.diff configuration settings.
--no-color Turn off colored diff. This can be used to override configuration settings. It is the same as --color=never.
--color-moved[=<mode>] Moved lines of code are colored differently. It can be changed by the diff.colorMoved configuration setting. The <mode> defaults to no if the option is not given and to zebra if the option with no mode is given. The mode must be one of:
no Moved lines are not highlighted.
default Is a synonym for zebra. This may change to a more sensible mode in the future.
plain Any line that is added in one location and was removed in another location will be colored with color.diff.newMoved. Similarly color.diff.oldMoved will be used for removed lines that are added somewhere else in the diff. This mode picks up any moved line, but it is not very useful in a review to determine if a block of code was moved without permutation.
blocks Blocks of moved text of at least 20 alphanumeric characters are detected greedily. The detected blocks are painted using either the color.diff.{old,new}Moved color. Adjacent blocks cannot be told apart.
zebra Blocks of moved text are detected as in blocks mode. The blocks are painted using either the color.diff.{old,new}Moved color or color.diff.{old,new}MovedAlternative. The change between the two colors indicates that a new block was detected.
dimmed-zebra Similar to zebra, but additional dimming of uninteresting parts of moved code is performed. The bordering lines of two adjacent blocks are considered interesting, the rest is uninteresting. dimmed_zebra is a deprecated synonym.
--no-color-moved Turn off move detection. This can be used to override configuration settings. It is the same as --color-moved=no.
--color-moved-ws=<modes> This configures how whitespace is ignored when performing the move detection for --color-moved. It can be set by the diff.colorMovedWS configuration setting. These modes can be given as a comma separated list:
no Do not ignore whitespace when performing move detection.
ignore-space-at-eol Ignore changes in whitespace at EOL.
ignore-space-change Ignore changes in amount of whitespace. This ignores whitespace at line end, and considers all other sequences of one or more whitespace characters to be equivalent.
ignore-all-space Ignore whitespace when comparing lines. This ignores differences even if one line has whitespace where the other line has none.
allow-indentation-change Initially ignore any whitespace in the move detection, then group the moved code blocks only into a block if the change in whitespace is the same per line. This is incompatible with the other modes.
--no-color-moved-ws Do not ignore whitespace when performing move detection. This can be used to override configuration settings. It is the same as --color-moved-ws=no.
--word-diff[=<mode>] Show a word diff, using the <mode> to delimit changed words. By default, words are delimited by whitespace; see --word-diff-regex below. The <mode> defaults to plain, and must be one of:
color Highlight changed words using only colors. Implies --color.
plain Show words as [-removed-] and {+added+}. Makes no attempts to escape the delimiters if they appear in the input, so the output may be ambiguous.
porcelain Use a special line-based format intended for script consumption. Added/removed/unchanged runs are printed in the usual unified diff format, starting with a +/-/‘ ‘ character at the beginning of the line and extending to the end of the line. Newlines in the input are represented by a tilde ~ on a line of its own.
none Disable word diff again.
Note that despite the name of the first mode, color is used to highlight the changed parts in all modes if enabled.
--word-diff-regex=<regex> Use <regex> to decide what a word is, instead of considering runs of non-whitespace to be a word. Also implies --word-diff unless it was already enabled.
Every non-overlapping match of the <regex> is considered a word. Anything between these matches is considered whitespace and ignored(!) for the purposes of finding differences. You may want to append |[^[:space:]] to your regular expression to make sure that it matches all non-whitespace characters. A match that contains a newline is silently truncated(!) at the newline.
For example, --word-diff-regex=. will treat each character as a word and, correspondingly, show differences character by character.
The regex can also be set via a diff driver or configuration option, see gitattributes(5) or git‐ config(1). Giving it explicitly overrides any diff driver or configuration setting. Diff drivers override configuration settings.
--color-words[=<regex>] Equivalent to --word-diff=color plus (if a regex was specified) --word-diff-regex=<regex>.
--no-renames Turn off rename detection, even when the configuration file gives the default to do so.
--[no-]rename-empty Whether to use empty blobs as rename source.
--check Warn if changes introduce conflict markers or whitespace errors. What are considered whitespace errors is controlled by core.whitespace configuration. By default, trailing whitespaces (including lines that consist solely of whitespaces) and a space character that is immediately followed by a tab character inside the initial indent of the line are considered whitespace errors. Exits with non-zero status if problems are found. Not compatible with --exit-code.
--ws-error-highlight=<kind> Highlight whitespace errors in the context, old or new lines of the diff. Multiple values are separated by comma, none resets previous values, default reset the list to new and all is a shorthand for old,new,context. When this option is not given, and the configuration variable diff.wsErrorHighlight is not set, only whitespace errors in new lines are highlighted. The whitespace errors are colored with color.diff.whitespace.
--full-index Instead of the first handful of characters, show the full pre- and post-image blob object names on the "index" line when generating patch format output.
--binary In addition to --full-index, output a binary diff that can be applied with git-apply. Implies --patch.
--abbrev[=<n>] Instead of showing the full 40-byte hexadecimal object name in diff-raw format output and diff-tree header lines, show the shortest prefix that is at least <n> hexdigits long that uniquely refers the object. In diff-patch output format, --full-index takes higher precedence, i.e. if --full-index is specified, full blob names will be shown regardless of --abbrev. Non default number of digits can be specified with --abbrev=<n>.
-B[<n>][/<m>], --break-rewrites[=[<n>][/<m>]] Break complete rewrite changes into pairs of delete and create. This serves two purposes:
It affects the way a change that amounts to a total rewrite of a file not as a series of deletion and insertion mixed together with a very few lines that happen to match textually as the context, but as a single deletion of everything old followed by a single insertion of everything new, and the number m controls this aspect of the -B option (defaults to 60%). -B/70% specifies that less than 30% of the original should remain in the result for Git to consider it a total rewrite (i.e. otherwise the resulting patch will be a series of deletion and insertion mixed together with context lines).
When used with -M, a totally-rewritten file is also considered as the source of a rename (usually -M only considers a file that disappeared as the source of a rename), and the number n controls this aspect of the -B option (defaults to 50%). -B20% specifies that a change with addition and deletion compared to 20% or more of the file’s size are eligible for being picked up as a possible source of a rename to another file.
-M[<n>], --find-renames[=<n>] Detect renames. If n is specified, it is a threshold on the similarity index (i.e. amount of addition/deletions compared to the file’s size). For example, -M90% means Git should consider a delete/add pair to be a rename if more than 90% of the file hasn’t changed. Without a % sign, the number is to be read as a fraction, with a decimal point before it. I.e., -M5 becomes 0.5, and is thus the same as -M50%. Similarly, -M05 is the same as -M5%. To limit detection to exact renames, use -M100%. The default similarity index is 50%.
-C[<n>], --find-copies[=<n>] Detect copies as well as renames. See also --find-copies-harder. If n is specified, it has the same meaning as for -M<n>.
--find-copies-harder For performance reasons, by default, -C option finds copies only if the original file of the copy was modified in the same changeset. This flag makes the command inspect unmodified files as candidates for the source of copy. This is a very expensive operation for large projects, so use it with caution. Giving more than one -C option has the same effect.
-D, --irreversible-delete Omit the preimage for deletes, i.e. print only the header but not the diff between the preimage and /dev/null. The resulting patch is not meant to be applied with patch or git apply; this is solely for people who want to just concentrate on reviewing the text after the change. In addition, the output obviously lacks enough information to apply such a patch in reverse, even manually, hence the name of the option.
When used together with -B, omit also the preimage in the deletion part of a delete/create pair.
-l<num> The -M and -C options involve some preliminary steps that can detect subsets of renames/copies cheaply, followed by an exhaustive fallback portion that compares all remaining unpaired destinations to all relevant sources. (For renames, only remaining unpaired sources are relevant; for copies, all original sources are relevant.) For N sources and destinations, this exhaustive check is O(N^2). This option prevents the exhaustive portion of rename/copy detection from running if the number of source/destination files involved exceeds the specified number. Defaults to diff.renameLimit. Note that a value of 0 is treated as unlimited.
--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]] Select only files that are Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type (i.e. regular file, symlink, submodule, ...) changed (T), are Unmerged (U), are Unknown (X), or have had their pairing Broken (B). Any combination of the filter characters (including none) can be used. When * (All-or-none) is added to the combination, all paths are selected if there is any file that matches other criteria in the comparison; if there is no file that matches other criteria, nothing is selected.
Also, these upper-case letters can be downcased to exclude. E.g. --diff-filter=ad excludes added and deleted paths.
Note that not all diffs can feature all types. For instance, copied and renamed entries cannot appear if detection for those types is disabled.
-S<string> Look for differences that change the number of occurrences of the specified string (i.e. addition/deletion) in a file. Intended for the scripter’s use.
It is useful when you’re looking for an exact block of code (like a struct), and want to know the history of that block since it first came into being: use the feature iteratively to feed the interesting block in the preimage back into -S, and keep going until you get the very first version of the block.
Binary files are searched as well.
-G<regex> Look for differences whose patch text contains added/removed lines that match <regex>.
To illustrate the difference between -S<regex> --pickaxe-regex and -G<regex>, consider a commit with the following diff in the same file:
+ return frotz(nitfol, two->ptr, 1, 0); ... - hit = frotz(nitfol, mf2.ptr, 1, 0);
While git log -G"frotz\(nitfol" will show this commit, git log -S"frotz\(nitfol" --pickaxe-regex will not (because the number of occurrences of that string did not change).
Unless --text is supplied patches of binary files without a textconv filter will be ignored.
See the pickaxe entry in gitdiffcore(7) for more information.
--find-object=<object-id> Look for differences that change the number of occurrences of the specified object. Similar to -S, just the argument is different in that it doesn’t search for a specific string but for a specific object id.
The object can be a blob or a submodule commit. It implies the -t option in git-log to also find trees.
--pickaxe-all When -S or -G finds a change, show all the changes in that changeset, not just the files that contain the change in <string>.
--pickaxe-regex Treat the <string> given to -S as an extended POSIX regular expression to match.
-O<orderfile> Control the order in which files appear in the output. This overrides the diff.orderFile configuration variable (see git‐config(1)). To cancel diff.orderFile, use -O/dev/null.
The output order is determined by the order of glob patterns in <orderfile>. All files with pathnames that match the first pattern are output first, all files with pathnames that match the second pattern (but not the first) are output next, and so on. All files with pathnames that do not match any pattern are output last, as if there was an implicit match-all pattern at the end of the file. If multiple pathnames have the same rank (they match the same pattern but no earlier patterns), their output order relative to each other is the normal order.
<orderfile> is parsed as follows:
• Blank lines are ignored, so they can be used as separators for readability.
• Lines starting with a hash ("#") are ignored, so they can be used for comments. Add a backslash ("\") to the beginning of the pattern if it starts with a hash.
• Each other line contains a single pattern.
Patterns have the same syntax and semantics as patterns used for fnmatch(3) without the FNM_PATHNAME flag, except a pathname also matches a pattern if removing any number of the final pathname components matches the pattern. For example, the pattern "foo*bar" matches "fooasdfbar" and "foo/bar/baz/asdf" but not "foobarx".
--skip-to=<file>, --rotate-to=<file> Discard the files before the named <file> from the output (i.e. skip to), or move them to the end of the output (i.e. rotate to). These were invented primarily for use of the git difftool command, and may not be very useful otherwise.
-R Swap two inputs; that is, show differences from index or on-disk file to tree contents.
--relative[=<path>], --no-relative When run from a subdirectory of the project, it can be told to exclude changes outside the directory and show pathnames relative to it with this option. When you are not in a subdirectory (e.g. in a bare repository), you can name which subdirectory to make the output relative to by giving a <path> as an argument. --no-relative can be used to countermand both diff.relative config option and previous --relative.
-a, --text Treat all files as text.
--ignore-cr-at-eol Ignore carriage-return at the end of line when doing a comparison.
--ignore-space-at-eol Ignore changes in whitespace at EOL.
-b, --ignore-space-change Ignore changes in amount of whitespace. This ignores whitespace at line end, and considers all other sequences of one or more whitespace characters to be equivalent.
-w, --ignore-all-space Ignore whitespace when comparing lines. This ignores differences even if one line has whitespace where the other line has none.
--ignore-blank-lines Ignore changes whose lines are all blank.
-I<regex>, --ignore-matching-lines=<regex> Ignore changes whose all lines match <regex>. This option may be specified more than once.
--inter-hunk-context=<lines> Show the context between diff hunks, up to the specified number of lines, thereby fusing hunks that are close to each other. Defaults to diff.interHunkContext or 0 if the config option is unset.
-W, --function-context Show whole function as context lines for each change. The function names are determined in the same way as git diff works out patch hunk headers (see Defining a custom hunk-header in gitattributes(5)).
--exit-code Make the program exit with codes similar to diff(1). That is, it exits with 1 if there were differences and 0 means no differences.
--quiet Disable all output of the program. Implies --exit-code.
--ext-diff Allow an external diff helper to be executed. If you set an external diff driver with gitattributes(5), you need to use this option with git‐log(1) and friends.
--no-ext-diff Disallow external diff drivers.
--textconv, --no-textconv Allow (or disallow) external text conversion filters to be run when comparing binary files. See gitattributes(5) for details. Because textconv filters are typically a one-way conversion, the resulting diff is suitable for human consumption, but cannot be applied. For this reason, textconv filters are enabled by default only for git‐ diff(1) and git‐log(1), but not for git‐format‐patch(1) or diff plumbing commands.
--ignore-submodules[=<when>] Ignore changes to submodules in the diff generation. <when> can be either "none", "untracked", "dirty" or "all", which is the default. Using "none" will consider the submodule modified when it either contains untracked or modified files or its HEAD differs from the commit recorded in the superproject and can be used to override any settings of the ignore option in git‐config(1) or gitmodules(5). When "untracked" is used submodules are not considered dirty when they only contain untracked content (but they are still scanned for modified content). Using "dirty" ignores all changes to the work tree of submodules, only changes to the commits stored in the superproject are shown (this was the behavior until 1.7.0). Using "all" hides all changes to submodules.
--src-prefix=<prefix> Show the given source prefix instead of "a/".
--dst-prefix=<prefix> Show the given destination prefix instead of "b/".
--no-prefix Do not show any source or destination prefix.
--line-prefix=<prefix> Prepend an additional prefix to every line of output.
--ita-invisible-in-index By default entries added by "git add -N" appear as an existing empty file in "git diff" and a new file in "git diff --cached". This option makes the entry appear as a new file in "git diff" and non-existent in "git diff --cached". This option could be reverted with --ita-visible-in-index. Both options are experimental and could be removed in future.
For more detailed explanation on these common options, see also gitdiffcore(7).
-1 --base, -2 --ours, -3 --theirs Compare the working tree with the "base" version (stage #1), "our branch" (stage #2) or "their branch" (stage #3). The index contains these stages only for unmerged entries i.e. while resolving conflicts. See git‐read‐tree(1) section "3-Way Merge" for detailed information.
-0 Omit diff output for unmerged entries and just show "Unmerged". Can be used only when comparing the working tree with the index.
<path>... The <paths> parameters, when given, are used to limit the diff to the named paths (you can give directory names and get diff for all files under them).
RAW OUTPUT FORMAT The raw output format from "git-diff-index", "git-diff-tree", "git-diff-files" and "git diff --raw" are very similar.
These commands all compare two sets of things; what is compared differs:
git-diff-index <tree-ish> compares the <tree-ish> and the files on the filesystem.
git-diff-index --cached <tree-ish> compares the <tree-ish> and the index.
git-diff-tree [-r] <tree-ish-1> <tree-ish-2> [<pattern>...] compares the trees named by the two arguments.
git-diff-files [<pattern>...] compares the index and the files on the filesystem.
The "git-diff-tree" command begins its output by printing the hash of what is being compared. After that, all the commands print one output line per changed file.
An output line is formatted this way:
in-place edit :100644 100644 bcd1234 0123456 M file0 copy-edit :100644 100644 abcd123 1234567 C68 file1 file2 rename-edit :100644 100644 abcd123 1234567 R86 file1 file3 create :000000 100644 0000000 1234567 A file4 delete :100644 000000 1234567 0000000 D file5 unmerged :000000 000000 0000000 0000000 U file6
That is, from the left to the right:
1. a colon.
2. mode for "src"; 000000 if creation or unmerged.
3. a space.
4. mode for "dst"; 000000 if deletion or unmerged.
5. a space.
6. sha1 for "src"; 0{40} if creation or unmerged.
7. a space.
8. sha1 for "dst"; 0{40} if deletion, unmerged or "work tree out of sync with the index".
9. a space.
10. status, followed by optional "score" number.
11. a tab or a NUL when -z option is used.
12. path for "src"
13. a tab or a NUL when -z option is used; only exists for C or R.
14. path for "dst"; only exists for C or R.
15. an LF or a NUL when -z option is used, to terminate the record.
Possible status letters are:
• A: addition of a file
• C: copy of a file into a new one
• D: deletion of a file
• M: modification of the contents or mode of a file
• R: renaming of a file
• T: change in the type of the file (regular file, symbolic link or submodule)
• U: file is unmerged (you must complete the merge before it can be committed)
• X: "unknown" change type (most probably a bug, please report it)
Status letters C and R are always followed by a score (denoting the percentage of similarity between the source and target of the move or copy). Status letter M may be followed by a score (denoting the percentage of dissimilarity) for file rewrites.
The sha1 for "dst" is shown as all 0’s if a file on the filesystem is out of sync with the index.
Example:
:100644 100644 5be4a4a 0000000 M file.c
Without the -z option, pathnames with "unusual" characters are quoted as explained for the configuration variable core.quotePath (see git‐config(1)). Using -z the filename is output verbatim and the line is terminated by a NUL byte.
DIFF FORMAT FOR MERGES "git-diff-tree", "git-diff-files" and "git-diff --raw" can take -c or --cc option to generate diff output also for merge commits. The output differs from the format described above in the following way:
1. there is a colon for each parent
2. there are more "src" modes and "src" sha1
3. status is concatenated status characters for each parent
4. no optional "score" number
5. tab-separated pathname(s) of the file
For -c and --cc, only the destination or final path is shown even if the file was renamed on any side of history. With --combined-all-paths, the name of the path in each parent is shown followed by the name of the path in the merge commit.
Examples for -c and --cc without --combined-all-paths:
::100644 100644 100644 fabadb8 cc95eb0 4866510 MM desc.c ::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM bar.sh ::100644 100644 100644 e07d6c5 9042e82 ee91881 RR phooey.c
Examples when --combined-all-paths added to either -c or --cc:
::100644 100644 100644 fabadb8 cc95eb0 4866510 MM desc.c desc.c desc.c ::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM foo.sh bar.sh bar.sh ::100644 100644 100644 e07d6c5 9042e82 ee91881 RR fooey.c fuey.c phooey.c
Note that combined diff lists only files which were modified from all parents.
GENERATING PATCH TEXT WITH -P Running git‐diff(1), git‐log(1), git‐show(1), git‐diff‐ index(1), git‐diff‐tree(1), or git‐diff‐files(1) with the -p option produces patch text. You can customize the creation of patch text via the GIT_EXTERNAL_DIFF and the GIT_DIFF_OPTS environment variables (see git(1)), and the diff attribute (see gitattributes(5)).
What the -p option produces is slightly different from the traditional diff format:
1. It is preceded with a "git diff" header that looks like this:
diff --git a/file1 b/file2
The a/ and b/ filenames are the same unless rename/copy is involved. Especially, even for a creation or a deletion, /dev/null is not used in place of the a/ or b/ filenames.
When rename/copy is involved, file1 and file2 show the name of the source file of the rename/copy and the name of the file that rename/copy produces, respectively.
2. It is followed by one or more extended header lines:
old mode <mode> new mode <mode> deleted file mode <mode> new file mode <mode> copy from <path> copy to <path> rename from <path> rename to <path> similarity index <number> dissimilarity index <number> index <hash>..<hash> <mode>
File modes are printed as 6-digit octal numbers including the file type and file permission bits.
Path names in extended headers do not include the a/ and b/ prefixes.
The similarity index is the percentage of unchanged lines, and the dissimilarity index is the percentage of changed lines. It is a rounded down integer, followed by a percent sign. The similarity index value of 100% is thus reserved for two equal files, while 100% dissimilarity means that no line from the old file made it into the new one.
The index line includes the blob object names before and after the change. The <mode> is included if the file mode does not change; otherwise, separate lines indicate the old and the new mode.
3. Pathnames with "unusual" characters are quoted as explained for the configuration variable core.quotePath (see git‐ config(1)).
4. All the file1 files in the output refer to files before the commit, and all the file2 files refer to files after the commit. It is incorrect to apply each change to each file sequentially. For example, this patch will swap a and b:
diff --git a/a b/b rename from a rename to b diff --git a/b b/a rename from b rename to a
5. Hunk headers mention the name of the function to which the hunk applies. See "Defining a custom hunk-header" in gitattributes(5) for details of how to tailor to this to specific languages.
COMBINED DIFF FORMAT Any diff-generating command can take the -c or --cc option to produce a combined diff when showing a merge. This is the default format when showing merges with git‐diff(1) or git‐ show(1). Note also that you can give suitable --diff-merges option to any of these commands to force generation of diffs in specific format.
A "combined diff" format looks like this:
diff --combined describe.c index fabadb8,cc95eb0..4866510 --- a/describe.c +++ b/describe.c @@@ -98,20 -98,12 +98,20 @@@ return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1; }
- static void describe(char *arg) -static void describe(struct commit *cmit, int last_one) ++static void describe(char *arg, int last_one) { + unsigned char sha1[20]; + struct commit *cmit; struct commit_list *list; static int initialized = 0; struct commit_name *n;
+ if (get_sha1(arg, sha1) < 0) + usage(describe_usage); + cmit = lookup_commit_reference(sha1); + if (!cmit) + usage(describe_usage); + if (!initialized) { initialized = 1; for_each_ref(get_name);
1. It is preceded with a "git diff" header, that looks like this (when the -c option is used):
diff --combined file
or like this (when the --cc option is used):
diff --cc file
2. It is followed by one or more extended header lines (this example shows a merge with two parents):
index <hash>,<hash>..<hash> mode <mode>,<mode>..<mode> new file mode <mode> deleted file mode <mode>,<mode>
The mode <mode>,<mode>..<mode> line appears only if at least one of the <mode> is different from the rest. Extended headers with information about detected contents movement (renames and copying detection) are designed to work with diff of two <tree-ish> and are not used by combined diff format.
3. It is followed by two-line from-file/to-file header
--- a/file +++ b/file
Similar to two-line header for traditional unified diff format, /dev/null is used to signal created or deleted files.
However, if the --combined-all-paths option is provided, instead of a two-line from-file/to-file you get a N+1 line from-file/to-file header, where N is the number of parents in the merge commit
--- a/file --- a/file --- a/file +++ b/file
This extended format can be useful if rename or copy detection is active, to allow you to see the original name of the file in different parents.
4. Chunk header format is modified to prevent people from accidentally feeding it to patch -p1. Combined diff format was created for review of merge commit changes, and was not meant to be applied. The change is similar to the change in the extended index header:
@@@ <from-file-range> <from-file-range> <to-file-range> @@@
There are (number of parents + 1) @ characters in the chunk header for combined diff format.
Unlike the traditional unified diff format, which shows two files A and B with a single column that has - (minus — appears in A but removed in B), + (plus — missing in A but added to B), or " " (space — unchanged) prefix, this format compares two or more files file1, file2,... with one file X, and shows how X differs from each of fileN. One column for each of fileN is prepended to the output line to note how X’s line is different from it.
A - character in the column N means that the line appears in fileN but it does not appear in the result. A + character in the column N means that the line appears in the result, and fileN does not have that line (in other words, the line was added, from the point of view of that parent).
In the above example output, the function signature was changed from both files (hence two - removals from both file1 and file2, plus ++ to mean one line that was added does not appear in either file1 or file2). Also eight other lines are the same from file1 but do not appear in file2 (hence prefixed with +).
When shown by git diff-tree -c, it compares the parents of a merge commit with the merge result (i.e. file1..fileN are the parents). When shown by git diff-files -c, it compares the two unresolved merge parents with the working tree file (i.e. file1 is stage 2 aka "our version", file2 is stage 3 aka "their version").
OTHER DIFF FORMATS The --summary option describes newly added, deleted, renamed and copied files. The --stat option adds diffstat(1) graph to the output. These options can be combined with other options, such as -p, and are meant for human consumption.
When showing a change that involves a rename or a copy, --stat output formats the pathnames compactly by combining common prefix and suffix of the pathnames. For example, a change that moves arch/i386/Makefile to arch/x86/Makefile while modifying 4 lines will be shown like this:
arch/{i386 => x86}/Makefile | 4 +--
The --numstat option gives the diffstat(1) information but is designed for easier machine consumption. An entry in --numstat output looks like this:
1 2 README 3 1 arch/{i386 => x86}/Makefile
That is, from left to right:
1. the number of added lines;
2. a tab;
3. the number of deleted lines;
4. a tab;
5. pathname (possibly with rename/copy information);
6. a newline.
When -z output option is in effect, the output is formatted this way:
1 2 README NUL 3 1 NUL arch/i386/Makefile NUL arch/x86/Makefile NUL
That is:
1. the number of added lines;
2. a tab;
3. the number of deleted lines;
4. a tab;
5. a NUL (only exists if renamed/copied);
6. pathname in preimage;
7. a NUL (only exists if renamed/copied);
8. pathname in postimage (only exists if renamed/copied);
9. a NUL.
The extra NUL before the preimage path in renamed case is to allow scripts that read the output to tell if the current record being read is a single-path record or a rename/copy record without reading ahead. After reading added and deleted lines, reading up to NUL would yield the pathname, but if that is NUL, the record will show two paths.
EXAMPLES Various ways to check your working tree
$ git diff (1) $ git diff --cached (2) $ git diff HEAD (3)
1. Changes in the working tree not yet staged for the next commit. 2. Changes between the index and your last commit; what you would be committing if you run git commit without -a option. 3. Changes in the working tree since your last commit; what you would be committing if you run git commit -a
Comparing with arbitrary commits
$ git diff test (1) $ git diff HEAD -- ./test (2) $ git diff HEAD^ HEAD (3)
1. Instead of using the tip of the current branch, compare with the tip of "test" branch. 2. Instead of comparing with the tip of "test" branch, compare with the tip of the current branch, but limit the comparison to the file "test". 3. Compare the version before the last commit and the last commit.
Comparing branches
$ git diff topic master (1) $ git diff topic..master (2) $ git diff topic...master (3)
1. Changes between the tips of the topic and the master branches. 2. Same as above. 3. Changes that occurred on the master branch since when the topic branch was started off it.
Limiting the diff output
$ git diff --diff-filter=MRC (1) $ git diff --name-status (2) $ git diff arch/i386 include/asm-i386 (3)
1. Show only modification, rename, and copy, but not addition or deletion. 2. Show only names and the nature of change, but not actual diff output. 3. Limit diff output to named subtrees.
Munging the diff output
$ git diff --find-copies-harder -B -C (1) $ git diff -R (2)
1. Spend extra cycles to find renames, copies and complete rewrites (very expensive). 2. Output diff in reverse.
CONFIGURATION Everything below this line in this section is selectively included from the git‐config(1) documentation. The content is the same as what’s found there:
diff.autoRefreshIndex When using git diff to compare with work tree files, do not consider stat-only change as changed. Instead, silently run git update-index --refresh to update the cached stat information for paths whose contents in the work tree match the contents in the index. This option defaults to true. Note that this affects only git diff Porcelain, and not lower level diff commands such as git diff-files.
diff.dirstat A comma separated list of --dirstat parameters specifying the default behavior of the --dirstat option to git‐diff(1) and friends. The defaults can be overridden on the command line (using --dirstat=<param1,param2,...>). The fallback defaults (when not changed by diff.dirstat) are changes,noncumulative,3. The following parameters are available:
changes Compute the dirstat numbers by counting the lines that have been removed from the source, or added to the destination. This ignores the amount of pure code movements within a file. In other words, rearranging lines in a file is not counted as much as other changes. This is the default behavior when no parameter is given.
lines Compute the dirstat numbers by doing the regular line-based diff analysis, and summing the removed/added line counts. (For binary files, count 64-byte chunks instead, since binary files have no natural concept of lines). This is a more expensive --dirstat behavior than the changes behavior, but it does count rearranged lines within a file as much as other changes. The resulting output is consistent with what you get from the other --*stat options.
files Compute the dirstat numbers by counting the number of files changed. Each changed file counts equally in the dirstat analysis. This is the computationally cheapest --dirstat behavior, since it does not have to look at the file contents at all.
cumulative Count changes in a child directory for the parent directory as well. Note that when using cumulative, the sum of the percentages reported may exceed 100%. The default (non-cumulative) behavior can be specified with the noncumulative parameter.
<limit> An integer parameter specifies a cut-off percent (3% by default). Directories contributing less than this percentage of the changes are not shown in the output.
Example: The following will count changed files, while ignoring directories with less than 10% of the total amount of changed files, and accumulating child directory counts in the parent directories: files,10,cumulative.
diff.statGraphWidth Limit the width of the graph part in --stat output. If set, applies to all commands generating --stat output except format-patch.
diff.context Generate diffs with <n> lines of context instead of the default of 3. This value is overridden by the -U option.
diff.interHunkContext Show the context between diff hunks, up to the specified number of lines, thereby fusing the hunks that are close to each other. This value serves as the default for the --inter-hunk-context command line option.
diff.external If this config variable is set, diff generation is not performed using the internal diff machinery, but using the given command. Can be overridden with the ‘GIT_EXTERNAL_DIFF’ environment variable. The command is called with parameters as described under "git Diffs" in git(1). Note: if you want to use an external diff program only on a subset of your files, you might want to use gitattributes(5) instead.
diff.ignoreSubmodules Sets the default value of --ignore-submodules. Note that this affects only git diff Porcelain, and not lower level diff commands such as git diff-files. git checkout and git switch also honor this setting when reporting uncommitted changes. Setting it to all disables the submodule summary normally shown by git commit and git status when status.submoduleSummary is set unless it is overridden by using the --ignore-submodules command-line option. The git submodule commands are not affected by this setting. By default this is set to untracked so that any untracked submodules are ignored.
diff.mnemonicPrefix If set, git diff uses a prefix pair that is different from the standard "a/" and "b/" depending on what is being compared. When this configuration is in effect, reverse diff output also swaps the order of the prefixes:
git diff compares the (i)ndex and the (w)ork tree;
git diff HEAD compares a (c)ommit and the (w)ork tree;
git diff --cached compares a (c)ommit and the (i)ndex;
git diff HEAD:file1 file2 compares an (o)bject and a (w)ork tree entity;
git diff --no-index a b compares two non-git things (1) and (2).
diff.noprefix If set, git diff does not show any source or destination prefix.
diff.relative If set to true, git diff does not show changes outside of the directory and show pathnames relative to the current directory.
diff.orderFile File indicating how to order files within a diff. See the -O option to git‐diff(1) for details. If diff.orderFile is a relative pathname, it is treated as relative to the top of the working tree.
diff.renameLimit The number of files to consider in the exhaustive portion of copy/rename detection; equivalent to the git diff option -l. If not set, the default value is currently 1000. This setting has no effect if rename detection is turned off.
diff.renames Whether and how Git detects renames. If set to "false", rename detection is disabled. If set to "true", basic rename detection is enabled. If set to "copies" or "copy", Git will detect copies, as well. Defaults to true. Note that this affects only git diff Porcelain like git‐diff(1) and git‐log(1), and not lower level commands such as git‐ diff‐files(1).
diff.suppressBlankEmpty A boolean to inhibit the standard behavior of printing a space before each empty output line. Defaults to false.
diff.submodule Specify the format in which differences in submodules are shown. The "short" format just shows the names of the commits at the beginning and end of the range. The "log" format lists the commits in the range like git‐submodule(1) summary does. The "diff" format shows an inline diff of the changed contents of the submodule. Defaults to "short".
diff.wordRegex A POSIX Extended Regular Expression used to determine what is a "word" when performing word-by-word difference calculations. Character sequences that match the regular expression are "words", all other characters are ignorable whitespace.
diff.<driver>.command The custom diff driver command. See gitattributes(5) for details.
diff.<driver>.xfuncname The regular expression that the diff driver should use to recognize the hunk header. A built-in pattern may also be used. See gitattributes(5) for details.
diff.<driver>.binary Set this option to true to make the diff driver treat files as binary. See gitattributes(5) for details.
diff.<driver>.textconv The command that the diff driver should call to generate the text-converted version of a file. The result of the conversion is used to generate a human-readable diff. See gitattributes(5) for details.
diff.<driver>.wordRegex The regular expression that the diff driver should use to split words in a line. See gitattributes(5) for details.
diff.<driver>.cachetextconv Set this option to true to make the diff driver cache the text conversion outputs. See gitattributes(5) for details.
araxis Use Araxis Merge (requires a graphical session)
bc Use Beyond Compare (requires a graphical session)
bc3 Use Beyond Compare (requires a graphical session)
bc4 Use Beyond Compare (requires a graphical session)
codecompare Use Code Compare (requires a graphical session)
deltawalker Use DeltaWalker (requires a graphical session)
diffmerge Use DiffMerge (requires a graphical session)
diffuse Use Diffuse (requires a graphical session)
ecmerge Use ECMerge (requires a graphical session)
emerge Use Emacs' Emerge
examdiff Use ExamDiff Pro (requires a graphical session)
guiffy Use Guiffy’s Diff Tool (requires a graphical session)
gvimdiff Use gVim (requires a graphical session)
kdiff3 Use KDiff3 (requires a graphical session)
kompare Use Kompare (requires a graphical session)
meld Use Meld (requires a graphical session)
nvimdiff Use Neovim
opendiff Use FileMerge (requires a graphical session)
p4merge Use HelixCore P4Merge (requires a graphical session)
smerge Use Sublime Merge (requires a graphical session)
tkdiff Use TkDiff (requires a graphical session)
vimdiff Use Vim
winmerge Use WinMerge (requires a graphical session)
xxdiff Use xxdiff (requires a graphical session)
diff.indentHeuristic Set this option to false to disable the default heuristics that shift diff hunk boundaries to make patches easier to read.
diff.algorithm Choose a diff algorithm. The variants are as follows:
default, myers The basic greedy diff algorithm. Currently, this is the default.
minimal Spend extra time to make sure the smallest possible diff is produced.
patience Use "patience diff" algorithm when generating patches.
histogram This algorithm extends the patience algorithm to "support low-occurrence common elements".
diff.wsErrorHighlight Highlight whitespace errors in the context, old or new lines of the diff. Multiple values are separated by comma, none resets previous values, default reset the list to new and all is a shorthand for old,new,context. The whitespace errors are colored with color.diff.whitespace. The command line option --ws-error-highlight=<kind> overrides this setting.
diff.colorMoved If set to either a valid <mode> or a true value, moved lines in a diff are colored differently, for details of valid modes see --color-moved in git‐diff(1). If simply set to true the default color mode will be used. When set to false, moved lines are not colored.
diff.colorMovedWS When moved lines are colored using e.g. the diff.colorMoved setting, this option controls the <mode> how spaces are treated for details of valid modes see --color-moved-ws in git‐diff(1).
SEE ALSO diff(1), git‐difftool(1), git‐log(1), gitdiffcore(7), git‐ format‐patch(1), git‐apply(1), git‐show(1)
GIT Part of the git(1) suite
Git 2.40.1 05/18/2023 GIT-DIFF(1)

To create a patch between HEAD and the previous commit:

Shell
$ git diff HEAD HEAD~1
diff --git a/_sass/jekyll_img.scss b/_sass/jekyll_img.scss
index 31ae65c8..2981b79d 100644
--- a/_sass/jekyll_img.scss
+++ b/_sass/jekyll_img.scss
@@ -32,9 +32,9 @@ td.center {
  /* Center captions within div.imgWrapper */
  .imgFigCaption {
    hyphens: none;
-  width: 100%;
+  min-width: 100%;
    text-align: center;
-  width: min-content;
+  width: max-content;
  }
/* Marker class applied to <img> tag */ diff --git a/collections/_llm/500-whisper.html b/collections/_llm/500-whisper.html index 7b74a761..79bb7625 100644 --- a/collections/_llm/500-whisper.html +++ b/collections/_llm/500-whisper.html @@ -17,7 +17,6 @@ title: 'OpenAI Whisper' </p> {% img caption="Whisper’s performance (left) is close to the performance of a professional human transcriber. It is best in class of LLMs (A-D in figure), but can’t beat computer-assisted (E in figure) transcription" - size="100%" src="./images/whisper_rank.webp" url="https://generativeai.net/campaigns/view-campaign/Bk7x68hty0FKSXFLDBacH7Nfti_5ifC6ZxfIUiGMyUC0aTUUCI2AWj7oCs20TcANxm6U2hHJJq4s4tys-ybajYBSM7fsZyKX#:~:text=In%20the%20following%20figure%2C%20one,figure)%20transcription%20%5B6%5D." %}

Git-Hash-Object

Computes the object id (oid) for an object, and optionally store it as a blog.

Shell
$ git help hash-object
GIT-HASH-OBJECT(1)            Git Manual            GIT-HASH-OBJECT(1)
NAME git‐hash‐object - Compute object ID and optionally creates a blob from a file
SYNOPSIS git hash-object [-t <type>] [-w] [--path=<file> | --no-filters] [--stdin [--literally]] [--] <file>... git hash-object [-t <type>] [-w] --stdin-paths [--no-filters]
DESCRIPTION Computes the object ID value for an object with specified type with the contents of the named file (which can be outside of the work tree), and optionally writes the resulting object into the object database. Reports its object ID to its standard output. When <type> is not specified, it defaults to "blob".
OPTIONS -t <type> Specify the type (default: "blob").
-w Actually write the object into the object database.
--stdin Read the object from standard input instead of from a file.
--stdin-paths Read file names from the standard input, one per line, instead of from the command-line.
--path Hash object as it were located at the given path. The location of file does not directly influence on the hash value, but path is used to determine what Git filters should be applied to the object before it can be placed to the object database, and, as result of applying filters, the actual blob put into the object database may differ from the given file. This option is mainly useful for hashing temporary files located outside of the working directory or files read from stdin.
--no-filters Hash the contents as is, ignoring any input filter that would have been chosen by the attributes mechanism, including the end-of-line conversion. If the file is read from standard input then this is always implied, unless the --path option is given.
--literally Allow --stdin to hash any garbage into a loose object which might not otherwise pass standard object parsing or git-fsck checks. Useful for stress-testing Git itself or reproducing characteristics of corrupt or bogus objects encountered in the wild.
GIT Part of the git(1) suite
Git 2.40.1 05/18/2023 GIT-HASH-OBJECT(1)
hash-object from stdin
$ echo 'test content' | git hash-object --stdin
d670460b4b4aece5915caf5c68d12f560a9fe3e4 

Git-Log

Git log is flexible and powerful. Here is the help message

Shell
$ git help log
GIT-LOG(1)                    Git Manual                    GIT-LOG(1)
NAME git‐log - Show commit logs
SYNOPSIS git log [<options>] [<revision-range>] [[--] <path>...]
DESCRIPTION Shows the commit logs.
List commits that are reachable by following the parent links from the given commit(s), but exclude commits that are reachable from the one(s) given with a ^ in front of them. The output is given in reverse chronological order by default.
You can think of this as a set operation. Commits reachable from any of the commits given on the command line form a set, and then commits reachable from any of the ones given with ^ in front are subtracted from that set. The remaining commits are what comes out in the command’s output. Various other options and paths parameters can be used to further limit the result.
Thus, the following command:
$ git log foo bar ^baz
means "list all the commits which are reachable from foo or bar, but not from baz".
A special notation "<commit1>..<commit2>" can be used as a short-hand for "^<commit1> <commit2>". For example, either of the following may be used interchangeably:
$ git log origin..HEAD $ git log HEAD ^origin
Another special notation is "<commit1>...<commit2>" which is useful for merges. The resulting set of commits is the symmetric difference between the two operands. The following two commands are equivalent:
$ git log A B --not $(git merge-base --all A B) $ git log A...B
The command takes options applicable to the git‐rev‐list(1) command to control what is shown and how, and options applicable to the git‐diff(1) command to control how the changes each commit introduces are shown.
OPTIONS --follow Continue listing the history of a file beyond renames (works only for a single file).
--no-decorate, --decorate[=short|full|auto|no] Print out the ref names of any commits that are shown. If short is specified, the ref name prefixes refs/heads/, refs/tags/ and refs/remotes/ will not be printed. If full is specified, the full ref name (including prefix) will be printed. If auto is specified, then if the output is going to a terminal, the ref names are shown as if short were given, otherwise no ref names are shown. The option --decorate is short-hand for --decorate=short. Default to configuration value of log.decorate if configured, otherwise, auto.
--decorate-refs=<pattern>, --decorate-refs-exclude=<pattern> For each candidate reference, do not use it for decoration if it matches any patterns given to --decorate-refs-exclude or if it doesn’t match any of the patterns given to --decorate-refs. The log.excludeDecoration config option allows excluding refs from the decorations, but an explicit --decorate-refs pattern will override a match in log.excludeDecoration.
If none of these options or config settings are given, then references are used as decoration if they match HEAD, refs/heads/, refs/remotes/, refs/stash/, or refs/tags/.
--clear-decorations When specified, this option clears all previous --decorate-refs or --decorate-refs-exclude options and relaxes the default decoration filter to include all references. This option is assumed if the config value log.initialDecorationSet is set to all.
--source Print out the ref name given on the command line by which each commit was reached.
--[no-]mailmap, --[no-]use-mailmap Use mailmap file to map author and committer names and email addresses to canonical real names and email addresses. See git‐shortlog(1).
--full-diff Without this flag, git log -p <path>... shows commits that touch the specified paths, and diffs about the same specified paths. With this, the full diff is shown for commits that touch the specified paths; this means that "<path>..." limits only commits, and doesn’t limit diff for those commits.
Note that this affects all diff-based output types, e.g. those produced by --stat, etc.
--log-size Include a line “log size <number>” in the output for each commit, where <number> is the length of that commit’s message in bytes. Intended to speed up tools that read log messages from git log output by allowing them to allocate space in advance.
-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 gitattributes(5)).
<revision-range> Show only commits in the specified revision range. When no <revision-range> is specified, it defaults to HEAD (i.e. the whole history leading to the current commit). origin..HEAD specifies all the commits reachable from the current commit (i.e. HEAD), but not from origin. For a complete list of ways to spell <revision-range>, see the Specifying Ranges section of gitrevisions(7).
[--] <path>... Show only commits that are enough to explain how the files that match the specified paths came to be. See History Simplification below for details and other simplification modes.
Paths may need to be prefixed with -- to separate them from options or the revision range, when confusion arises.
Commit Limiting Besides specifying a range of commits that should be listed using the special notations explained in the description, additional commit limiting may be applied.
Using more options generally further limits the output (e.g. --since=<date1> limits to commits newer than <date1>, and using it with --grep=<pattern> further limits to commits whose log message has a line that matches <pattern>), unless otherwise noted.
Note that these are applied before commit ordering and formatting options, such as --reverse.
-<number>, -n <number>, --max-count=<number> Limit the number of commits to output.
--skip=<number> Skip number commits before starting to show the commit output.
--since=<date>, --after=<date> Show commits more recent than a specific date.
--since-as-filter=<date> Show all commits more recent than a specific date. This visits all commits in the range, rather than stopping at the first commit which is older than a specific date.
--until=<date>, --before=<date> Show commits older than a specific date.
--author=<pattern>, --committer=<pattern> Limit the commits output to ones with author/committer header lines that match the specified pattern (regular expression). With more than one --author=<pattern>, commits whose author matches any of the given patterns are chosen (similarly for multiple --committer=<pattern>).
--grep-reflog=<pattern> Limit the commits output to ones with reflog entries that match the specified pattern (regular expression). With more than one --grep-reflog, commits whose reflog message matches any of the given patterns are chosen. It is an error to use this option unless --walk-reflogs is in use.
--grep=<pattern> Limit the commits output to ones with log message that matches the specified pattern (regular expression). With more than one --grep=<pattern>, commits whose message matches any of the given patterns are chosen (but see --all-match).
When --notes is in effect, the message from the notes is matched as if it were part of the log message.
--all-match Limit the commits output to ones that match all given --grep, instead of ones that match at least one.
--invert-grep Limit the commits output to ones with log message that do not match the pattern specified with --grep=<pattern>.
-i, --regexp-ignore-case Match the regular expression limiting patterns without regard to letter case.
--basic-regexp Consider the limiting patterns to be basic regular expressions; this is the default.
-E, --extended-regexp Consider the limiting patterns to be extended regular expressions instead of the default basic regular expressions.
-F, --fixed-strings Consider the limiting patterns to be fixed strings (don’t interpret pattern as a regular expression).
-P, --perl-regexp Consider the limiting patterns to be Perl-compatible regular expressions.
Support for these types of regular expressions is an optional compile-time dependency. If Git wasn’t compiled with support for them providing this option will cause it to die.
--remove-empty Stop when a given path disappears from the tree.
--merges Print only merge commits. This is exactly the same as --min-parents=2.
--no-merges Do not print commits with more than one parent. This is exactly the same as --max-parents=1.
--min-parents=<number>, --max-parents=<number>, --no-min-parents, --no-max-parents Show only commits which have at least (or at most) that many parent commits. In particular, --max-parents=1 is the same as --no-merges, --min-parents=2 is the same as --merges. --max-parents=0 gives all root commits and --min-parents=3 all octopus merges.
--no-min-parents and --no-max-parents reset these limits (to no limit) again. Equivalent forms are --min-parents=0 (any commit has 0 or more parents) and --max-parents=-1 (negative numbers denote no upper limit).
--first-parent When finding commits to include, follow only the first parent commit upon seeing a merge commit. This option can give a better overview when viewing the evolution of a particular topic branch, because merges into a topic branch tend to be only about adjusting to updated upstream from time to time, and this option allows you to ignore the individual commits brought in to your history by such a merge.
This option also changes default diff format for merge commits to first-parent, see --diff-merges=first-parent for details.
--exclude-first-parent-only When finding commits to exclude (with a ^), follow only the first parent commit upon seeing a merge commit. This can be used to find the set of changes in a topic branch from the point where it diverged from the remote branch, given that arbitrary merges can be valid topic branch changes.
--not Reverses the meaning of the ^ prefix (or lack thereof) for all following revision specifiers, up to the next --not.
--all Pretend as if all the refs in refs/, along with HEAD, are listed on the command line as <commit>.
--branches[=<pattern>] Pretend as if all the refs in refs/heads are listed on the command line as <commit>. If <pattern> is given, limit branches to ones matching given shell glob. If pattern lacks ?, *, or [, /* at the end is implied.
--tags[=<pattern>] Pretend as if all the refs in refs/tags are listed on the command line as <commit>. If <pattern> is given, limit tags to ones matching given shell glob. If pattern lacks ?, *, or [, /* at the end is implied.
--remotes[=<pattern>] Pretend as if all the refs in refs/remotes are listed on the command line as <commit>. If <pattern> is given, limit remote-tracking branches to ones matching given shell glob. If pattern lacks ?, *, or [, /* at the end is implied.
--glob=<glob-pattern> Pretend as if all the refs matching shell glob <glob-pattern> are listed on the command line as <commit>. Leading refs/, is automatically prepended if missing. If pattern lacks ?, *, or [, /* at the end is implied.
--exclude=<glob-pattern> Do not include refs matching <glob-pattern> that the next --all, --branches, --tags, --remotes, or --glob would otherwise consider. Repetitions of this option accumulate exclusion patterns up to the next --all, --branches, --tags, --remotes, or --glob option (other options or arguments do not clear accumulated patterns).
The patterns given should not begin with refs/heads, refs/tags, or refs/remotes when applied to --branches, --tags, or --remotes, respectively, and they must begin with refs/ when applied to --glob or --all. If a trailing /* is intended, it must be given explicitly.
--exclude-hidden=[receive|uploadpack] Do not include refs that would be hidden by git-receive-pack or git-upload-pack by consulting the appropriate receive.hideRefs or uploadpack.hideRefs configuration along with transfer.hideRefs (see git‐ config(1)). This option affects the next pseudo-ref option --all or --glob and is cleared after processing them.
--reflog Pretend as if all objects mentioned by reflogs are listed on the command line as <commit>.
--alternate-refs Pretend as if all objects mentioned as ref tips of alternate repositories were listed on the command line. An alternate repository is any repository whose object directory is specified in objects/info/alternates. The set of included objects may be modified by core.alternateRefsCommand, etc. See git‐config(1).
--single-worktree By default, all working trees will be examined by the following options when there are more than one (see git‐ worktree(1)): --all, --reflog and --indexed-objects. This option forces them to examine the current working tree only.
--ignore-missing Upon seeing an invalid object name in the input, pretend as if the bad input was not given.
--bisect Pretend as if the bad bisection ref refs/bisect/bad was listed and as if it was followed by --not and the good bisection refs refs/bisect/good-* on the command line.
--stdin In addition to the <commit> listed on the command line, read them from the standard input. If a -- separator is seen, stop reading commits and start reading paths to limit the result.
--cherry-mark Like --cherry-pick (see below) but mark equivalent commits with = rather than omitting them, and inequivalent ones with +.
--cherry-pick Omit any commit that introduces the same change as another commit on the “other side” when the set of commits are limited with symmetric difference.
For example, if you have two branches, A and B, a usual way to list all commits on only one side of them is with --left-right (see the example below in the description of the --left-right option). However, it shows the commits that were cherry-picked from the other branch (for example, “3rd on b” may be cherry-picked from branch A). With this option, such pairs of commits are excluded from the output.
--left-only, --right-only List only commits on the respective side of a symmetric difference, i.e. only those which would be marked < resp. > by --left-right.
For example, --cherry-pick --right-only A...B omits those commits from B which are in A or are patch-equivalent to a commit in A. In other words, this lists the + commits from git cherry A B. More precisely, --cherry-pick --right-only --no-merges gives the exact list.
--cherry A synonym for --right-only --cherry-mark --no-merges; useful to limit the output to the commits on our side and mark those that have been applied to the other side of a forked history with git log --cherry upstream...mybranch, similar to git cherry upstream mybranch.
-g, --walk-reflogs Instead of walking the commit ancestry chain, walk reflog entries from the most recent one to older ones. When this option is used you cannot specify commits to exclude (that is, ^commit, commit1..commit2, and commit1...commit2 notations cannot be used).
With --pretty format other than oneline and reference (for obvious reasons), this causes the output to have two extra lines of information taken from the reflog. The reflog designator in the output may be shown as ref@{Nth} (where Nth is the reverse-chronological index in the reflog) or as ref@{timestamp} (with the timestamp for that entry), depending on a few rules:
1. If the starting point is specified as ref@{Nth}, show the index format.
2. If the starting point was specified as ref@{now}, show the timestamp format.
3. If neither was used, but --date was given on the command line, show the timestamp in the format requested by --date.
4. Otherwise, show the index format.
Under --pretty=oneline, the commit message is prefixed with this information on the same line. This option cannot be combined with --reverse. See also git‐reflog(1).
Under --pretty=reference, this information will not be shown at all.
--merge After a failed merge, show refs that touch files having a conflict and don’t exist on all heads to merge.
--boundary Output excluded boundary commits. Boundary commits are prefixed with -.
History Simplification Sometimes you are only interested in parts of the history, for example the commits modifying a particular <path>. But there are two parts of History Simplification, one part is selecting the commits and the other is how to do it, as there are various strategies to simplify the history.
The following options select the commits to be shown:
<paths> Commits modifying the given <paths> are selected.
--simplify-by-decoration Commits that are referred by some branch or tag are selected.
Note that extra commits can be shown to give a meaningful history.
The following options affect the way the simplification is performed:
Default mode Simplifies the history to the simplest history explaining the final state of the tree. Simplest because it prunes some side branches if the end result is the same (i.e. merging branches with the same content)
--show-pulls Include all commits from the default mode, but also any merge commits that are not TREESAME to the first parent but are TREESAME to a later parent. This mode is helpful for showing the merge commits that "first introduced" a change to a branch.
--full-history Same as the default mode, but does not prune some history.
--dense Only the selected commits are shown, plus some to have a meaningful history.
--sparse All commits in the simplified history are shown.
--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.
--ancestry-path[=<commit>] When given a range of commits to display (e.g. commit1..commit2 or commit2 ^commit1), only display commits in that range that are ancestors of <commit>, descendants of <commit>, or <commit> itself. If no commit is specified, use commit1 (the excluded part of the range) as <commit>. Can be passed multiple times; if so, a commit is included if it is any of the commits given or if it is an ancestor or descendant of one of them.
A more detailed explanation follows.
Suppose you specified foo as the <paths>. We shall call commits that modify foo !TREESAME, and the rest TREESAME. (In a diff filtered for foo, they look different and equal, respectively.)
In the following, we will always refer to the same example history to illustrate the differences between simplification settings. We assume that you are filtering for a file foo in this commit graph:
.-A---M---N---O---P---Q / / / / / / I B C D E Y \ / / / / / ‘-------------' X
The horizontal line of history A---Q is taken to be the first parent of each merge. The commits are:
• I is the initial commit, in which foo exists with contents “asdf”, and a file quux exists with contents “quux”. Initial commits are compared to an empty tree, so I is !TREESAME.
• In A, foo contains just “foo”.
• B contains the same change as A. Its merge M is trivial and hence TREESAME to all parents.
• C does not change foo, but its merge N changes it to “foobar”, so it is not TREESAME to any parent.
• D sets foo to “baz”. Its merge O combines the strings from N and D to “foobarbaz”; i.e., it is not TREESAME to any parent.
• E changes quux to “xyzzy”, and its merge P combines the strings to “quux xyzzy”. P is TREESAME to O, but not to E.
• X is an independent root commit that added a new file side, and Y modified it. Y is TREESAME to X. Its merge Q added side to P, and Q is TREESAME to P, but not to Y.
rev-list walks backwards through history, including or excluding commits based on whether --full-history and/or parent rewriting (via --parents or --children) are used. The following settings are available.
Default mode Commits are included if they are not TREESAME to any parent (though this can be changed, see --sparse below). If the commit was a merge, and it was TREESAME to one parent, follow only that parent. (Even if there are several TREESAME parents, follow only one of them.) Otherwise, follow all parents.
This results in:
.-A---N---O / / / I---------D
Note how the rule to only follow the TREESAME parent, if one is available, removed B from consideration entirely. C was considered via N, but is TREESAME. Root commits are compared to an empty tree, so I is !TREESAME.
Parent/child relations are only visible with --parents, but that does not affect the commits selected in default mode, so we have shown the parent lines.
--full-history without parent rewriting This mode differs from the default in one point: always follow all parents of a merge, even if it is TREESAME to one of them. Even if more than one side of the merge has commits that are included, this does not imply that the merge itself is! In the example, we get
I A B N D O P Q
M was excluded because it is TREESAME to both parents. E, C and B were all walked, but only B was !TREESAME, so the others do not appear.
Note that without parent rewriting, it is not really possible to talk about the parent/child relationships between the commits, so we show them disconnected.
--full-history with parent rewriting Ordinary commits are only included if they are !TREESAME (though this can be changed, see --sparse below).
Merges are always included. However, their parent list is rewritten: Along each parent, prune away commits that are not included themselves. This results in
.-A---M---N---O---P---Q / / / / / I B / D / \ / / / / ‘-------------'
Compare to --full-history without rewriting above. Note that E was pruned away because it is TREESAME, but the parent list of P was rewritten to contain E's parent I. The same happened for C and N, and X, Y and Q.
In addition to the above settings, you can change whether TREESAME affects inclusion:
--dense Commits that are walked are included if they are not TREESAME to any parent.
--sparse All commits that are walked are included.
Note that without --full-history, this still simplifies merges: if one of the parents is TREESAME, we follow only that one, so the other sides of the merge are never walked.
--simplify-merges First, build a history graph in the same way that --full-history with parent rewriting does (see above).
Then simplify each commit C to its replacement C' in the final history according to the following rules:
• Set C' to C.
• Replace each parent P of C' with its simplification P'. In the process, drop parents that are ancestors of other parents or that are root commits TREESAME to an empty tree, and remove duplicates, but take care to never drop all parents that we are TREESAME to.
• If after this parent rewriting, C' is a root or merge commit (has zero or >1 parents), a boundary commit, or !TREESAME, it remains. Otherwise, it is replaced with its only parent.
The effect of this is best shown by way of comparing to --full-history with parent rewriting. The example turns into:
.-A---M---N---O / / / I B D \ / / ‘---------'
Note the major differences in N, P, and Q over --full-history:
• N's parent list had I removed, because it is an ancestor of the other parent M. Still, N remained because it is !TREESAME.
• P's parent list similarly had I removed. P was then removed completely, because it had one parent and is TREESAME.
• Q's parent list had Y simplified to X. X was then removed, because it was a TREESAME root. Q was then removed completely, because it had one parent and is TREESAME.
There is another simplification mode available:
--ancestry-path[=<commit>] Limit the displayed commits to those which are an ancestor of <commit>, or which are a descendant of <commit>, or are <commit> itself.
As an example use case, consider the following commit history:
D---E-------F / \ \ B---C---G---H---I---J / \ A-------K---------------L--M
A regular D..M computes the set of commits that are ancestors of M, but excludes the ones that are ancestors of D. This is useful to see what happened to the history leading to M since D, in the sense that “what does M have that did not exist in D”. The result in this example would be all the commits, except A and B (and D itself, of course).
When we want to find out what commits in M are contaminated with the bug introduced by D and need fixing, however, we might want to view only the subset of D..M that are actually descendants of D, i.e. excluding C and K. This is exactly what the --ancestry-path option does. Applied to the D..M range, it results in:
E-------F \ \ G---H---I---J \ L--M
We can also use --ancestry-path=D instead of --ancestry-path which means the same thing when applied to the D..M range but is just more explicit.
If we instead are interested in a given topic within this range, and all commits affected by that topic, we may only want to view the subset of D..M which contain that topic in their ancestry path. So, using --ancestry-path=H D..M for example would result in:
E \ G---H---I---J \ L--M
Whereas --ancestry-path=K D..M would result in
K---------------L--M
Before discussing another option, --show-pulls, we need to create a new example history.
A common problem users face when looking at simplified history is that a commit they know changed a file somehow does not appear in the file’s simplified history. Let’s demonstrate a new example and show how options such as --full-history and --simplify-merges works in that case:
.-A---M-----C--N---O---P / / \ \ \/ / / I B \ R-'‘-Z' / \ / \/ / \ / /\ / ‘---X--' ‘---Y--'
For this example, suppose I created file.txt which was modified by A, B, and X in different ways. The single-parent commits C, Z, and Y do not change file.txt. The merge commit M was created by resolving the merge conflict to include both changes from A and B and hence is not TREESAME to either. The merge commit R, however, was created by ignoring the contents of file.txt at M and taking only the contents of file.txt at X. Hence, R is TREESAME to X but not M. Finally, the natural merge resolution to create N is to take the contents of file.txt at R, so N is TREESAME to R but not C. The merge commits O and P are TREESAME to their first parents, but not to their second parents, Z and Y respectively.
When using the default mode, N and R both have a TREESAME parent, so those edges are walked and the others are ignored. The resulting history graph is:
I---X
When using --full-history, Git walks every edge. This will discover the commits A and B and the merge M, but also will reveal the merge commits O and P. With parent rewriting, the resulting graph is:
.-A---M--------N---O---P / / \ \ \/ / / I B \ R-'‘--' / \ / \/ / \ / /\ / ‘---X--' ‘------'
Here, the merge commits O and P contribute extra noise, as they did not actually contribute a change to file.txt. They only merged a topic that was based on an older version of file.txt. This is a common issue in repositories using a workflow where many contributors work in parallel and merge their topic branches along a single trunk: many unrelated merges appear in the --full-history results.
When using the --simplify-merges option, the commits O and P disappear from the results. This is because the rewritten second parents of O and P are reachable from their first parents. Those edges are removed and then the commits look like single-parent commits that are TREESAME to their parent. This also happens to the commit N, resulting in a history view as follows:
.-A---M--. / / \ I B R \ / / \ / / ‘---X--'
In this view, we see all of the important single-parent changes from A, B, and X. We also see the carefully-resolved merge M and the not-so-carefully-resolved merge R. This is usually enough information to determine why the commits A and B "disappeared" from history in the default view. However, there are a few issues with this approach.
The first issue is performance. Unlike any previous option, the --simplify-merges option requires walking the entire commit history before returning a single result. This can make the option difficult to use for very large repositories.
The second issue is one of auditing. When many contributors are working on the same repository, it is important which merge commits introduced a change into an important branch. The problematic merge R above is not likely to be the merge commit that was used to merge into an important branch. Instead, the merge N was used to merge R and X into the important branch. This commit may have information about why the change X came to override the changes from A and B in its commit message.
--show-pulls In addition to the commits shown in the default history, show each merge commit that is not TREESAME to its first parent but is TREESAME to a later parent.
When a merge commit is included by --show-pulls, the merge is treated as if it "pulled" the change from another branch. When using --show-pulls on this example (and no other options) the resulting graph is:
I---X---R---N
Here, the merge commits R and N are included because they pulled the commits X and R into the base branch, respectively. These merges are the reason the commits A and B do not appear in the default history.
When --show-pulls is paired with --simplify-merges, the graph includes all of the necessary information:
.-A---M--. N / / \ / I B R \ / / \ / / ‘---X--'
Notice that since M is reachable from R, the edge from N to M was simplified away. However, N still appears in the history as an important commit because it "pulled" the change R into the main branch.
The --simplify-by-decoration option allows you to view only the big picture of the topology of the history, by omitting commits that are not referenced by tags. Commits are marked as !TREESAME (in other words, kept after history simplification rules described above) if (1) they are referenced by tags, or (2) they change the contents of the paths given on the command line. All other commits are marked as TREESAME (subject to be simplified away).
Commit Ordering By default, the commits are shown in reverse chronological order.
--date-order Show no parents before all of its children are shown, but otherwise show commits in the commit timestamp order.
--author-date-order Show no parents before all of its children are shown, but otherwise show commits in the author timestamp order.
--topo-order Show no parents before all of its children are shown, and avoid showing commits on multiple lines of history intermixed.
For example, in a commit history like this:
---1----2----4----7 \ \ 3----5----6----8---
where the numbers denote the order of commit timestamps, git rev-list and friends with --date-order show the commits in the timestamp order: 8 7 6 5 4 3 2 1.
With --topo-order, they would show 8 6 5 3 7 4 2 1 (or 8 7 4 2 6 5 3 1); some older commits are shown before newer ones in order to avoid showing the commits from two parallel development track mixed together.
--reverse Output the commits chosen to be shown (see Commit Limiting section above) in reverse order. Cannot be combined with --walk-reflogs.
Object Traversal These options are mostly targeted for packing of Git repositories.
--no-walk[=(sorted|unsorted)] Only show the given commits, but do not traverse their ancestors. This has no effect if a range is specified. If the argument unsorted is given, the commits are shown in the order they were given on the command line. Otherwise (if sorted or no argument was given), the commits are shown in reverse chronological order by commit time. Cannot be combined with --graph.
--do-walk Overrides a previous --no-walk.
Commit Formatting --pretty[=<format>], --format=<format> Pretty-print the contents of the commit logs in a given format, where <format> can be one of oneline, short, medium, full, fuller, reference, email, raw, format:<string> and tformat:<string>. When <format> is none of the above, and has %placeholder in it, it acts as if --pretty=tformat:<format> were given.
See the "PRETTY FORMATS" section for some additional details for each format. When =<format> part is omitted, it defaults to medium.
Note: you can specify the default pretty format in the repository configuration (see git‐config(1)).
--abbrev-commit Instead of showing the full 40-byte hexadecimal commit object name, show a prefix that names the object uniquely. "--abbrev=<n>" (which also modifies diff output, if it is displayed) option can be used to specify the minimum length of the prefix.
This should make "--pretty=oneline" a whole lot more readable for people using 80-column terminals.
--no-abbrev-commit Show the full 40-byte hexadecimal commit object name. This negates --abbrev-commit, either explicit or implied by other options such as "--oneline". It also overrides the log.abbrevCommit variable.
--oneline This is a shorthand for "--pretty=oneline --abbrev-commit" used together.
--encoding=<encoding> Commit objects record the character encoding used for the log message in their encoding header; this option can be used to tell the command to re-code the commit log message in the encoding preferred by the user. For non plumbing commands this defaults to UTF-8. Note that if an object claims to be encoded in X and we are outputting in X, we will output the object verbatim; this means that invalid sequences in the original commit may be copied to the output. Likewise, if iconv(3) fails to convert the commit, we will quietly output the original object verbatim.
--expand-tabs=<n>, --expand-tabs, --no-expand-tabs Perform a tab expansion (replace each tab with enough spaces to fill to the next display column that is multiple of <n>) in the log message before showing it in the output. --expand-tabs is a short-hand for --expand-tabs=8, and --no-expand-tabs is a short-hand for --expand-tabs=0, which disables tab expansion.
By default, tabs are expanded in pretty formats that indent the log message by 4 spaces (i.e. medium, which is the default, full, and fuller).
--notes[=<ref>] Show the notes (see git‐notes(1)) that annotate the commit, when showing the commit log message. This is the default for git log, git show and git whatchanged commands when there is no --pretty, --format, or --oneline option given on the command line.
By default, the notes shown are from the notes refs listed in the core.notesRef and notes.displayRef variables (or corresponding environment overrides). See git‐config(1) for more details.
With an optional <ref> argument, use the ref to find the notes to display. The ref can specify the full refname when it begins with refs/notes/; when it begins with notes/, refs/ and otherwise refs/notes/ is prefixed to form a full name of the ref.
Multiple --notes options can be combined to control which notes are being displayed. Examples: "--notes=foo" will show only notes from "refs/notes/foo"; "--notes=foo --notes" will show both notes from "refs/notes/foo" and from the default notes ref(s).
--no-notes Do not show notes. This negates the above --notes option, by resetting the list of notes refs from which notes are shown. Options are parsed in the order given on the command line, so e.g. "--notes --notes=foo --no-notes --notes=bar" will only show notes from "refs/notes/bar".
--show-notes[=<ref>], --[no-]standard-notes These options are deprecated. Use the above --notes/--no-notes options instead.
--show-signature Check the validity of a signed commit object by passing the signature to gpg --verify and show the output.
--relative-date Synonym for --date=relative.
--date=<format> Only takes effect for dates shown in human-readable format, such as when using --pretty. log.date config variable sets a default value for the log command’s --date option. By default, dates are shown in the original time zone (either committer’s or author’s). If -local is appended to the format (e.g., iso-local), the user’s local time zone is used instead.
--date=relative shows dates relative to the current time, e.g. “2 hours ago”. The -local option has no effect for --date=relative.
--date=local is an alias for --date=default-local.
--date=iso (or --date=iso8601) shows timestamps in a ISO 8601-like format. The differences to the strict ISO 8601 format are:
• a space instead of the T date/time delimiter
• a space between time and time zone
• no colon between hours and minutes of the time zone
--date=iso-strict (or --date=iso8601-strict) shows timestamps in strict ISO 8601 format.
--date=rfc (or --date=rfc2822) shows timestamps in RFC 2822 format, often found in email messages.
--date=short shows only the date, but not the time, in YYYY-MM-DD format.
--date=raw shows the date as seconds since the epoch (1970-01-01 00:00:00 UTC), followed by a space, and then the timezone as an offset from UTC (a + or - with four digits; the first two are hours, and the second two are minutes). I.e., as if the timestamp were formatted with strftime("%s %z")). Note that the -local option does not affect the seconds-since-epoch value (which is always measured in UTC), but does switch the accompanying timezone value.
--date=human shows the timezone if the timezone does not match the current time-zone, and doesn’t print the whole date if that matches (ie skip printing year for dates that are "this year", but also skip the whole date itself if it’s in the last few days and we can just say what weekday it was). For older dates the hour and minute is also omitted.
--date=unix shows the date as a Unix epoch timestamp (seconds since 1970). As with --raw, this is always in UTC and therefore -local has no effect.
--date=format:... feeds the format ... to your system strftime, except for %s, %z, and %Z, which are handled internally. Use --date=format:%c to show the date in your system locale’s preferred format. See the strftime manual for a complete list of format placeholders. When using -local, the correct syntax is --date=format-local:....
--date=default is the default format, and is based on ctime(3) output. It shows a single line with three-letter day of the week, three-letter month, day-of-month, hour-minute-seconds in "HH:MM:SS" format, followed by 4-digit year, plus timezone information, unless the local time zone is used, e.g. Thu Jan 1 00:00:00 1970 +0000.
--parents Print also the parents of the commit (in the form "commit parent..."). Also enables parent rewriting, see History Simplification above.
--children Print also the children of the commit (in the form "commit child..."). Also enables parent rewriting, see History Simplification above.
--left-right Mark which side of a symmetric difference a commit is reachable from. Commits from the left side are prefixed with < and those from the right with >. If combined with --boundary, those commits are prefixed with -.
For example, if you have this topology:
y---b---b branch B / \ / / . / / \ o---x---a---a branch A
you would get an output like this:
$ git rev-list --left-right --boundary --pretty=oneline A...B
>bbbbbbb... 3rd on b >bbbbbbb... 2nd on b <aaaaaaa... 3rd on a <aaaaaaa... 2nd on a -yyyyyyy... 1st on b -xxxxxxx... 1st on a
--graph Draw a text-based graphical representation of the commit history on the left hand side of the output. This may cause extra lines to be printed in between commits, in order for the graph history to be drawn properly. Cannot be combined with --no-walk.
This enables parent rewriting, see History Simplification above.
This implies the --topo-order option by default, but the --date-order option may also be specified.
--show-linear-break[=<barrier>] When --graph is not used, all history branches are flattened which can make it hard to see that the two consecutive commits do not belong to a linear branch. This option puts a barrier in between them in that case. If <barrier> is specified, it is the string that will be shown instead of the default one.
PRETTY FORMATS If the commit is a merge, and if the pretty-format is not oneline, email or raw, an additional line is inserted before the Author: line. This line begins with "Merge: " and the hashes of ancestral commits are printed, separated by spaces. Note that the listed commits may not necessarily be the list of the direct parent commits if you have limited your view of history: for example, if you are only interested in changes related to a certain directory or file.
There are several built-in formats, and you can define additional formats by setting a pretty.<name> config option to either another format name, or a format: string, as described below (see git‐config(1)). Here are the details of the built-in formats:
• oneline
<hash> <title-line>
This is designed to be as compact as possible.
• short
commit <hash> Author: <author>
<title-line>
• medium
commit <hash> Author: <author> Date: <author-date>
<title-line>
<full-commit-message>
• full
commit <hash> Author: <author> Commit: <committer>
<title-line>
<full-commit-message>
• fuller
commit <hash> Author: <author> AuthorDate: <author-date> Commit: <committer> CommitDate: <committer-date>
<title-line>
<full-commit-message>
• reference
<abbrev-hash> (<title-line>, <short-author-date>)
This format is used to refer to another commit in a commit message and is the same as --pretty='format:%C(auto)%h (%s, %ad)'. By default, the date is formatted with --date=short unless another --date option is explicitly specified. As with any format: with format placeholders, its output is not affected by other options like --decorate and --walk-reflogs.
• email
From <hash> <date> From: <author> Date: <author-date> Subject: [PATCH] <title-line>
<full-commit-message>
• mboxrd
Like email, but lines in the commit message starting with "From " (preceded by zero or more ">") are quoted with ">" so they aren’t confused as starting a new commit.
• raw
The raw format shows the entire commit exactly as stored in the commit object. Notably, the hashes are displayed in full, regardless of whether --abbrev or --no-abbrev are used, and parents information show the true parent commits, without taking grafts or history simplification into account. Note that this format affects the way commits are displayed, but not the way the diff is shown e.g. with git log --raw. To get full object names in a raw diff format, use --no-abbrev.
• format:<format-string>
The format:<format-string> format allows you to specify which information you want to show. It works a little bit like printf format, with the notable exception that you get a newline with %n instead of \n.
E.g, format:"The author of %h was %an, %ar%nThe title was >>%s<<%n" would show something like this:
The author of fe6e0ee was Junio C Hamano, 23 hours ago The title was >>t4119: test autocomputing -p<n> for traditional diff input.<<
The placeholders are:
• Placeholders that expand to a single literal character:
%n newline
%% a raw %
%x00 print a byte from a hex code
• Placeholders that affect formatting of later placeholders:
%Cred switch color to red
%Cgreen switch color to green
%Cblue switch color to blue
%Creset reset color
%C(...) color specification, as described under Values in the "CONFIGURATION FILE" section of git‐config(1). By default, colors are shown only when enabled for log output (by color.diff, color.ui, or --color, and respecting the auto settings of the former if we are going to a terminal). %C(auto,...) is accepted as a historical synonym for the default (e.g., %C(auto,red)). Specifying %C(always,...) will show the colors even when color is not otherwise enabled (though consider just using --color=always to enable color for the whole output, including this format and anything else git might color). auto alone (i.e. %C(auto)) will turn on auto coloring on the next placeholders until the color is switched again.
%m left (<), right (>) or boundary (-) mark
%w([<w>[,<i1>[,<i2>]]]) switch line wrapping, like the -w option of git‐ shortlog(1).
%<( <N> [,trunc|ltrunc|mtrunc]) make the next placeholder take at least N column widths, padding spaces on the right if necessary. Optionally truncate (with ellipsis ..) at the left (ltrunc) ..ft, the middle (mtrunc) mi..le, or the end (trunc) rig.., if the output is longer than N columns. Note 1: that truncating only works correctly with N >= 2. Note 2: spaces around the N and M (see below) values are optional. Note 3: Emojis and other wide characters will take two display columns, which may over-run column boundaries. Note 4: decomposed character combining marks may be misplaced at padding boundaries.
%<|( <M> ) make the next placeholder take at least until Mth display column, padding spaces on the right if necessary. Use negative M values for column positions measured from the right hand edge of the terminal window.
%>( <N> ), %>|( <M> ) similar to %<( <N> ), %<|( <M> ) respectively, but padding spaces on the left
%>>( <N> ), %>>|( <M> ) similar to %>( <N> ), %>|( <M> ) respectively, except that if the next placeholder takes more spaces than given and there are spaces on its left, use those spaces
%><( <N> ), %><|( <M> ) similar to %<( <N> ), %<|( <M> ) respectively, but padding both sides (i.e. the text is centered)
• Placeholders that expand to information extracted from the commit:
%H commit hash
%h abbreviated commit hash
%T tree hash
%t abbreviated tree hash
%P parent hashes
%p abbreviated parent hashes
%an author name
%aN author name (respecting .mailmap, see git‐ shortlog(1) or git‐blame(1))
%ae author email
%aE author email (respecting .mailmap, see git‐ shortlog(1) or git‐blame(1))
%al author email local-part (the part before the @ sign)
%aL author local-part (see %al) respecting .mailmap, see git‐shortlog(1) or git‐blame(1))
%ad author date (format respects --date= option)
%aD author date, RFC2822 style
%ar author date, relative
%at author date, UNIX timestamp
%ai author date, ISO 8601-like format
%aI author date, strict ISO 8601 format
%as author date, short format (YYYY-MM-DD)
%ah author date, human style (like the --date=human option of git‐rev‐list(1))
%cn committer name
%cN committer name (respecting .mailmap, see git‐ shortlog(1) or git‐blame(1))
%ce committer email
%cE committer email (respecting .mailmap, see git‐ shortlog(1) or git‐blame(1))
%cl committer email local-part (the part before the @ sign)
%cL committer local-part (see %cl) respecting .mailmap, see git‐shortlog(1) or git‐blame(1))
%cd committer date (format respects --date= option)
%cD committer date, RFC2822 style
%cr committer date, relative
%ct committer date, UNIX timestamp
%ci committer date, ISO 8601-like format
%cI committer date, strict ISO 8601 format
%cs committer date, short format (YYYY-MM-DD)
%ch committer date, human style (like the --date=human option of git‐rev‐list(1))
%d ref names, like the --decorate option of git‐log(1)
%D ref names without the " (", ")" wrapping.
%(describe[:options]) human-readable name, like git‐describe(1); empty string for undescribable commits. The describe string may be followed by a colon and zero or more comma-separated options. Descriptions can be inconsistent when tags are added or removed at the same time.
• tags[=<bool-value>]: Instead of only considering annotated tags, consider lightweight tags as well.
• abbrev=<number>: Instead of using the default number of hexadecimal digits (which will vary according to the number of objects in the repository with a default of 7) of the abbreviated object name, use <number> digits, or as many digits as needed to form a unique object name.
• match=<pattern>: Only consider tags matching the given glob(7) pattern, excluding the "refs/tags/" prefix.
• exclude=<pattern>: Do not consider tags matching the given glob(7) pattern, excluding the "refs/tags/" prefix.
%S ref name given on the command line by which the commit was reached (like git log --source), only works with git log
%e encoding
%s subject
%f sanitized subject line, suitable for a filename
%b body
%B raw body (unwrapped subject and body)
%N commit notes
%GG raw verification message from GPG for a signed commit
%G? show "G" for a good (valid) signature, "B" for a bad signature, "U" for a good signature with unknown validity, "X" for a good signature that has expired, "Y" for a good signature made by an expired key, "R" for a good signature made by a revoked key, "E" if the signature cannot be checked (e.g. missing key) and "N" for no signature
%GS show the name of the signer for a signed commit
%GK show the key used to sign a signed commit
%GF show the fingerprint of the key used to sign a signed commit
%GP show the fingerprint of the primary key whose subkey was used to sign a signed commit
%GT show the trust level for the key used to sign a signed commit
%gD reflog selector, e.g., refs/stash@{1} or refs/stash@{2 minutes ago}; the format follows the rules described for the -g option. The portion before the @ is the refname as given on the command line (so git log -g refs/heads/master would yield refs/heads/master@{0}).
%gd shortened reflog selector; same as %gD, but the refname portion is shortened for human readability (so refs/heads/master becomes just master).
%gn reflog identity name
%gN reflog identity name (respecting .mailmap, see git‐ shortlog(1) or git‐blame(1))
%ge reflog identity email
%gE reflog identity email (respecting .mailmap, see git‐shortlog(1) or git‐blame(1))
%gs reflog subject
%(trailers[:options]) display the trailers of the body as interpreted by git‐interpret‐trailers(1). The trailers string may be followed by a colon and zero or more comma-separated options. If any option is provided multiple times the last occurrence wins.
• key=<key>: only show trailers with specified <key>. Matching is done case-insensitively and trailing colon is optional. If option is given multiple times trailer lines matching any of the keys are shown. This option automatically enables the only option so that non-trailer lines in the trailer block are hidden. If that is not desired it can be disabled with only=false. E.g., %(trailers:key=Reviewed-by) shows trailer lines with key Reviewed-by.
• only[=<bool>]: select whether non-trailer lines from the trailer block should be included.
• separator=<sep>: specify a separator inserted between trailer lines. When this option is not given each trailer line is terminated with a line feed character. The string <sep> may contain the literal formatting codes described above. To use comma as separator one must use %x2C as it would otherwise be parsed as next option. E.g., %(trailers:key=Ticket,separator=%x2C ) shows all trailer lines whose key is "Ticket" separated by a comma and a space.
• unfold[=<bool>]: make it behave as if interpret-trailer’s --unfold option was given. E.g., %(trailers:only,unfold=true) unfolds and shows all trailer lines.
• keyonly[=<bool>]: only show the key part of the trailer.
• valueonly[=<bool>]: only show the value part of the trailer.
• key_value_separator=<sep>: specify a separator inserted between trailer lines. When this option is not given each trailer key-value pair is separated by ": ". Otherwise it shares the same semantics as separator=<sep> above.
Note
Some placeholders may depend on other options given to the revision traversal engine. For example, the %g* reflog options will insert an empty string unless we are traversing reflog entries (e.g., by git log -g). The %d and %D placeholders will use the "short" decoration format if --decorate was not already provided on the command line.
The boolean options accept an optional value [=<bool-value>]. The values true, false, on, off etc. are all accepted. See the "boolean" sub-section in "EXAMPLES" in git‐config(1). If a boolean option is given with no value, it’s enabled.
If you add a + (plus sign) after % of a placeholder, a line-feed is inserted immediately before the expansion if and only if the placeholder expands to a non-empty string.
If you add a - (minus sign) after % of a placeholder, all consecutive line-feeds immediately preceding the expansion are deleted if and only if the placeholder expands to an empty string.
If you add a ‘ ‘ (space) after % of a placeholder, a space is inserted immediately before the expansion if and only if the placeholder expands to a non-empty string.
• tformat:
The tformat: format works exactly like format:, except that it provides "terminator" semantics instead of "separator" semantics. In other words, each commit has the message terminator character (usually a newline) appended, rather than a separator placed between entries. This means that the final entry of a single-line format will be properly terminated with a new line, just as the "oneline" format does. For example:
$ git log -2 --pretty=format:%h 4da45bef \ | perl -pe '$_ .= " -- NO NEWLINE\n" unless /\n/' 4da45be 7134973 -- NO NEWLINE
$ git log -2 --pretty=tformat:%h 4da45bef \ | perl -pe '$_ .= " -- NO NEWLINE\n" unless /\n/' 4da45be 7134973
In addition, any unrecognized string that has a % in it is interpreted as if it has tformat: in front of it. For example, these two are equivalent:
$ git log -2 --pretty=tformat:%h 4da45bef $ git log -2 --pretty=%h 4da45bef
DIFF FORMATTING By default, git log does not generate any diff output. The options below can be used to show the changes made by each commit.
Note that unless one of --diff-merges variants (including short -m, -c, and --cc options) is explicitly given, merge commits will not show a diff, even if a diff format like --patch is selected, nor will they match search options like -S. The exception is when --first-parent is in use, in which case first-parent is the default format.
-p, -u, --patch Generate patch (see section titled "Generating patch text with -p").
-s, --no-patch Suppress diff output. Useful for commands like git show that show the patch by default, or to cancel the effect of --patch.
--diff-merges=(off|none|on|first-parent|1|separate|m|combined|c|dense-combined|cc|remerge|r), --no-diff-merges Specify diff format to be used for merge commits. Default is off unless --first-parent is in use, in which case first-parent is the default.
--diff-merges=(off|none), --no-diff-merges Disable output of diffs for merge commits. Useful to override implied value.
--diff-merges=on, --diff-merges=m, -m This option makes diff output for merge commits to be shown in the default format. -m will produce the output only if -p is given as well. The default format could be changed using log.diffMerges configuration parameter, which default value is separate.
--diff-merges=first-parent, --diff-merges=1 This option makes merge commits show the full diff with respect to the first parent only.
--diff-merges=separate This makes merge commits show the full diff with respect to each of the parents. Separate log entry and diff is generated for each parent.
--diff-merges=remerge, --diff-merges=r, --remerge-diff With this option, two-parent merge commits are remerged to create a temporary tree object — potentially containing files with conflict markers and such. A diff is then shown between that temporary tree and the actual merge commit.
The output emitted when this option is used is subject to change, and so is its interaction with other options (unless explicitly documented).
--diff-merges=combined, --diff-merges=c, -c With this option, diff output for a merge commit shows the differences from each of the parents to the merge result simultaneously instead of showing pairwise diff between a parent and the result one at a time. Furthermore, it lists only files which were modified from all parents. -c implies -p.
--diff-merges=dense-combined, --diff-merges=cc, --cc With this option the output produced by --diff-merges=combined is further compressed by omitting uninteresting hunks whose contents in the parents have only two variants and the merge result picks one of them without modification. --cc implies -p.
--combined-all-paths This flag causes combined diffs (used for merge commits) to list the name of the file from all parents. It thus only has effect when --diff-merges=[dense-]combined is in use, and is likely only useful if filename changes are detected (i.e. when either rename or copy detection have been requested).
-U<n>, --unified=<n> Generate diffs with <n> lines of context instead of the usual three. Implies --patch.
--output=<file> Output to a specific file instead of stdout.
--output-indicator-new=<char>, --output-indicator-old=<char>, --output-indicator-context=<char> Specify the character used to indicate new, old or context lines in the generated patch. Normally they are +, - and ' ' respectively.
--raw For each commit, show a summary of changes using the raw diff format. See the "RAW OUTPUT FORMAT" section of git‐ diff(1). This is different from showing the log itself in raw format, which you can achieve with --format=raw.
--patch-with-raw Synonym for -p --raw.
-t Show the tree objects in the diff output.
--indent-heuristic Enable the heuristic that shifts diff hunk boundaries to make patches easier to read. This is the default.
--no-indent-heuristic Disable the indent heuristic.
--minimal Spend extra time to make sure the smallest possible diff is produced.
--patience Generate a diff using the "patience diff" algorithm.
--histogram Generate a diff using the "histogram diff" algorithm.
--anchored=<text> Generate a diff using the "anchored diff" algorithm.
This option may be specified more than once.
If a line exists in both the source and destination, exists only once, and starts with this text, this algorithm attempts to prevent it from appearing as a deletion or addition in the output. It uses the "patience diff" algorithm internally.
--diff-algorithm={patience|minimal|histogram|myers} Choose a diff algorithm. The variants are as follows:
default, myers The basic greedy diff algorithm. Currently, this is the default.
minimal Spend extra time to make sure the smallest possible diff is produced.
patience Use "patience diff" algorithm when generating patches.
histogram This algorithm extends the patience algorithm to "support low-occurrence common elements".
For instance, if you configured the diff.algorithm variable to a non-default value and want to use the default one, then you have to use --diff-algorithm=default option.
--stat[=<width>[,<name-width>[,<count>]]] Generate a diffstat. By default, as much space as necessary will be used for the filename part, and the rest for the graph part. Maximum width defaults to terminal width, or 80 columns if not connected to a terminal, and can be overridden by <width>. The width of the filename part can be limited by giving another width <name-width> after a comma. The width of the graph part can be limited by using --stat-graph-width=<width> (affects all commands generating a stat graph) or by setting diff.statGraphWidth=<width> (does not affect git format-patch). By giving a third parameter <count>, you can limit the output to the first <count> lines, followed by ... if there are more.
These parameters can also be set individually with --stat-width=<width>, --stat-name-width=<name-width> and --stat-count=<count>.
--compact-summary Output a condensed summary of extended header information such as file creations or deletions ("new" or "gone", optionally "+l" if it’s a symlink) and mode changes ("+x" or "-x" for adding or removing executable bit respectively) in diffstat. The information is put between the filename part and the graph part. Implies --stat.
--numstat Similar to --stat, but shows number of added and deleted lines in decimal notation and pathname without abbreviation, to make it more machine friendly. For binary files, outputs two - instead of saying 0 0.
--shortstat Output only the last line of the --stat format containing total number of modified files, as well as number of added and deleted lines.
-X[<param1,param2,...>], --dirstat[=<param1,param2,...>] Output the distribution of relative amount of changes for each sub-directory. The behavior of --dirstat can be customized by passing it a comma separated list of parameters. The defaults are controlled by the diff.dirstat configuration variable (see git‐config(1)). The following parameters are available:
changes Compute the dirstat numbers by counting the lines that have been removed from the source, or added to the destination. This ignores the amount of pure code movements within a file. In other words, rearranging lines in a file is not counted as much as other changes. This is the default behavior when no parameter is given.
lines Compute the dirstat numbers by doing the regular line-based diff analysis, and summing the removed/added line counts. (For binary files, count 64-byte chunks instead, since binary files have no natural concept of lines). This is a more expensive --dirstat behavior than the changes behavior, but it does count rearranged lines within a file as much as other changes. The resulting output is consistent with what you get from the other --*stat options.
files Compute the dirstat numbers by counting the number of files changed. Each changed file counts equally in the dirstat analysis. This is the computationally cheapest --dirstat behavior, since it does not have to look at the file contents at all.
cumulative Count changes in a child directory for the parent directory as well. Note that when using cumulative, the sum of the percentages reported may exceed 100%. The default (non-cumulative) behavior can be specified with the noncumulative parameter.
<limit> An integer parameter specifies a cut-off percent (3% by default). Directories contributing less than this percentage of the changes are not shown in the output.
Example: The following will count changed files, while ignoring directories with less than 10% of the total amount of changed files, and accumulating child directory counts in the parent directories: --dirstat=files,10,cumulative.
--cumulative Synonym for --dirstat=cumulative
--dirstat-by-file[=<param1,param2>...] Synonym for --dirstat=files,param1,param2...
--summary Output a condensed summary of extended header information such as creations, renames and mode changes.
--patch-with-stat Synonym for -p --stat.
-z Separate the commits with NULs instead of with new newlines.
Also, when --raw or --numstat has been given, do not munge pathnames and use NULs as output field terminators.
Without this option, pathnames with "unusual" characters are quoted as explained for the configuration variable core.quotePath (see git‐config(1)).
--name-only Show only names of changed files. The file names are often encoded in UTF-8. For more information see the discussion about encoding in the git‐log(1) manual page.
--name-status Show only names and status of changed files. See the description of the --diff-filter option on what the status letters mean. Just like --name-only the file names are often encoded in UTF-8.
--submodule[=<format>] Specify how differences in submodules are shown. When specifying --submodule=short the short format is used. This format just shows the names of the commits at the beginning and end of the range. When --submodule or --submodule=log is specified, the log format is used. This format lists the commits in the range like git‐submodule(1) summary does. When --submodule=diff is specified, the diff format is used. This format shows an inline diff of the changes in the submodule contents between the commit range. Defaults to diff.submodule or the short format if the config option is unset.
--color[=<when>] Show colored diff. --color (i.e. without =<when>) is the same as --color=always. <when> can be one of always, never, or auto.
--no-color Turn off colored diff. It is the same as --color=never.
--color-moved[=<mode>] Moved lines of code are colored differently. The <mode> defaults to no if the option is not given and to zebra if the option with no mode is given. The mode must be one of:
no Moved lines are not highlighted.
default Is a synonym for zebra. This may change to a more sensible mode in the future.
plain Any line that is added in one location and was removed in another location will be colored with color.diff.newMoved. Similarly color.diff.oldMoved will be used for removed lines that are added somewhere else in the diff. This mode picks up any moved line, but it is not very useful in a review to determine if a block of code was moved without permutation.
blocks Blocks of moved text of at least 20 alphanumeric characters are detected greedily. The detected blocks are painted using either the color.diff.{old,new}Moved color. Adjacent blocks cannot be told apart.
zebra Blocks of moved text are detected as in blocks mode. The blocks are painted using either the color.diff.{old,new}Moved color or color.diff.{old,new}MovedAlternative. The change between the two colors indicates that a new block was detected.
dimmed-zebra Similar to zebra, but additional dimming of uninteresting parts of moved code is performed. The bordering lines of two adjacent blocks are considered interesting, the rest is uninteresting. dimmed_zebra is a deprecated synonym.
--no-color-moved Turn off move detection. This can be used to override configuration settings. It is the same as --color-moved=no.
--color-moved-ws=<modes> This configures how whitespace is ignored when performing the move detection for --color-moved. These modes can be given as a comma separated list:
no Do not ignore whitespace when performing move detection.
ignore-space-at-eol Ignore changes in whitespace at EOL.
ignore-space-change Ignore changes in amount of whitespace. This ignores whitespace at line end, and considers all other sequences of one or more whitespace characters to be equivalent.
ignore-all-space Ignore whitespace when comparing lines. This ignores differences even if one line has whitespace where the other line has none.
allow-indentation-change Initially ignore any whitespace in the move detection, then group the moved code blocks only into a block if the change in whitespace is the same per line. This is incompatible with the other modes.
--no-color-moved-ws Do not ignore whitespace when performing move detection. This can be used to override configuration settings. It is the same as --color-moved-ws=no.
--word-diff[=<mode>] Show a word diff, using the <mode> to delimit changed words. By default, words are delimited by whitespace; see --word-diff-regex below. The <mode> defaults to plain, and must be one of:
color Highlight changed words using only colors. Implies --color.
plain Show words as [-removed-] and {+added+}. Makes no attempts to escape the delimiters if they appear in the input, so the output may be ambiguous.
porcelain Use a special line-based format intended for script consumption. Added/removed/unchanged runs are printed in the usual unified diff format, starting with a +/-/‘ ‘ character at the beginning of the line and extending to the end of the line. Newlines in the input are represented by a tilde ~ on a line of its own.
none Disable word diff again.
Note that despite the name of the first mode, color is used to highlight the changed parts in all modes if enabled.
--word-diff-regex=<regex> Use <regex> to decide what a word is, instead of considering runs of non-whitespace to be a word. Also implies --word-diff unless it was already enabled.
Every non-overlapping match of the <regex> is considered a word. Anything between these matches is considered whitespace and ignored(!) for the purposes of finding differences. You may want to append |[^[:space:]] to your regular expression to make sure that it matches all non-whitespace characters. A match that contains a newline is silently truncated(!) at the newline.
For example, --word-diff-regex=. will treat each character as a word and, correspondingly, show differences character by character.
The regex can also be set via a diff driver or configuration option, see gitattributes(5) or git‐ config(1). Giving it explicitly overrides any diff driver or configuration setting. Diff drivers override configuration settings.
--color-words[=<regex>] Equivalent to --word-diff=color plus (if a regex was specified) --word-diff-regex=<regex>.
--no-renames Turn off rename detection, even when the configuration file gives the default to do so.
--[no-]rename-empty Whether to use empty blobs as rename source.
--check Warn if changes introduce conflict markers or whitespace errors. What are considered whitespace errors is controlled by core.whitespace configuration. By default, trailing whitespaces (including lines that consist solely of whitespaces) and a space character that is immediately followed by a tab character inside the initial indent of the line are considered whitespace errors. Exits with non-zero status if problems are found. Not compatible with --exit-code.
--ws-error-highlight=<kind> Highlight whitespace errors in the context, old or new lines of the diff. Multiple values are separated by comma, none resets previous values, default reset the list to new and all is a shorthand for old,new,context. When this option is not given, and the configuration variable diff.wsErrorHighlight is not set, only whitespace errors in new lines are highlighted. The whitespace errors are colored with color.diff.whitespace.
--full-index Instead of the first handful of characters, show the full pre- and post-image blob object names on the "index" line when generating patch format output.
--binary In addition to --full-index, output a binary diff that can be applied with git-apply. Implies --patch.
--abbrev[=<n>] Instead of showing the full 40-byte hexadecimal object name in diff-raw format output and diff-tree header lines, show the shortest prefix that is at least <n> hexdigits long that uniquely refers the object. In diff-patch output format, --full-index takes higher precedence, i.e. if --full-index is specified, full blob names will be shown regardless of --abbrev. Non default number of digits can be specified with --abbrev=<n>.
-B[<n>][/<m>], --break-rewrites[=[<n>][/<m>]] Break complete rewrite changes into pairs of delete and create. This serves two purposes:
It affects the way a change that amounts to a total rewrite of a file not as a series of deletion and insertion mixed together with a very few lines that happen to match textually as the context, but as a single deletion of everything old followed by a single insertion of everything new, and the number m controls this aspect of the -B option (defaults to 60%). -B/70% specifies that less than 30% of the original should remain in the result for Git to consider it a total rewrite (i.e. otherwise the resulting patch will be a series of deletion and insertion mixed together with context lines).
When used with -M, a totally-rewritten file is also considered as the source of a rename (usually -M only considers a file that disappeared as the source of a rename), and the number n controls this aspect of the -B option (defaults to 50%). -B20% specifies that a change with addition and deletion compared to 20% or more of the file’s size are eligible for being picked up as a possible source of a rename to another file.
-M[<n>], --find-renames[=<n>] If generating diffs, detect and report renames for each commit. For following files across renames while traversing history, see --follow. If n is specified, it is a threshold on the similarity index (i.e. amount of addition/deletions compared to the file’s size). For example, -M90% means Git should consider a delete/add pair to be a rename if more than 90% of the file hasn’t changed. Without a % sign, the number is to be read as a fraction, with a decimal point before it. I.e., -M5 becomes 0.5, and is thus the same as -M50%. Similarly, -M05 is the same as -M5%. To limit detection to exact renames, use -M100%. The default similarity index is 50%.
-C[<n>], --find-copies[=<n>] Detect copies as well as renames. See also --find-copies-harder. If n is specified, it has the same meaning as for -M<n>.
--find-copies-harder For performance reasons, by default, -C option finds copies only if the original file of the copy was modified in the same changeset. This flag makes the command inspect unmodified files as candidates for the source of copy. This is a very expensive operation for large projects, so use it with caution. Giving more than one -C option has the same effect.
-D, --irreversible-delete Omit the preimage for deletes, i.e. print only the header but not the diff between the preimage and /dev/null. The resulting patch is not meant to be applied with patch or git apply; this is solely for people who want to just concentrate on reviewing the text after the change. In addition, the output obviously lacks enough information to apply such a patch in reverse, even manually, hence the name of the option.
When used together with -B, omit also the preimage in the deletion part of a delete/create pair.
-l<num> The -M and -C options involve some preliminary steps that can detect subsets of renames/copies cheaply, followed by an exhaustive fallback portion that compares all remaining unpaired destinations to all relevant sources. (For renames, only remaining unpaired sources are relevant; for copies, all original sources are relevant.) For N sources and destinations, this exhaustive check is O(N^2). This option prevents the exhaustive portion of rename/copy detection from running if the number of source/destination files involved exceeds the specified number. Defaults to diff.renameLimit. Note that a value of 0 is treated as unlimited.
--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]] Select only files that are Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type (i.e. regular file, symlink, submodule, ...) changed (T), are Unmerged (U), are Unknown (X), or have had their pairing Broken (B). Any combination of the filter characters (including none) can be used. When * (All-or-none) is added to the combination, all paths are selected if there is any file that matches other criteria in the comparison; if there is no file that matches other criteria, nothing is selected.
Also, these upper-case letters can be downcased to exclude. E.g. --diff-filter=ad excludes added and deleted paths.
Note that not all diffs can feature all types. For instance, copied and renamed entries cannot appear if detection for those types is disabled.
-S<string> Look for differences that change the number of occurrences of the specified string (i.e. addition/deletion) in a file. Intended for the scripter’s use.
It is useful when you’re looking for an exact block of code (like a struct), and want to know the history of that block since it first came into being: use the feature iteratively to feed the interesting block in the preimage back into -S, and keep going until you get the very first version of the block.
Binary files are searched as well.
-G<regex> Look for differences whose patch text contains added/removed lines that match <regex>.
To illustrate the difference between -S<regex> --pickaxe-regex and -G<regex>, consider a commit with the following diff in the same file:
+ return frotz(nitfol, two->ptr, 1, 0); ... - hit = frotz(nitfol, mf2.ptr, 1, 0);
While git log -G"frotz\(nitfol" will show this commit, git log -S"frotz\(nitfol" --pickaxe-regex will not (because the number of occurrences of that string did not change).
Unless --text is supplied patches of binary files without a textconv filter will be ignored.
See the pickaxe entry in gitdiffcore(7) for more information.
--find-object=<object-id> Look for differences that change the number of occurrences of the specified object. Similar to -S, just the argument is different in that it doesn’t search for a specific string but for a specific object id.
The object can be a blob or a submodule commit. It implies the -t option in git-log to also find trees.
--pickaxe-all When -S or -G finds a change, show all the changes in that changeset, not just the files that contain the change in <string>.
--pickaxe-regex Treat the <string> given to -S as an extended POSIX regular expression to match.
-O<orderfile> Control the order in which files appear in the output. This overrides the diff.orderFile configuration variable (see git‐config(1)). To cancel diff.orderFile, use -O/dev/null.
The output order is determined by the order of glob patterns in <orderfile>. All files with pathnames that match the first pattern are output first, all files with pathnames that match the second pattern (but not the first) are output next, and so on. All files with pathnames that do not match any pattern are output last, as if there was an implicit match-all pattern at the end of the file. If multiple pathnames have the same rank (they match the same pattern but no earlier patterns), their output order relative to each other is the normal order.
<orderfile> is parsed as follows:
• Blank lines are ignored, so they can be used as separators for readability.
• Lines starting with a hash ("#") are ignored, so they can be used for comments. Add a backslash ("\") to the beginning of the pattern if it starts with a hash.
• Each other line contains a single pattern.
Patterns have the same syntax and semantics as patterns used for fnmatch(3) without the FNM_PATHNAME flag, except a pathname also matches a pattern if removing any number of the final pathname components matches the pattern. For example, the pattern "foo*bar" matches "fooasdfbar" and "foo/bar/baz/asdf" but not "foobarx".
--skip-to=<file>, --rotate-to=<file> Discard the files before the named <file> from the output (i.e. skip to), or move them to the end of the output (i.e. rotate to). These were invented primarily for use of the git difftool command, and may not be very useful otherwise.
-R Swap two inputs; that is, show differences from index or on-disk file to tree contents.
--relative[=<path>], --no-relative When run from a subdirectory of the project, it can be told to exclude changes outside the directory and show pathnames relative to it with this option. When you are not in a subdirectory (e.g. in a bare repository), you can name which subdirectory to make the output relative to by giving a <path> as an argument. --no-relative can be used to countermand both diff.relative config option and previous --relative.
-a, --text Treat all files as text.
--ignore-cr-at-eol Ignore carriage-return at the end of line when doing a comparison.
--ignore-space-at-eol Ignore changes in whitespace at EOL.
-b, --ignore-space-change Ignore changes in amount of whitespace. This ignores whitespace at line end, and considers all other sequences of one or more whitespace characters to be equivalent.
-w, --ignore-all-space Ignore whitespace when comparing lines. This ignores differences even if one line has whitespace where the other line has none.
--ignore-blank-lines Ignore changes whose lines are all blank.
-I<regex>, --ignore-matching-lines=<regex> Ignore changes whose all lines match <regex>. This option may be specified more than once.
--inter-hunk-context=<lines> Show the context between diff hunks, up to the specified number of lines, thereby fusing hunks that are close to each other. Defaults to diff.interHunkContext or 0 if the config option is unset.
-W, --function-context Show whole function as context lines for each change. The function names are determined in the same way as git diff works out patch hunk headers (see Defining a custom hunk-header in gitattributes(5)).
--ext-diff Allow an external diff helper to be executed. If you set an external diff driver with gitattributes(5), you need to use this option with git‐log(1) and friends.
--no-ext-diff Disallow external diff drivers.
--textconv, --no-textconv Allow (or disallow) external text conversion filters to be run when comparing binary files. See gitattributes(5) for details. Because textconv filters are typically a one-way conversion, the resulting diff is suitable for human consumption, but cannot be applied. For this reason, textconv filters are enabled by default only for git‐ diff(1) and git‐log(1), but not for git‐format‐patch(1) or diff plumbing commands.
--ignore-submodules[=<when>] Ignore changes to submodules in the diff generation. <when> can be either "none", "untracked", "dirty" or "all", which is the default. Using "none" will consider the submodule modified when it either contains untracked or modified files or its HEAD differs from the commit recorded in the superproject and can be used to override any settings of the ignore option in git‐config(1) or gitmodules(5). When "untracked" is used submodules are not considered dirty when they only contain untracked content (but they are still scanned for modified content). Using "dirty" ignores all changes to the work tree of submodules, only changes to the commits stored in the superproject are shown (this was the behavior until 1.7.0). Using "all" hides all changes to submodules.
--src-prefix=<prefix> Show the given source prefix instead of "a/".
--dst-prefix=<prefix> Show the given destination prefix instead of "b/".
--no-prefix Do not show any source or destination prefix.
--line-prefix=<prefix> Prepend an additional prefix to every line of output.
--ita-invisible-in-index By default entries added by "git add -N" appear as an existing empty file in "git diff" and a new file in "git diff --cached". This option makes the entry appear as a new file in "git diff" and non-existent in "git diff --cached". This option could be reverted with --ita-visible-in-index. Both options are experimental and could be removed in future.
For more detailed explanation on these common options, see also gitdiffcore(7).
GENERATING PATCH TEXT WITH -P Running git‐diff(1), git‐log(1), git‐show(1), git‐diff‐ index(1), git‐diff‐tree(1), or git‐diff‐files(1) with the -p option produces patch text. You can customize the creation of patch text via the GIT_EXTERNAL_DIFF and the GIT_DIFF_OPTS environment variables (see git(1)), and the diff attribute (see gitattributes(5)).
What the -p option produces is slightly different from the traditional diff format:
1. It is preceded with a "git diff" header that looks like this:
diff --git a/file1 b/file2
The a/ and b/ filenames are the same unless rename/copy is involved. Especially, even for a creation or a deletion, /dev/null is not used in place of the a/ or b/ filenames.
When rename/copy is involved, file1 and file2 show the name of the source file of the rename/copy and the name of the file that rename/copy produces, respectively.
2. It is followed by one or more extended header lines:
old mode <mode> new mode <mode> deleted file mode <mode> new file mode <mode> copy from <path> copy to <path> rename from <path> rename to <path> similarity index <number> dissimilarity index <number> index <hash>..<hash> <mode>
File modes are printed as 6-digit octal numbers including the file type and file permission bits.
Path names in extended headers do not include the a/ and b/ prefixes.
The similarity index is the percentage of unchanged lines, and the dissimilarity index is the percentage of changed lines. It is a rounded down integer, followed by a percent sign. The similarity index value of 100% is thus reserved for two equal files, while 100% dissimilarity means that no line from the old file made it into the new one.
The index line includes the blob object names before and after the change. The <mode> is included if the file mode does not change; otherwise, separate lines indicate the old and the new mode.
3. Pathnames with "unusual" characters are quoted as explained for the configuration variable core.quotePath (see git‐ config(1)).
4. All the file1 files in the output refer to files before the commit, and all the file2 files refer to files after the commit. It is incorrect to apply each change to each file sequentially. For example, this patch will swap a and b:
diff --git a/a b/b rename from a rename to b diff --git a/b b/a rename from b rename to a
5. Hunk headers mention the name of the function to which the hunk applies. See "Defining a custom hunk-header" in gitattributes(5) for details of how to tailor to this to specific languages.
COMBINED DIFF FORMAT Any diff-generating command can take the -c or --cc option to produce a combined diff when showing a merge. This is the default format when showing merges with git‐diff(1) or git‐ show(1). Note also that you can give suitable --diff-merges option to any of these commands to force generation of diffs in specific format.
A "combined diff" format looks like this:
diff --combined describe.c index fabadb8,cc95eb0..4866510 --- a/describe.c +++ b/describe.c @@@ -98,20 -98,12 +98,20 @@@ return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1; }
- static void describe(char *arg) -static void describe(struct commit *cmit, int last_one) ++static void describe(char *arg, int last_one) { + unsigned char sha1[20]; + struct commit *cmit; struct commit_list *list; static int initialized = 0; struct commit_name *n;
+ if (get_sha1(arg, sha1) < 0) + usage(describe_usage); + cmit = lookup_commit_reference(sha1); + if (!cmit) + usage(describe_usage); + if (!initialized) { initialized = 1; for_each_ref(get_name);
1. It is preceded with a "git diff" header, that looks like this (when the -c option is used):
diff --combined file
or like this (when the --cc option is used):
diff --cc file
2. It is followed by one or more extended header lines (this example shows a merge with two parents):
index <hash>,<hash>..<hash> mode <mode>,<mode>..<mode> new file mode <mode> deleted file mode <mode>,<mode>
The mode <mode>,<mode>..<mode> line appears only if at least one of the <mode> is different from the rest. Extended headers with information about detected contents movement (renames and copying detection) are designed to work with diff of two <tree-ish> and are not used by combined diff format.
3. It is followed by two-line from-file/to-file header
--- a/file +++ b/file
Similar to two-line header for traditional unified diff format, /dev/null is used to signal created or deleted files.
However, if the --combined-all-paths option is provided, instead of a two-line from-file/to-file you get a N+1 line from-file/to-file header, where N is the number of parents in the merge commit
--- a/file --- a/file --- a/file +++ b/file
This extended format can be useful if rename or copy detection is active, to allow you to see the original name of the file in different parents.
4. Chunk header format is modified to prevent people from accidentally feeding it to patch -p1. Combined diff format was created for review of merge commit changes, and was not meant to be applied. The change is similar to the change in the extended index header:
@@@ <from-file-range> <from-file-range> <to-file-range> @@@
There are (number of parents + 1) @ characters in the chunk header for combined diff format.
Unlike the traditional unified diff format, which shows two files A and B with a single column that has - (minus — appears in A but removed in B), + (plus — missing in A but added to B), or " " (space — unchanged) prefix, this format compares two or more files file1, file2,... with one file X, and shows how X differs from each of fileN. One column for each of fileN is prepended to the output line to note how X’s line is different from it.
A - character in the column N means that the line appears in fileN but it does not appear in the result. A + character in the column N means that the line appears in the result, and fileN does not have that line (in other words, the line was added, from the point of view of that parent).
In the above example output, the function signature was changed from both files (hence two - removals from both file1 and file2, plus ++ to mean one line that was added does not appear in either file1 or file2). Also eight other lines are the same from file1 but do not appear in file2 (hence prefixed with +).
When shown by git diff-tree -c, it compares the parents of a merge commit with the merge result (i.e. file1..fileN are the parents). When shown by git diff-files -c, it compares the two unresolved merge parents with the working tree file (i.e. file1 is stage 2 aka "our version", file2 is stage 3 aka "their version").
EXAMPLES git log --no-merges Show the whole commit history, but skip any merges
git log v2.6.12.. include/scsi drivers/scsi Show all commits since version v2.6.12 that changed any file in the include/scsi or drivers/scsi subdirectories
git log --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
git log --name-status release..test Show the commits that are in the "test" branch but not yet in the "release" branch, along with the list of paths each commit modifies.
git log --follow builtin/rev-list.c Shows the commits that changed builtin/rev-list.c, including those commits that occurred before the file was given its present name.
git log --branches --not --remotes=origin Shows all commits that are in any of local branches but not in any of remote-tracking branches for origin (what you have that origin doesn’t).
git log master --not --remotes=*/master Shows all commits that are in local master but not in any remote repository master branches.
git log -p -m --first-parent Shows the history including change diffs, but only from the “main branch” perspective, skipping commits that come from merged branches, and showing full diffs of changes introduced by the merges. This makes sense only when following a strict policy of merging all topic branches when staying on a single integration branch.
git log -L '/int main/',/^}/:main.c Shows how the function main() in the file main.c evolved over time.
git log -3 Limits the number of commits to show to 3.
DISCUSSION Git is to some extent character encoding agnostic.
• The contents of the blob objects are uninterpreted sequences of bytes. There is no encoding translation at the core level.
• Path names are encoded in UTF-8 normalization form C. This applies to tree objects, the index file, ref names, as well as path names in command line arguments, environment variables and config files (.git/config (see git‐ config(1)), gitignore(5), gitattributes(5) and gitmodules(5)).
Note that Git at the core level treats path names simply as sequences of non-NUL bytes, there are no path name encoding conversions (except on Mac and Windows). Therefore, using non-ASCII path names will mostly work even on platforms and file systems that use legacy extended ASCII encodings. However, repositories created on such systems will not work properly on UTF-8-based systems (e.g. Linux, Mac, Windows) and vice versa. Additionally, many Git-based tools simply assume path names to be UTF-8 and will fail to display other encodings correctly.
• Commit log messages are typically encoded in UTF-8, but other extended ASCII encodings are also supported. This includes ISO-8859-x, CP125x and many others, but not UTF-16/32, EBCDIC and CJK multi-byte encodings (GBK, Shift-JIS, Big5, EUC-x, CP9xx etc.).
Although we encourage that the commit log messages are encoded in UTF-8, both the core and Git Porcelain are designed not to force UTF-8 on projects. If all participants of a particular project find it more convenient to use legacy encodings, Git does not forbid it. However, there are a few things to keep in mind.
1. git commit and git commit-tree issues a warning if the commit log message given to it does not look like a valid UTF-8 string, unless you explicitly say your project uses a legacy encoding. The way to say this is to have i18n.commitEncoding in .git/config file, like this:
[i18n] commitEncoding = ISO-8859-1
Commit objects created with the above setting record the value of i18n.commitEncoding in its encoding header. This is to help other people who look at them later. Lack of this header implies that the commit log message is encoded in UTF-8.
2. git log, git show, git blame and friends look at the encoding header of a commit object, and try to re-code the log message into UTF-8 unless otherwise specified. You can specify the desired output encoding with i18n.logOutputEncoding in .git/config file, like this:
[i18n] logOutputEncoding = ISO-8859-1
If you do not have this configuration variable, the value of i18n.commitEncoding is used instead.
Note that we deliberately chose not to re-code the commit log message when a commit is made to force UTF-8 at the commit object level, because re-coding to UTF-8 is not necessarily a reversible operation.
CONFIGURATION See git‐config(1) for core variables and git‐diff(1) for settings related to diff generation.
format.pretty Default for the --format option. (See Pretty Formats above.) Defaults to medium.
i18n.logOutputEncoding Encoding to use when displaying logs. (See Discussion above.) Defaults to the value of i18n.commitEncoding if set, and UTF-8 otherwise.
Everything above this line in this section isn’t included from the git‐config(1) documentation. The content that follows is the same as what’s found there:
log.abbrevCommit If true, makes git‐log(1), git‐show(1), and git‐ whatchanged(1) assume --abbrev-commit. You may override this option with --no-abbrev-commit.
log.date Set the default date-time mode for the log command. Setting a value for log.date is similar to using git log's --date option. See git‐log(1) for details.
If the format is set to "auto:foo" and the pager is in use, format "foo" will be the used for the date format. Otherwise "default" will be used.
log.decorate Print out the ref names of any commits that are shown by the log command. If short is specified, the ref name prefixes refs/heads/, refs/tags/ and refs/remotes/ will not be printed. If full is specified, the full ref name (including prefix) will be printed. If auto is specified, then if the output is going to a terminal, the ref names are shown as if short were given, otherwise no ref names are shown. This is the same as the --decorate option of the git log.
log.initialDecorationSet By default, git log only shows decorations for certain known ref namespaces. If all is specified, then show all refs as decorations.
log.excludeDecoration Exclude the specified patterns from the log decorations. This is similar to the --decorate-refs-exclude command-line option, but the config option can be overridden by the --decorate-refs option.
log.diffMerges Set diff format to be used when --diff-merges=on is specified, see --diff-merges in git‐log(1) for details. Defaults to separate.
log.follow If true, git log will act as if the --follow option was used when a single <path> is given. This has the same limitations as --follow, i.e. it cannot be used to follow multiple files and does not work well on non-linear history.
log.graphColors A list of colors, separated by commas, that can be used to draw history lines in git log --graph.
log.showRoot If true, the initial commit will be shown as a big creation event. This is equivalent to a diff against an empty tree. Tools like git‐log(1) or git‐whatchanged(1), which normally hide the root commit will now show it. True by default.
log.showSignature If true, makes git‐log(1), git‐show(1), and git‐ whatchanged(1) assume --show-signature.
log.mailmap If true, makes git‐log(1), git‐show(1), and git‐ whatchanged(1) assume --use-mailmap, otherwise assume --no-use-mailmap. True by default.
notes.mergeStrategy Which merge strategy to choose by default when resolving notes conflicts. Must be one of manual, ours, theirs, union, or cat_sort_uniq. Defaults to manual. See "NOTES MERGE STRATEGIES" section of git‐notes(1) for more information on each strategy.
This setting can be overridden by passing the --strategy option to git‐notes(1).
notes.<name>.mergeStrategy Which merge strategy to choose when doing a notes merge into refs/notes/<name>. This overrides the more general "notes.mergeStrategy". See the "NOTES MERGE STRATEGIES" section in git‐notes(1) for more information on the available strategies.
notes.displayRef Which ref (or refs, if a glob or specified more than once), in addition to the default set by core.notesRef or GIT_NOTES_REF, to read notes from when showing commit messages with the git log family of commands.
This setting can be overridden with the GIT_NOTES_DISPLAY_REF environment variable, which must be a colon separated list of refs or globs.
A warning will be issued for refs that do not exist, but a glob that does not match any refs is silently ignored.
This setting can be disabled by the --no-notes option to the git log family of commands, or by the --notes=<ref> option accepted by those commands.
The effective value of "core.notesRef" (possibly overridden by GIT_NOTES_REF) is also implicitly added to the list of refs to be displayed.
notes.rewrite.<command> When rewriting commits with <command> (currently amend or rebase), if this variable is false, git will not copy notes from the original to the rewritten commit. Defaults to true. See also "notes.rewriteRef" below.
This setting can be overridden with the GIT_NOTES_REWRITE_REF environment variable, which must be a colon separated list of refs or globs.
notes.rewriteMode When copying notes during a rewrite (see the "notes.rewrite.<command>" option), determines what to do if the target commit already has a note. Must be one of overwrite, concatenate, cat_sort_uniq, or ignore. Defaults to concatenate.
This setting can be overridden with the GIT_NOTES_REWRITE_MODE environment variable.
notes.rewriteRef When copying notes during a rewrite, specifies the (fully qualified) ref whose notes should be copied. May be a glob, in which case notes in all matching refs will be copied. You may also specify this configuration several times.
Does not have a default value; you must configure this variable to enable note rewriting. Set it to refs/notes/commits to enable rewriting for the default commit notes.
Can be overridden with the GIT_NOTES_REWRITE_REF environment variable. See notes.rewrite.<command> above for a further description of its format.
GIT Part of the git(1) suite
Git 2.40.1 05/18/2023 GIT-LOG(1)

View the N Most Recent Commits

The following uses git-log to view the commit message, the commit date, the branch, the remote branch and author information of the most recent commit on the current branch:

Shell
$ git log -1
commit d9eaf1372978872c232c2875c7376f4e9e2dbd7f
Author: Mike Slinn <mslinn@mslinn.com>
Date:   Mon May 15 14:29:46 2023 -0400
this is a comment

Similarly, git log -N returns information about the N most recent commits.

Shell
$ git log -3
commit 795e7d363e0677ebf64ff02fc8e2e03bccf1ff9f (HEAD -> master, origin/master, origin/HEAD)
Author: Mike Slinn 
Date:   Thu Jul 13 14:20:50 2023 -0400
this is a comment
commit c0b0e51264c6077815241c8d0c584f2746cd30ab Author: Mike Slinn Date: Thu Jul 13 14:03:44 2023 -0400
yet another comment
commit a34f1b489ae450edec45acfedd46177135ae4bd6 Author: Mike Slinn Date: Thu Jul 13 14:02:54 2023 -0400
yay, another comment

Find Commit Of the First Version of a File

To get information about the first commit that has a specific file in it:

Shell
$ git log --diff-filter=A -- README.md
commit c8c92b5f19e49402aa367d470fb89b289ae788f0
Author: Mike Slinn 
Date:   Sat Jul 11 21:11:38 2020 -0400
This is the comment

To specify a file path, do not provide a leading slash. For example, write the path this way:

Good example of a path, without a leading slash
$ git log --diff-filter=A -- path/to/file.ext

Do not write it this way:

Bad example, path has a leading slash
$ git log --diff-filter=A -- /path/to/file.ext

Obtain Commit SHA Containing the First Version of a File

To get the hash of the first commit that has the file in it:

Shell
$ git log --format="%h" --diff-filter=A -- path/to/file.ext
c8c92b5 

To get 9 digits of the hash, use the --abbrev option:

Shell
$ git log --format="%h" --abbrev=9 --diff-filter=A -- path/to/file.ext
c8c92b5f1 

Git-Ls-Files

Here is the help information for git-ls-files.

Shell
$ git help ls-files
GIT-LS-FILES(1)               Git Manual               GIT-LS-FILES(1)
NAME git‐ls‐files - Show information about files in the index and the working tree
SYNOPSIS git ls-files [-z] [-t] [-v] [-f] [-c|--cached] [-d|--deleted] [-o|--others] [-i|--ignored] [-s|--stage] [-u|--unmerged] [-k|--killed] [-m|--modified] [--resolve-undo] [--directory [--no-empty-directory]] [--eol] [--deduplicate] [-x <pattern>|--exclude=<pattern>] [-X <file>|--exclude-from=<file>] [--exclude-per-directory=<file>] [--exclude-standard] [--error-unmatch] [--with-tree=<tree-ish>] [--full-name] [--recurse-submodules] [--abbrev[=<n>]] [--format=<format>] [--] [<file>...]
DESCRIPTION This merges the file listing in the index with the actual working directory list, and shows different combinations of the two.
One or more of the options below may be used to determine the files shown, and each file may be printed multiple times if there are multiple entries in the index or multiple statuses are applicable for the relevant file selection options.
OPTIONS -c, --cached Show all files cached in Git’s index, i.e. all tracked files. (This is the default if no -c/-s/-d/-o/-u/-k/-m/--resolve-undo options are specified.)
-d, --deleted Show files with an unstaged deletion
-m, --modified Show files with an unstaged modification (note that an unstaged deletion also counts as an unstaged modification)
-o, --others Show other (i.e. untracked) files in the output
-i, --ignored Show only ignored files in the output. Must be used with either an explicit -c or -o. When showing files in the index (i.e. when used with -c), print only those files matching an exclude pattern. When showing "other" files (i.e. when used with -o), show only those matched by an exclude pattern. Standard ignore rules are not automatically activated, therefore at least one of the --exclude* options is required.
-s, --stage Show staged contents' mode bits, object name and stage number in the output.
--directory If a whole directory is classified as "other", show just its name (with a trailing slash) and not its whole contents. Has no effect without -o/--others.
--no-empty-directory Do not list empty directories. Has no effect without --directory.
-u, --unmerged Show information about unmerged files in the output, but do not show any other tracked files (forces --stage, overrides --cached).
-k, --killed Show untracked files on the filesystem that need to be removed due to file/directory conflicts for tracked files to be able to be written to the filesystem.
--resolve-undo Show files having resolve-undo information in the index together with their resolve-undo information. (resolve-undo information is what is used to implement "git checkout -m $PATH", i.e. to recreate merge conflicts that were accidentally resolved)
-z \0 line termination on output and do not quote filenames. See OUTPUT below for more information.
--deduplicate When only filenames are shown, suppress duplicates that may come from having multiple stages during a merge, or giving --deleted and --modified option at the same time. When any of the -t, --unmerged, or --stage option is in use, this option has no effect.
-x <pattern>, --exclude=<pattern> Skip untracked files matching pattern. Note that pattern is a shell wildcard pattern. See EXCLUDE PATTERNS below for more information.
-X <file>, --exclude-from=<file> Read exclude patterns from <file>; 1 per line.
--exclude-per-directory=<file> Read additional exclude patterns that apply only to the directory and its subdirectories in <file>. Deprecated; use --exclude-standard instead.
--exclude-standard Add the standard Git exclusions: .git/info/exclude, .gitignore in each directory, and the user’s global exclusion file.
--error-unmatch If any <file> does not appear in the index, treat this as an error (return 1).
--with-tree=<tree-ish> When using --error-unmatch to expand the user supplied <file> (i.e. path pattern) arguments to paths, pretend that paths which were removed in the index since the named <tree-ish> are still present. Using this option with -s or -u options does not make any sense.
-t Show status tags together with filenames. Note that for scripting purposes, git‐status(1) --porcelain and git‐diff‐ files(1) --name-status are almost always superior alternatives, and users should look at git‐status(1) --short or git‐diff(1) --name-status for more user-friendly alternatives.
This option provides a reason for showing each filename, in the form of a status tag (which is followed by a space and then the filename). The status tags are all single characters from the following list:
H tracked file that is not either unmerged or skip-worktree
S tracked file that is skip-worktree
M tracked file that is unmerged
R tracked file with unstaged removal/deletion
C tracked file with unstaged modification/change
K untracked paths which are part of file/directory conflicts which prevent checking out tracked files
? untracked file
U file with resolve-undo information
-v Similar to -t, but use lowercase letters for files that are marked as assume unchanged (see git‐update‐index(1)).
-f Similar to -t, but use lowercase letters for files that are marked as fsmonitor valid (see git‐update‐index(1)).
--full-name When run from a subdirectory, the command usually outputs paths relative to the current directory. This option forces paths to be output relative to the project top directory.
--recurse-submodules Recursively calls ls-files on each active submodule in the repository. Currently there is only support for the --cached and --stage modes.
--abbrev[=<n>] Instead of showing the full 40-byte hexadecimal object lines, show the shortest prefix that is at least <n> hexdigits long that uniquely refers the object. Non default number of digits can be specified with --abbrev=<n>.
--debug After each line that describes a file, add more data about its cache entry. This is intended to show as much information as possible for manual inspection; the exact format may change at any time.
--eol Show <eolinfo> and <eolattr> of files. <eolinfo> is the file content identification used by Git when the "text" attribute is "auto" (or not set and core.autocrlf is not false). <eolinfo> is either "-text", "none", "lf", "crlf", "mixed" or "".
"" means the file is not a regular file, it is not in the index or not accessible in the working tree.
<eolattr> is the attribute that is used when checking out or committing, it is either "", "-text", "text", "text=auto", "text eol=lf", "text eol=crlf". Since Git 2.10 "text=auto eol=lf" and "text=auto eol=crlf" are supported.
Both the <eolinfo> in the index ("i/<eolinfo>") and in the working tree ("w/<eolinfo>") are shown for regular files, followed by the ("attr/<eolattr>").
--sparse If the index is sparse, show the sparse directories without expanding to the contained files. Sparse directories will be shown with a trailing slash, such as "x/" for a sparse directory "x".
--format=<format> A string that interpolates %(fieldname) from the result being shown. It also interpolates %% to %, and %xx where xx are hex digits interpolates to character with hex code xx; for example %00 interpolates to \0 (NUL), %09 to \t (TAB) and %0a to \n (LF). --format cannot be combined with -s, -o, -k, -t, --resolve-undo and --eol.
-- Do not interpret any more arguments as options.
<file> Files to show. If no files are given all files which match the other specified criteria are shown.
OUTPUT git ls-files just outputs the filenames unless --stage is specified in which case it outputs:
[<tag> ]<mode> <object> <stage> <file>
git ls-files --eol will show i/<eolinfo><SPACES>w/<eolinfo><SPACES>attr/<eolattr><SPACE*><TAB><file>
git ls-files --unmerged and git ls-files --stage can be used to examine detailed information on unmerged paths.
For an unmerged path, instead of recording a single mode/SHA-1 pair, the index records up to three such pairs; one from tree O in stage 1, A in stage 2, and B in stage 3. This information can be used by the user (or the porcelain) to see what should eventually be recorded at the path. (see git‐read‐tree(1) for more information on state)
Without the -z option, pathnames with "unusual" characters are quoted as explained for the configuration variable core.quotePath (see git‐config(1)). Using -z the filename is output verbatim and the line is terminated by a NUL byte.
It is possible to print in a custom format by using the --format option, which is able to interpolate different fields using a %(fieldname) notation. For example, if you only care about the "objectname" and "path" fields, you can execute with a specific "--format" like
git ls-files --format='%(objectname) %(path)'
FIELD NAMES The way each path is shown can be customized by using the --format=<format> option, where the %(fieldname) in the <format> string for various aspects of the index entry are interpolated. The following "fieldname" are understood:
objectmode The mode of the file which is recorded in the index.
objectname The name of the file which is recorded in the index.
stage The stage of the file which is recorded in the index.
eolinfo:index, eolinfo:worktree The <eolinfo> (see the description of the --eol option) of the contents in the index or in the worktree for the path.
eolattr The <eolattr> (see the description of the --eol option) that applies to the path.
path The pathname of the file which is recorded in the index.
EXCLUDE PATTERNS git ls-files can use a list of "exclude patterns" when traversing the directory tree and finding files to show when the flags --others or --ignored are specified. gitignore(5) specifies the format of exclude patterns.
Generally, you should just use --exclude-standard, but for historical reasons the exclude patterns can be specified from the following places, in order:
1. The command-line flag --exclude=<pattern> specifies a single pattern. Patterns are ordered in the same order they appear in the command line.
2. The command-line flag --exclude-from=<file> specifies a file containing a list of patterns. Patterns are ordered in the same order they appear in the file.
3. The command-line flag --exclude-per-directory=<name> specifies a name of the file in each directory git ls-files examines, normally .gitignore. Files in deeper directories take precedence. Patterns are ordered in the same order they appear in the files.
A pattern specified on the command line with --exclude or read from the file specified with --exclude-from is relative to the top of the directory tree. A pattern read from a file specified by --exclude-per-directory is relative to the directory that the pattern file appears in.
SEE ALSO git‐read‐tree(1), gitignore(5)
GIT Part of the git(1) suite
Git 2.40.1 05/18/2023 GIT-LS-FILES(1)

Git-Ls-Tree

Git ls-tree shows the contents of a tree object. This is the git-ls-tree man page:

Shell
$ git help ls-tree
GIT-LS-TREE(1)                Git Manual                GIT-LS-TREE(1)
NAME git‐ls‐tree - List the contents of a tree object
SYNOPSIS git ls-tree [-d] [-r] [-t] [-l] [-z] [--name-only] [--name-status] [--object-only] [--full-name] [--full-tree] [--abbrev[=<n>]] [--format=<format>] <tree-ish> [<path>...]
DESCRIPTION Lists the contents of a given tree object, like what "/bin/ls -a" does in the current working directory. Note that:
• the behaviour is slightly different from that of "/bin/ls" in that the <path> denotes just a list of patterns to match, e.g. so specifying directory name (without -r) will behave differently, and order of the arguments does not matter.
• the behaviour is similar to that of "/bin/ls" in that the <path> is taken as relative to the current working directory. E.g. when you are in a directory sub that has a directory dir, you can run git ls-tree -r HEAD dir to list the contents of the tree (that is sub/dir in HEAD). You don’t want to give a tree that is not at the root level (e.g. git ls-tree -r HEAD:sub dir) in this case, as that would result in asking for sub/sub/dir in the HEAD commit. However, the current working directory can be ignored by passing --full-tree option.
OPTIONS <tree-ish> Id of a tree-ish.
-d Show only the named tree entry itself, not its children.
-r Recurse into sub-trees.
-t Show tree entries even when going to recurse them. Has no effect if -r was not passed. -d implies -t.
-l, --long Show object size of blob (file) entries.
-z \0 line termination on output and do not quote filenames. See OUTPUT FORMAT below for more information.
--name-only, --name-status List only filenames (instead of the "long" output), one per line. Cannot be combined with --object-only.
--object-only List only names of the objects, one per line. Cannot be combined with --name-only or --name-status. This is equivalent to specifying --format='%(objectname)', but for both this option and that exact format the command takes a hand-optimized codepath instead of going through the generic formatting mechanism.
--abbrev[=<n>] Instead of showing the full 40-byte hexadecimal object lines, show the shortest prefix that is at least <n> hexdigits long that uniquely refers the object. Non default number of digits can be specified with --abbrev=<n>.
--full-name Instead of showing the path names relative to the current working directory, show the full path names.
--full-tree Do not limit the listing to the current working directory. Implies --full-name.
--format=<format> A string that interpolates %(fieldname) from the result being shown. It also interpolates %% to %, and %xx where xx are hex digits interpolates to character with hex code xx; for example %00 interpolates to \0 (NUL), %09 to \t (TAB) and %0a to \n (LF). When specified, --format cannot be combined with other format-altering options, including --long, --name-only and --object-only.
[<path>...] When paths are given, show them (note that this isn’t really raw pathnames, but rather a list of patterns to match). Otherwise implicitly uses the root level of the tree as the sole path argument.
OUTPUT FORMAT The output format of ls-tree is determined by either the --format option, or other format-altering options such as --name-only etc. (see --format above).
The use of certain --format directives is equivalent to using those options, but invoking the full formatting machinery can be slower than using an appropriate formatting option.
In cases where the --format would exactly map to an existing option ls-tree will use the appropriate faster path. Thus the default format is equivalent to:
%(objectmode) %(objecttype) %(objectname)%x09%(path)
This output format is compatible with what --index-info --stdin of git update-index expects.
When the -l option is used, format changes to
%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)
Object size identified by <objectname> is given in bytes, and right-justified with minimum width of 7 characters. Object size is given only for blobs (file) entries; for other entries - character is used in place of size.
Without the -z option, pathnames with "unusual" characters are quoted as explained for the configuration variable core.quotePath (see git‐config(1)). Using -z the filename is output verbatim and the line is terminated by a NUL byte.
Customized format:
It is possible to print in a custom format by using the --format option, which is able to interpolate different fields using a %(fieldname) notation. For example, if you only care about the "objectname" and "path" fields, you can execute with a specific "--format" like
git ls-tree --format='%(objectname) %(path)' <tree-ish>
FIELD NAMES Various values from structured fields can be used to interpolate into the resulting output. For each outputing line, the following names can be used:
objectmode The mode of the object.
objecttype The type of the object (commit, blob or tree).
objectname The name of the object.
objectsize[:padded] The size of a blob object ("-" if it’s a commit or tree). It also supports a padded format of size with "%(objectsize:padded)".
path The pathname of the object.
GIT Part of the git(1) suite
Git 2.40.1 05/18/2023 GIT-LS-TREE(1)
  • -t seems to be the default
  • --abbrev=6 shortens the SHAs to the first 6 characters, which is usually enough to make them unique

HEAD points to the snapshot of the most recent commit to a branch. To see what the first 10 lines of that snapshot looks like, run the following in the root directory of your repository:

Shell
$ git ls-tree --name-only HEAD | head
.bundle
.gitignore
.rubocop.yml
.ruby-version
.shellcheckrc
.vscode
404.html
670nm.html 

Directory enties can be suppressed, such that only files are recursively displayed, via the -r option:

Shell
$ git ls-tree --name-only -r HEAD | head
100644 .bundle/config
.gitignore
.rubocop.yml
.ruby-version
.shellcheckrc
.vscode/launch.json
.vscode/settings.json
.vscode/tasks.json
404.html
670nm.html 

The default is to display the commit’s mode, type and SHA as well as the file name:

Shell
$ git ls-tree HEAD | head
040000 tree aaf10b00a2daba90550321ed46912db00c690a62    .bundle
100644 blob 6e11c49ab69e6d2ca5109dffd269b0ce3e97f767    .gitignore
100644 blob f480670f694bc102098c514b695b177b6258cc3f    .rubocop.yml
100644 blob fd2a01863fdd3035fac5918c59666363544bfe23    .ruby-version
100644 blob 4e0ef479723860d16a332347a691d422a0ef2770    .shellcheckrc
040000 tree bd6408dfd6ecaba73a77c4cff0c9a82dadff76d6    .vscode
100644 blob 14ad2b4cc7658f00f26da39cc70583f6750c2943    404.html
100644 blob 1fe1aa295d166663285b54cb94954bfe19da152c    670nm.html
100644 blob 02862b254846b5669596de4d2795d023ebc87c7c    BingSiteAuth.xml
100644 blob e527be14f8b957cbbd3517a16198a701e38f5dd7    Gemfile 

Git-Rev-Parse

This is the help message for git-rev-parse – the Swiss Army Knife for git. It supports revision syntax.

Shell
$ man git-rev-parse
GIT-REV-PARSE(1)              Git Manual              GIT-REV-PARSE(1)
NAME git‐rev‐parse - Pick out and massage parameters
SYNOPSIS git rev-parse [<options>] <args>...
DESCRIPTION Many Git porcelainish commands take mixture of flags (i.e. parameters that begin with a dash -) and parameters meant for the underlying git rev-list command they use internally and flags and parameters for the other commands they use downstream of git rev-list. This command is used to distinguish between them.
OPTIONS Operation Modes Each of these options must appear first on the command line.
--parseopt Use git rev-parse in option parsing mode (see PARSEOPT section below).
--sq-quote Use git rev-parse in shell quoting mode (see SQ-QUOTE section below). In contrast to the --sq option below, this mode does only quoting. Nothing else is done to command input.
Options for --parseopt --keep-dashdash Only meaningful in --parseopt mode. Tells the option parser to echo out the first -- met instead of skipping it.
--stop-at-non-option Only meaningful in --parseopt mode. Lets the option parser stop at the first non-option argument. This can be used to parse sub-commands that take options themselves.
--stuck-long Only meaningful in --parseopt mode. Output the options in their long form if available, and with their arguments stuck.
Options for Filtering --revs-only Do not output flags and parameters not meant for git rev-list command.
--no-revs Do not output flags and parameters meant for git rev-list command.
--flags Do not output non-flag parameters.
--no-flags Do not output flag parameters.
Options for Output --default <arg> If there is no parameter given by the user, use <arg> instead.
--prefix <arg> Behave as if git rev-parse was invoked from the <arg> subdirectory of the working tree. Any relative filenames are resolved as if they are prefixed by <arg> and will be printed in that form.
This can be used to convert arguments to a command run in a subdirectory so that they can still be used after moving to the top-level of the repository. For example:
prefix=$(git rev-parse --show-prefix) cd "$(git rev-parse --show-toplevel)" # rev-parse provides the -- needed for 'set' eval "set $(git rev-parse --sq --prefix "$prefix" -- "$@")"
--verify Verify that exactly one parameter is provided, and that it can be turned into a raw 20-byte SHA-1 that can be used to access the object database. If so, emit it to the standard output; otherwise, error out.
If you want to make sure that the output actually names an object in your object database and/or can be used as a specific type of object you require, you can add the ^{type} peeling operator to the parameter. For example, git rev-parse "$VAR^{commit}" will make sure $VAR names an existing object that is a commit-ish (i.e. a commit, or an annotated tag that points at a commit). To make sure that $VAR names an existing object of any type, git rev-parse "$VAR^{object}" can be used.
Note that if you are verifying a name from an untrusted source, it is wise to use --end-of-options so that the name argument is not mistaken for another option.
-q, --quiet Only meaningful in --verify mode. Do not output an error message if the first argument is not a valid object name; instead exit with non-zero status silently. SHA-1s for valid object names are printed to stdout on success.
--sq Usually the output is made one line per flag and parameter. This option makes output a single line, properly quoted for consumption by shell. Useful when you expect your parameter to contain whitespaces and newlines (e.g. when using pickaxe -S with git diff-*). In contrast to the --sq-quote option, the command input is still interpreted as usual.
--short[=length] Same as --verify but shortens the object name to a unique prefix with at least length characters. The minimum length is 4, the default is the effective value of the core.abbrev configuration variable (see git‐config(1)).
--not When showing object names, prefix them with ^ and strip ^ prefix from the object names that already have one.
--abbrev-ref[=(strict|loose)] A non-ambiguous short name of the objects name. The option core.warnAmbiguousRefs is used to select the strict abbreviation mode.
--symbolic Usually the object names are output in SHA-1 form (with possible ^ prefix); this option makes them output in a form as close to the original input as possible.
--symbolic-full-name This is similar to --symbolic, but it omits input that are not refs (i.e. branch or tag names; or more explicitly disambiguating "heads/master" form, when you want to name the "master" branch when there is an unfortunately named tag "master"), and show them as full refnames (e.g. "refs/heads/master").
Options for Objects --all Show all refs found in refs/.
--branches[=pattern], --tags[=pattern], --remotes[=pattern] Show all branches, tags, or remote-tracking branches, respectively (i.e., refs found in refs/heads, refs/tags, or refs/remotes, respectively).
If a pattern is given, only refs matching the given shell glob are shown. If the pattern does not contain a globbing character (?, *, or [), it is turned into a prefix match by appending /*.
--glob=pattern Show all refs matching the shell glob pattern pattern. If the pattern does not start with refs/, this is automatically prepended. If the pattern does not contain a globbing character (?, *, or [), it is turned into a prefix match by appending /*.
--exclude=<glob-pattern> Do not include refs matching <glob-pattern> that the next --all, --branches, --tags, --remotes, or --glob would otherwise consider. Repetitions of this option accumulate exclusion patterns up to the next --all, --branches, --tags, --remotes, or --glob option (other options or arguments do not clear accumulated patterns).
The patterns given should not begin with refs/heads, refs/tags, or refs/remotes when applied to --branches, --tags, or --remotes, respectively, and they must begin with refs/ when applied to --glob or --all. If a trailing /* is intended, it must be given explicitly.
--exclude-hidden=[receive|uploadpack] Do not include refs that would be hidden by git-receive-pack or git-upload-pack by consulting the appropriate receive.hideRefs or uploadpack.hideRefs configuration along with transfer.hideRefs (see git‐ config(1)). This option affects the next pseudo-ref option --all or --glob and is cleared after processing them.
--disambiguate=<prefix> Show every object whose name begins with the given prefix. The <prefix> must be at least 4 hexadecimal digits long to avoid listing each and every object in the repository by mistake.
Options for Files --local-env-vars List the GIT_* environment variables that are local to the repository (e.g. GIT_DIR or GIT_WORK_TREE, but not GIT_EDITOR). Only the names of the variables are listed, not their value, even if they are set.
--path-format=(absolute|relative) Controls the behavior of certain other options. If specified as absolute, the paths printed by those options will be absolute and canonical. If specified as relative, the paths will be relative to the current working directory if that is possible. The default is option specific.
This option may be specified multiple times and affects only the arguments that follow it on the command line, either to the end of the command line or the next instance of this option.
The following options are modified by --path-format:
--git-dir Show $GIT_DIR if defined. Otherwise show the path to the .git directory. The path shown, when relative, is relative to the current working directory.
If $GIT_DIR is not defined and the current directory is not detected to lie in a Git repository or work tree print a message to stderr and exit with nonzero status.
--git-common-dir Show $GIT_COMMON_DIR if defined, else $GIT_DIR.
--resolve-git-dir <path> Check if <path> is a valid repository or a gitfile that points at a valid repository, and print the location of the repository. If <path> is a gitfile then the resolved path to the real repository is printed.
--git-path <path> Resolve "$GIT_DIR/<path>" and takes other path relocation variables such as $GIT_OBJECT_DIRECTORY, $GIT_INDEX_FILE... into account. For example, if $GIT_OBJECT_DIRECTORY is set to /foo/bar then "git rev-parse --git-path objects/abc" returns /foo/bar/abc.
--show-toplevel Show the (by default, absolute) path of the top-level directory of the working tree. If there is no working tree, report an error.
--show-superproject-working-tree Show the absolute path of the root of the superproject’s working tree (if exists) that uses the current repository as its submodule. Outputs nothing if the current repository is not used as a submodule by any project.
--shared-index-path Show the path to the shared index file in split index mode, or empty if not in split-index mode.
The following options are unaffected by --path-format:
--absolute-git-dir Like --git-dir, but its output is always the canonicalized absolute path.
--is-inside-git-dir When the current working directory is below the repository directory print "true", otherwise "false".
--is-inside-work-tree When the current working directory is inside the work tree of the repository print "true", otherwise "false".
--is-bare-repository When the repository is bare print "true", otherwise "false".
--is-shallow-repository When the repository is shallow print "true", otherwise "false".
--show-cdup When the command is invoked from a subdirectory, show the path of the top-level directory relative to the current directory (typically a sequence of "../", or an empty string).
--show-prefix When the command is invoked from a subdirectory, show the path of the current directory relative to the top-level directory.
--show-object-format[=(storage|input|output)] Show the object format (hash algorithm) used for the repository for storage inside the .git directory, input, or output. For input, multiple algorithms may be printed, space-separated. If not specified, the default is "storage".
Other Options --since=datestring, --after=datestring Parse the date string, and output the corresponding --max-age= parameter for git rev-list.
--until=datestring, --before=datestring Parse the date string, and output the corresponding --min-age= parameter for git rev-list.
<args>... Flags and parameters to be parsed.
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 and CHERRY_PICK_HEAD);
2. otherwise, refs/<refname> if it exists;
3. otherwise, refs/tags/<refname> if it exists;
4. otherwise, refs/heads/<refname> if it exists;
5. otherwise, refs/remotes/<refname> if it exists;
6. otherwise, refs/remotes/<refname>/HEAD if it exists.
HEAD names the commit on which you based the changes in the working tree. FETCH_HEAD records the branch which you fetched from a remote repository with your last git fetch invocation. ORIG_HEAD is created by commands that move your HEAD in a drastic way (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. CHERRY_PICK_HEAD records the commit which you are cherry-picking when you run git cherry-pick.
Note that any of the refs/* cases above may come either from the $GIT_DIR/refs directory or from the $GIT_DIR/packed-refs file. While the ref name encoding is unspecified, UTF-8 is preferred as some output processing may assume ref names in UTF-8.
@ @ alone is a shortcut for HEAD.
[<refname>]@{<date>}, e.g. master@{yesterday}, HEAD@{5 minutes ago} A ref followed by the suffix @ with a date specification enclosed in a brace pair (e.g. {yesterday}, {1 month 2 weeks 3 days 1 hour 1 second ago} or {1979-02-26 18:30:00}) specifies the value of the ref at a prior point in time. This suffix may only be used immediately following a ref name and the ref must have an existing log ($GIT_DIR/logs/<ref>). Note that this looks up the state of your local ref at a given time; e.g., what was in your local master branch last week. If you want to look at commits made during certain times, see --since and --until.
<refname>@{<n>}, e.g. master@{1} A ref followed by the suffix @ with an ordinal specification enclosed in a brace pair (e.g. {1}, {15}) specifies the n-th prior value of that ref. For example master@{1} is the immediate prior value of master while master@{5} is the 5th prior value of master. This suffix may only be used immediately following a ref name and the ref must have an existing log ($GIT_DIR/logs/<refname>).
@{<n>}, e.g. @{1} You can use the @ construct with an empty ref part to get at a reflog entry of the current branch. For example, if you are on branch blabla then @{1} means the same as blabla@{1}.
@{-<n>}, e.g. @{-1} The construct @{-<n>} means the <n>th branch/commit checked out before the current one.
[<branchname>]@{upstream}, e.g. master@{upstream}, @{u} 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
PARSEOPT In --parseopt mode, git rev-parse helps massaging options to bring to shell scripts the same facilities C builtins have. It works as an option normalizer (e.g. splits single switches aggregate values), a bit like getopt(1) does.
It takes on the standard input the specification of the options to parse and understand, and echoes on the standard output a string suitable for sh(1) eval to replace the arguments with normalized ones. In case of error, it outputs usage on the standard error stream, and exits with code 129.
Note: Make sure you quote the result when passing it to eval. See below for an example.
Input Format git rev-parse --parseopt input format is fully text based. It has two parts, separated by a line that contains only --. The lines before the separator (should be one or more) are used for the usage. The lines after the separator describe the options.
Each line of options has this format:
<opt-spec><flags>*<arg-hint>? SP+ help LF
<opt-spec> its format is the short option character, then the long option name separated by a comma. Both parts are not required, though at least one is necessary. May not contain any of the <flags> characters. h,help, dry-run and f are examples of correct <opt-spec>.
<flags> <flags> are of *, =, ? or !.
• Use = if the option takes an argument.
• Use ? to mean that the option takes an optional argument. You probably want to use the --stuck-long mode to be able to unambiguously parse the optional argument.
• Use * to mean that this option should not be listed in the usage generated for the -h argument. It’s shown for --help-all as documented in gitcli(7).
• Use ! to not make the corresponding negated long option available.
<arg-hint> <arg-hint>, if specified, is used as a name of the argument in the help output, for options that take arguments. <arg-hint> is terminated by the first whitespace. It is customary to use a dash to separate words in a multi-word argument hint.
The remainder of the line, after stripping the spaces, is used as the help associated to the option.
Blank lines are ignored, and lines that don’t match this specification are used as option group headers (start the line with a space to create such lines on purpose).
Example OPTS_SPEC="\ some-command [<options>] <args>...
some-command does foo and bar! -- h,help show the help
foo some nifty option --foo bar= some cool option --bar with an argument baz=arg another cool option --baz with a named argument qux?path qux may take a path argument but has meaning by itself
An option group Header C? option C with an optional argument"
eval "$(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)"
Usage text When "$@" is -h or --help in the above example, the following usage text would be shown:
usage: some-command [<options>] <args>...
some-command does foo and bar!
-h, --help show the help --foo some nifty option --foo --bar ... some cool option --bar with an argument --baz <arg> another cool option --baz with a named argument --qux[=<path>] qux may take a path argument but has meaning by itself
An option group Header -C[...] option C with an optional argument
SQ-QUOTE In --sq-quote mode, git rev-parse echoes on the standard output a single line suitable for sh(1) eval. This line is made by normalizing the arguments following --sq-quote. Nothing other than quoting the arguments is done.
If you want command input to still be interpreted as usual by git rev-parse before the output is shell quoted, see the --sq option.
Example $ cat >your-git-script.sh <<\EOF #!/bin/sh args=$(git rev-parse --sq-quote "$@") # quote user-supplied arguments command="git frotz -n24 $args" # and use it inside a handcrafted # command line eval "$command" EOF
$ sh your-git-script.sh "a b'c"
EXAMPLES • Print the object name of the current commit:
$ git rev-parse --verify HEAD
• Print the commit object name from the revision in the $REV shell variable:
$ git rev-parse --verify --end-of-options $REV^{commit}
This will error out if $REV is empty or not a valid revision.
• Similar to above:
$ git rev-parse --default master --verify --end-of-options $REV
but if $REV is empty, the commit object name from master will be printed.
GIT Part of the git(1) suite
Git 2.40.1 05/18/2023 GIT-REV-PARSE(1)

There are several ways to discover the SHA of the HEAD commit:

Shell
$ git rev-parse HEAD
d9eaf1372978872c232c2875c7376f4e9e2dbd7f 
$ $ git rev-parse --symbolic-full-name HEAD refs/heads/master
$ git rev-parse refs/heads/master d9eaf1372978872c232c2875c7376f4e9e2dbd7f
$ git rev-parse --short HEAD d9eaf137
$ git rev-parse --short master d9eaf137
$ git rev-parse --short refs/heads/master d9eaf137
$ git rev-parse --short @ d9eaf137

Read about accessing parent commits. You can get the SHA of the penultimate commit (the parent of HEAD), and the SHA of the commit before that:

Shell
$ git rev-parse --short HEAD~
e4e53f69 
$ git rev-parse --short HEAD~2 1d711f74

Use the reflog to access the snapshot of the previous value of HEAD:

Shell
$ git rev-parse --short HEAD@{1}
e4e53f69 

Git-Show

This is the help message for git-show:

Shell
$ man git-show
GIT-SHOW(1)                   Git Manual                   GIT-SHOW(1)
NAME git‐show - Show various types of objects
SYNOPSIS git show [<options>] [<object>...]
DESCRIPTION Shows one or more objects (blobs, trees, tags and commits).
For commits it shows the log message and textual diff. It also presents the merge commit in a special format as produced by git diff-tree --cc.
For tags, it shows the tag message and the referenced objects.
For trees, it shows the names (equivalent to git ls-tree with --name-only).
For plain blobs, it shows the plain contents.
The command takes options applicable to the git diff-tree command to control how the changes the commit introduces are shown.
This manual page describes only the most frequently used options.
OPTIONS <object>... The names of objects to show (defaults to HEAD). For a more complete list of ways to spell object names, see "SPECIFYING REVISIONS" section in gitrevisions(7).
--pretty[=<format>], --format=<format> Pretty-print the contents of the commit logs in a given format, where <format> can be one of oneline, short, medium, full, fuller, reference, email, raw, format:<string> and tformat:<string>. When <format> is none of the above, and has %placeholder in it, it acts as if --pretty=tformat:<format> were given.
See the "PRETTY FORMATS" section for some additional details for each format. When =<format> part is omitted, it defaults to medium.
Note: you can specify the default pretty format in the repository configuration (see git‐config(1)).
--abbrev-commit Instead of showing the full 40-byte hexadecimal commit object name, show a prefix that names the object uniquely. "--abbrev=<n>" (which also modifies diff output, if it is displayed) option can be used to specify the minimum length of the prefix.
This should make "--pretty=oneline" a whole lot more readable for people using 80-column terminals.
--no-abbrev-commit Show the full 40-byte hexadecimal commit object name. This negates --abbrev-commit, either explicit or implied by other options such as "--oneline". It also overrides the log.abbrevCommit variable.
--oneline This is a shorthand for "--pretty=oneline --abbrev-commit" used together.
--encoding=<encoding> Commit objects record the character encoding used for the log message in their encoding header; this option can be used to tell the command to re-code the commit log message in the encoding preferred by the user. For non plumbing commands this defaults to UTF-8. Note that if an object claims to be encoded in X and we are outputting in X, we will output the object verbatim; this means that invalid sequences in the original commit may be copied to the output. Likewise, if iconv(3) fails to convert the commit, we will quietly output the original object verbatim.
--expand-tabs=<n>, --expand-tabs, --no-expand-tabs Perform a tab expansion (replace each tab with enough spaces to fill to the next display column that is multiple of <n>) in the log message before showing it in the output. --expand-tabs is a short-hand for --expand-tabs=8, and --no-expand-tabs is a short-hand for --expand-tabs=0, which disables tab expansion.
By default, tabs are expanded in pretty formats that indent the log message by 4 spaces (i.e. medium, which is the default, full, and fuller).
--notes[=<ref>] Show the notes (see git‐notes(1)) that annotate the commit, when showing the commit log message. This is the default for git log, git show and git whatchanged commands when there is no --pretty, --format, or --oneline option given on the command line.
By default, the notes shown are from the notes refs listed in the core.notesRef and notes.displayRef variables (or corresponding environment overrides). See git‐config(1) for more details.
With an optional <ref> argument, use the ref to find the notes to display. The ref can specify the full refname when it begins with refs/notes/; when it begins with notes/, refs/ and otherwise refs/notes/ is prefixed to form a full name of the ref.
Multiple --notes options can be combined to control which notes are being displayed. Examples: "--notes=foo" will show only notes from "refs/notes/foo"; "--notes=foo --notes" will show both notes from "refs/notes/foo" and from the default notes ref(s).
--no-notes Do not show notes. This negates the above --notes option, by resetting the list of notes refs from which notes are shown. Options are parsed in the order given on the command line, so e.g. "--notes --notes=foo --no-notes --notes=bar" will only show notes from "refs/notes/bar".
--show-notes[=<ref>], --[no-]standard-notes These options are deprecated. Use the above --notes/--no-notes options instead.
--show-signature Check the validity of a signed commit object by passing the signature to gpg --verify and show the output.
PRETTY FORMATS If the commit is a merge, and if the pretty-format is not oneline, email or raw, an additional line is inserted before the Author: line. This line begins with "Merge: " and the hashes of ancestral commits are printed, separated by spaces. Note that the listed commits may not necessarily be the list of the direct parent commits if you have limited your view of history: for example, if you are only interested in changes related to a certain directory or file.
There are several built-in formats, and you can define additional formats by setting a pretty.<name> config option to either another format name, or a format: string, as described below (see git‐config(1)). Here are the details of the built-in formats:
• oneline
<hash> <title-line>
This is designed to be as compact as possible.
• short
commit <hash> Author: <author>
<title-line>
• medium
commit <hash> Author: <author> Date: <author-date>
<title-line>
<full-commit-message>
• full
commit <hash> Author: <author> Commit: <committer>
<title-line>
<full-commit-message>
• fuller
commit <hash> Author: <author> AuthorDate: <author-date> Commit: <committer> CommitDate: <committer-date>
<title-line>
<full-commit-message>
• reference
<abbrev-hash> (<title-line>, <short-author-date>)
This format is used to refer to another commit in a commit message and is the same as --pretty='format:%C(auto)%h (%s, %ad)'. By default, the date is formatted with --date=short unless another --date option is explicitly specified. As with any format: with format placeholders, its output is not affected by other options like --decorate and --walk-reflogs.
• email
From <hash> <date> From: <author> Date: <author-date> Subject: [PATCH] <title-line>
<full-commit-message>
• mboxrd
Like email, but lines in the commit message starting with "From " (preceded by zero or more ">") are quoted with ">" so they aren’t confused as starting a new commit.
• raw
The raw format shows the entire commit exactly as stored in the commit object. Notably, the hashes are displayed in full, regardless of whether --abbrev or --no-abbrev are used, and parents information show the true parent commits, without taking grafts or history simplification into account. Note that this format affects the way commits are displayed, but not the way the diff is shown e.g. with git log --raw. To get full object names in a raw diff format, use --no-abbrev.
• format:<format-string>
The format:<format-string> format allows you to specify which information you want to show. It works a little bit like printf format, with the notable exception that you get a newline with %n instead of \n.
E.g, format:"The author of %h was %an, %ar%nThe title was >>%s<<%n" would show something like this:
The author of fe6e0ee was Junio C Hamano, 23 hours ago The title was >>t4119: test autocomputing -p<n> for traditional diff input.<<
The placeholders are:
• Placeholders that expand to a single literal character:
%n newline
%% a raw %
%x00 print a byte from a hex code
• Placeholders that affect formatting of later placeholders:
%Cred switch color to red
%Cgreen switch color to green
%Cblue switch color to blue
%Creset reset color
%C(...) color specification, as described under Values in the "CONFIGURATION FILE" section of git‐config(1). By default, colors are shown only when enabled for log output (by color.diff, color.ui, or --color, and respecting the auto settings of the former if we are going to a terminal). %C(auto,...) is accepted as a historical synonym for the default (e.g., %C(auto,red)). Specifying %C(always,...) will show the colors even when color is not otherwise enabled (though consider just using --color=always to enable color for the whole output, including this format and anything else git might color). auto alone (i.e. %C(auto)) will turn on auto coloring on the next placeholders until the color is switched again.
%m left (<), right (>) or boundary (-) mark
%w([<w>[,<i1>[,<i2>]]]) switch line wrapping, like the -w option of git‐ shortlog(1).
%<( <N> [,trunc|ltrunc|mtrunc]) make the next placeholder take at least N column widths, padding spaces on the right if necessary. Optionally truncate (with ellipsis ..) at the left (ltrunc) ..ft, the middle (mtrunc) mi..le, or the end (trunc) rig.., if the output is longer than N columns. Note 1: that truncating only works correctly with N >= 2. Note 2: spaces around the N and M (see below) values are optional. Note 3: Emojis and other wide characters will take two display columns, which may over-run column boundaries. Note 4: decomposed character combining marks may be misplaced at padding boundaries.
%<|( <M> ) make the next placeholder take at least until Mth display column, padding spaces on the right if necessary. Use negative M values for column positions measured from the right hand edge of the terminal window.
%>( <N> ), %>|( <M> ) similar to %<( <N> ), %<|( <M> ) respectively, but padding spaces on the left
%>>( <N> ), %>>|( <M> ) similar to %>( <N> ), %>|( <M> ) respectively, except that if the next placeholder takes more spaces than given and there are spaces on its left, use those spaces
%><( <N> ), %><|( <M> ) similar to %<( <N> ), %<|( <M> ) respectively, but padding both sides (i.e. the text is centered)
• Placeholders that expand to information extracted from the commit:
%H commit hash
%h abbreviated commit hash
%T tree hash
%t abbreviated tree hash
%P parent hashes
%p abbreviated parent hashes
%an author name
%aN author name (respecting .mailmap, see git‐ shortlog(1) or git‐blame(1))
%ae author email
%aE author email (respecting .mailmap, see git‐ shortlog(1) or git‐blame(1))
%al author email local-part (the part before the @ sign)
%aL author local-part (see %al) respecting .mailmap, see git‐shortlog(1) or git‐blame(1))
%ad author date (format respects --date= option)
%aD author date, RFC2822 style
%ar author date, relative
%at author date, UNIX timestamp
%ai author date, ISO 8601-like format
%aI author date, strict ISO 8601 format
%as author date, short format (YYYY-MM-DD)
%ah author date, human style (like the --date=human option of git‐rev‐list(1))
%cn committer name
%cN committer name (respecting .mailmap, see git‐ shortlog(1) or git‐blame(1))
%ce committer email
%cE committer email (respecting .mailmap, see git‐ shortlog(1) or git‐blame(1))
%cl committer email local-part (the part before the @ sign)
%cL committer local-part (see %cl) respecting .mailmap, see git‐shortlog(1) or git‐blame(1))
%cd committer date (format respects --date= option)
%cD committer date, RFC2822 style
%cr committer date, relative
%ct committer date, UNIX timestamp
%ci committer date, ISO 8601-like format
%cI committer date, strict ISO 8601 format
%cs committer date, short format (YYYY-MM-DD)
%ch committer date, human style (like the --date=human option of git‐rev‐list(1))
%d ref names, like the --decorate option of git‐log(1)
%D ref names without the " (", ")" wrapping.
%(describe[:options]) human-readable name, like git‐describe(1); empty string for undescribable commits. The describe string may be followed by a colon and zero or more comma-separated options. Descriptions can be inconsistent when tags are added or removed at the same time.
• tags[=<bool-value>]: Instead of only considering annotated tags, consider lightweight tags as well.
• abbrev=<number>: Instead of using the default number of hexadecimal digits (which will vary according to the number of objects in the repository with a default of 7) of the abbreviated object name, use <number> digits, or as many digits as needed to form a unique object name.
• match=<pattern>: Only consider tags matching the given glob(7) pattern, excluding the "refs/tags/" prefix.
• exclude=<pattern>: Do not consider tags matching the given glob(7) pattern, excluding the "refs/tags/" prefix.
%S ref name given on the command line by which the commit was reached (like git log --source), only works with git log
%e encoding
%s subject
%f sanitized subject line, suitable for a filename
%b body
%B raw body (unwrapped subject and body)
%N commit notes
%GG raw verification message from GPG for a signed commit
%G? show "G" for a good (valid) signature, "B" for a bad signature, "U" for a good signature with unknown validity, "X" for a good signature that has expired, "Y" for a good signature made by an expired key, "R" for a good signature made by a revoked key, "E" if the signature cannot be checked (e.g. missing key) and "N" for no signature
%GS show the name of the signer for a signed commit
%GK show the key used to sign a signed commit
%GF show the fingerprint of the key used to sign a signed commit
%GP show the fingerprint of the primary key whose subkey was used to sign a signed commit
%GT show the trust level for the key used to sign a signed commit
%gD reflog selector, e.g., refs/stash@{1} or refs/stash@{2 minutes ago}; the format follows the rules described for the -g option. The portion before the @ is the refname as given on the command line (so git log -g refs/heads/master would yield refs/heads/master@{0}).
%gd shortened reflog selector; same as %gD, but the refname portion is shortened for human readability (so refs/heads/master becomes just master).
%gn reflog identity name
%gN reflog identity name (respecting .mailmap, see git‐ shortlog(1) or git‐blame(1))
%ge reflog identity email
%gE reflog identity email (respecting .mailmap, see git‐shortlog(1) or git‐blame(1))
%gs reflog subject
%(trailers[:options]) display the trailers of the body as interpreted by git‐interpret‐trailers(1). The trailers string may be followed by a colon and zero or more comma-separated options. If any option is provided multiple times the last occurrence wins.
• key=<key>: only show trailers with specified <key>. Matching is done case-insensitively and trailing colon is optional. If option is given multiple times trailer lines matching any of the keys are shown. This option automatically enables the only option so that non-trailer lines in the trailer block are hidden. If that is not desired it can be disabled with only=false. E.g., %(trailers:key=Reviewed-by) shows trailer lines with key Reviewed-by.
• only[=<bool>]: select whether non-trailer lines from the trailer block should be included.
• separator=<sep>: specify a separator inserted between trailer lines. When this option is not given each trailer line is terminated with a line feed character. The string <sep> may contain the literal formatting codes described above. To use comma as separator one must use %x2C as it would otherwise be parsed as next option. E.g., %(trailers:key=Ticket,separator=%x2C ) shows all trailer lines whose key is "Ticket" separated by a comma and a space.
• unfold[=<bool>]: make it behave as if interpret-trailer’s --unfold option was given. E.g., %(trailers:only,unfold=true) unfolds and shows all trailer lines.
• keyonly[=<bool>]: only show the key part of the trailer.
• valueonly[=<bool>]: only show the value part of the trailer.
• key_value_separator=<sep>: specify a separator inserted between trailer lines. When this option is not given each trailer key-value pair is separated by ": ". Otherwise it shares the same semantics as separator=<sep> above.
Note
Some placeholders may depend on other options given to the revision traversal engine. For example, the %g* reflog options will insert an empty string unless we are traversing reflog entries (e.g., by git log -g). The %d and %D placeholders will use the "short" decoration format if --decorate was not already provided on the command line.
The boolean options accept an optional value [=<bool-value>]. The values true, false, on, off etc. are all accepted. See the "boolean" sub-section in "EXAMPLES" in git‐config(1). If a boolean option is given with no value, it’s enabled.
If you add a + (plus sign) after % of a placeholder, a line-feed is inserted immediately before the expansion if and only if the placeholder expands to a non-empty string.
If you add a - (minus sign) after % of a placeholder, all consecutive line-feeds immediately preceding the expansion are deleted if and only if the placeholder expands to an empty string.
If you add a ‘ ‘ (space) after % of a placeholder, a space is inserted immediately before the expansion if and only if the placeholder expands to a non-empty string.
• tformat:
The tformat: format works exactly like format:, except that it provides "terminator" semantics instead of "separator" semantics. In other words, each commit has the message terminator character (usually a newline) appended, rather than a separator placed between entries. This means that the final entry of a single-line format will be properly terminated with a new line, just as the "oneline" format does. For example:
$ git log -2 --pretty=format:%h 4da45bef \ | perl -pe '$_ .= " -- NO NEWLINE\n" unless /\n/' 4da45be 7134973 -- NO NEWLINE
$ git log -2 --pretty=tformat:%h 4da45bef \ | perl -pe '$_ .= " -- NO NEWLINE\n" unless /\n/' 4da45be 7134973
In addition, any unrecognized string that has a % in it is interpreted as if it has tformat: in front of it. For example, these two are equivalent:
$ git log -2 --pretty=tformat:%h 4da45bef $ git log -2 --pretty=%h 4da45bef
DIFF FORMATTING The options below can be used to change the way git show generates diff output.
-p, -u, --patch Generate patch (see section titled "Generating patch text with -p").
-s, --no-patch Suppress diff output. Useful for commands like git show that show the patch by default, or to cancel the effect of --patch.
--diff-merges=(off|none|on|first-parent|1|separate|m|combined|c|dense-combined|cc|remerge|r), --no-diff-merges Specify diff format to be used for merge commits. Default is dense-combined unless --first-parent is in use, in which case first-parent is the default.
--diff-merges=(off|none), --no-diff-merges Disable output of diffs for merge commits. Useful to override implied value.
--diff-merges=on, --diff-merges=m, -m This option makes diff output for merge commits to be shown in the default format. -m will produce the output only if -p is given as well. The default format could be changed using log.diffMerges configuration parameter, which default value is separate.
--diff-merges=first-parent, --diff-merges=1 This option makes merge commits show the full diff with respect to the first parent only.
--diff-merges=separate This makes merge commits show the full diff with respect to each of the parents. Separate log entry and diff is generated for each parent.
--diff-merges=remerge, --diff-merges=r, --remerge-diff With this option, two-parent merge commits are remerged to create a temporary tree object — potentially containing files with conflict markers and such. A diff is then shown between that temporary tree and the actual merge commit.
The output emitted when this option is used is subject to change, and so is its interaction with other options (unless explicitly documented).
--diff-merges=combined, --diff-merges=c, -c With this option, diff output for a merge commit shows the differences from each of the parents to the merge result simultaneously instead of showing pairwise diff between a parent and the result one at a time. Furthermore, it lists only files which were modified from all parents. -c implies -p.
--diff-merges=dense-combined, --diff-merges=cc, --cc With this option the output produced by --diff-merges=combined is further compressed by omitting uninteresting hunks whose contents in the parents have only two variants and the merge result picks one of them without modification. --cc implies -p.
--combined-all-paths This flag causes combined diffs (used for merge commits) to list the name of the file from all parents. It thus only has effect when --diff-merges=[dense-]combined is in use, and is likely only useful if filename changes are detected (i.e. when either rename or copy detection have been requested).
-U<n>, --unified=<n> Generate diffs with <n> lines of context instead of the usual three. Implies --patch.
--output=<file> Output to a specific file instead of stdout.
--output-indicator-new=<char>, --output-indicator-old=<char>, --output-indicator-context=<char> Specify the character used to indicate new, old or context lines in the generated patch. Normally they are +, - and ' ' respectively.
--raw For each commit, show a summary of changes using the raw diff format. See the "RAW OUTPUT FORMAT" section of git‐ diff(1). This is different from showing the log itself in raw format, which you can achieve with --format=raw.
--patch-with-raw Synonym for -p --raw.
-t Show the tree objects in the diff output.
--indent-heuristic Enable the heuristic that shifts diff hunk boundaries to make patches easier to read. This is the default.
--no-indent-heuristic Disable the indent heuristic.
--minimal Spend extra time to make sure the smallest possible diff is produced.
--patience Generate a diff using the "patience diff" algorithm.
--histogram Generate a diff using the "histogram diff" algorithm.
--anchored=<text> Generate a diff using the "anchored diff" algorithm.
This option may be specified more than once.
If a line exists in both the source and destination, exists only once, and starts with this text, this algorithm attempts to prevent it from appearing as a deletion or addition in the output. It uses the "patience diff" algorithm internally.
--diff-algorithm={patience|minimal|histogram|myers} Choose a diff algorithm. The variants are as follows:
default, myers The basic greedy diff algorithm. Currently, this is the default.
minimal Spend extra time to make sure the smallest possible diff is produced.
patience Use "patience diff" algorithm when generating patches.
histogram This algorithm extends the patience algorithm to "support low-occurrence common elements".
For instance, if you configured the diff.algorithm variable to a non-default value and want to use the default one, then you have to use --diff-algorithm=default option.
--stat[=<width>[,<name-width>[,<count>]]] Generate a diffstat. By default, as much space as necessary will be used for the filename part, and the rest for the graph part. Maximum width defaults to terminal width, or 80 columns if not connected to a terminal, and can be overridden by <width>. The width of the filename part can be limited by giving another width <name-width> after a comma. The width of the graph part can be limited by using --stat-graph-width=<width> (affects all commands generating a stat graph) or by setting diff.statGraphWidth=<width> (does not affect git format-patch). By giving a third parameter <count>, you can limit the output to the first <count> lines, followed by ... if there are more.
These parameters can also be set individually with --stat-width=<width>, --stat-name-width=<name-width> and --stat-count=<count>.
--compact-summary Output a condensed summary of extended header information such as file creations or deletions ("new" or "gone", optionally "+l" if it’s a symlink) and mode changes ("+x" or "-x" for adding or removing executable bit respectively) in diffstat. The information is put between the filename part and the graph part. Implies --stat.
--numstat Similar to --stat, but shows number of added and deleted lines in decimal notation and pathname without abbreviation, to make it more machine friendly. For binary files, outputs two - instead of saying 0 0.
--shortstat Output only the last line of the --stat format containing total number of modified files, as well as number of added and deleted lines.
-X[<param1,param2,...>], --dirstat[=<param1,param2,...>] Output the distribution of relative amount of changes for each sub-directory. The behavior of --dirstat can be customized by passing it a comma separated list of parameters. The defaults are controlled by the diff.dirstat configuration variable (see git‐config(1)). The following parameters are available:
changes Compute the dirstat numbers by counting the lines that have been removed from the source, or added to the destination. This ignores the amount of pure code movements within a file. In other words, rearranging lines in a file is not counted as much as other changes. This is the default behavior when no parameter is given.
lines Compute the dirstat numbers by doing the regular line-based diff analysis, and summing the removed/added line counts. (For binary files, count 64-byte chunks instead, since binary files have no natural concept of lines). This is a more expensive --dirstat behavior than the changes behavior, but it does count rearranged lines within a file as much as other changes. The resulting output is consistent with what you get from the other --*stat options.
files Compute the dirstat numbers by counting the number of files changed. Each changed file counts equally in the dirstat analysis. This is the computationally cheapest --dirstat behavior, since it does not have to look at the file contents at all.
cumulative Count changes in a child directory for the parent directory as well. Note that when using cumulative, the sum of the percentages reported may exceed 100%. The default (non-cumulative) behavior can be specified with the noncumulative parameter.
<limit> An integer parameter specifies a cut-off percent (3% by default). Directories contributing less than this percentage of the changes are not shown in the output.
Example: The following will count changed files, while ignoring directories with less than 10% of the total amount of changed files, and accumulating child directory counts in the parent directories: --dirstat=files,10,cumulative.
--cumulative Synonym for --dirstat=cumulative
--dirstat-by-file[=<param1,param2>...] Synonym for --dirstat=files,param1,param2...
--summary Output a condensed summary of extended header information such as creations, renames and mode changes.
--patch-with-stat Synonym for -p --stat.
-z Separate the commits with NULs instead of with new newlines.
Also, when --raw or --numstat has been given, do not munge pathnames and use NULs as output field terminators.
Without this option, pathnames with "unusual" characters are quoted as explained for the configuration variable core.quotePath (see git‐config(1)).
--name-only Show only names of changed files. The file names are often encoded in UTF-8. For more information see the discussion about encoding in the git‐log(1) manual page.
--name-status Show only names and status of changed files. See the description of the --diff-filter option on what the status letters mean. Just like --name-only the file names are often encoded in UTF-8.
--submodule[=<format>] Specify how differences in submodules are shown. When specifying --submodule=short the short format is used. This format just shows the names of the commits at the beginning and end of the range. When --submodule or --submodule=log is specified, the log format is used. This format lists the commits in the range like git‐submodule(1) summary does. When --submodule=diff is specified, the diff format is used. This format shows an inline diff of the changes in the submodule contents between the commit range. Defaults to diff.submodule or the short format if the config option is unset.
--color[=<when>] Show colored diff. --color (i.e. without =<when>) is the same as --color=always. <when> can be one of always, never, or auto.
--no-color Turn off colored diff. It is the same as --color=never.
--color-moved[=<mode>] Moved lines of code are colored differently. The <mode> defaults to no if the option is not given and to zebra if the option with no mode is given. The mode must be one of:
no Moved lines are not highlighted.
default Is a synonym for zebra. This may change to a more sensible mode in the future.
plain Any line that is added in one location and was removed in another location will be colored with color.diff.newMoved. Similarly color.diff.oldMoved will be used for removed lines that are added somewhere else in the diff. This mode picks up any moved line, but it is not very useful in a review to determine if a block of code was moved without permutation.
blocks Blocks of moved text of at least 20 alphanumeric characters are detected greedily. The detected blocks are painted using either the color.diff.{old,new}Moved color. Adjacent blocks cannot be told apart.
zebra Blocks of moved text are detected as in blocks mode. The blocks are painted using either the color.diff.{old,new}Moved color or color.diff.{old,new}MovedAlternative. The change between the two colors indicates that a new block was detected.
dimmed-zebra Similar to zebra, but additional dimming of uninteresting parts of moved code is performed. The bordering lines of two adjacent blocks are considered interesting, the rest is uninteresting. dimmed_zebra is a deprecated synonym.
--no-color-moved Turn off move detection. This can be used to override configuration settings. It is the same as --color-moved=no.
--color-moved-ws=<modes> This configures how whitespace is ignored when performing the move detection for --color-moved. These modes can be given as a comma separated list:
no Do not ignore whitespace when performing move detection.
ignore-space-at-eol Ignore changes in whitespace at EOL.
ignore-space-change Ignore changes in amount of whitespace. This ignores whitespace at line end, and considers all other sequences of one or more whitespace characters to be equivalent.
ignore-all-space Ignore whitespace when comparing lines. This ignores differences even if one line has whitespace where the other line has none.
allow-indentation-change Initially ignore any whitespace in the move detection, then group the moved code blocks only into a block if the change in whitespace is the same per line. This is incompatible with the other modes.
--no-color-moved-ws Do not ignore whitespace when performing move detection. This can be used to override configuration settings. It is the same as --color-moved-ws=no.
--word-diff[=<mode>] Show a word diff, using the <mode> to delimit changed words. By default, words are delimited by whitespace; see --word-diff-regex below. The <mode> defaults to plain, and must be one of:
color Highlight changed words using only colors. Implies --color.
plain Show words as [-removed-] and {+added+}. Makes no attempts to escape the delimiters if they appear in the input, so the output may be ambiguous.
porcelain Use a special line-based format intended for script consumption. Added/removed/unchanged runs are printed in the usual unified diff format, starting with a +/-/‘ ‘ character at the beginning of the line and extending to the end of the line. Newlines in the input are represented by a tilde ~ on a line of its own.
none Disable word diff again.
Note that despite the name of the first mode, color is used to highlight the changed parts in all modes if enabled.
--word-diff-regex=<regex> Use <regex> to decide what a word is, instead of considering runs of non-whitespace to be a word. Also implies --word-diff unless it was already enabled.
Every non-overlapping match of the <regex> is considered a word. Anything between these matches is considered whitespace and ignored(!) for the purposes of finding differences. You may want to append |[^[:space:]] to your regular expression to make sure that it matches all non-whitespace characters. A match that contains a newline is silently truncated(!) at the newline.
For example, --word-diff-regex=. will treat each character as a word and, correspondingly, show differences character by character.
The regex can also be set via a diff driver or configuration option, see gitattributes(5) or git‐ config(1). Giving it explicitly overrides any diff driver or configuration setting. Diff drivers override configuration settings.
--color-words[=<regex>] Equivalent to --word-diff=color plus (if a regex was specified) --word-diff-regex=<regex>.
--no-renames Turn off rename detection, even when the configuration file gives the default to do so.
--[no-]rename-empty Whether to use empty blobs as rename source.
--check Warn if changes introduce conflict markers or whitespace errors. What are considered whitespace errors is controlled by core.whitespace configuration. By default, trailing whitespaces (including lines that consist solely of whitespaces) and a space character that is immediately followed by a tab character inside the initial indent of the line are considered whitespace errors. Exits with non-zero status if problems are found. Not compatible with --exit-code.
--ws-error-highlight=<kind> Highlight whitespace errors in the context, old or new lines of the diff. Multiple values are separated by comma, none resets previous values, default reset the list to new and all is a shorthand for old,new,context. When this option is not given, and the configuration variable diff.wsErrorHighlight is not set, only whitespace errors in new lines are highlighted. The whitespace errors are colored with color.diff.whitespace.
--full-index Instead of the first handful of characters, show the full pre- and post-image blob object names on the "index" line when generating patch format output.
--binary In addition to --full-index, output a binary diff that can be applied with git-apply. Implies --patch.
--abbrev[=<n>] Instead of showing the full 40-byte hexadecimal object name in diff-raw format output and diff-tree header lines, show the shortest prefix that is at least <n> hexdigits long that uniquely refers the object. In diff-patch output format, --full-index takes higher precedence, i.e. if --full-index is specified, full blob names will be shown regardless of --abbrev. Non default number of digits can be specified with --abbrev=<n>.
-B[<n>][/<m>], --break-rewrites[=[<n>][/<m>]] Break complete rewrite changes into pairs of delete and create. This serves two purposes:
It affects the way a change that amounts to a total rewrite of a file not as a series of deletion and insertion mixed together with a very few lines that happen to match textually as the context, but as a single deletion of everything old followed by a single insertion of everything new, and the number m controls this aspect of the -B option (defaults to 60%). -B/70% specifies that less than 30% of the original should remain in the result for Git to consider it a total rewrite (i.e. otherwise the resulting patch will be a series of deletion and insertion mixed together with context lines).
When used with -M, a totally-rewritten file is also considered as the source of a rename (usually -M only considers a file that disappeared as the source of a rename), and the number n controls this aspect of the -B option (defaults to 50%). -B20% specifies that a change with addition and deletion compared to 20% or more of the file’s size are eligible for being picked up as a possible source of a rename to another file.
-M[<n>], --find-renames[=<n>] If generating diffs, detect and report renames for each commit. For following files across renames while traversing history, see --follow. If n is specified, it is a threshold on the similarity index (i.e. amount of addition/deletions compared to the file’s size). For example, -M90% means Git should consider a delete/add pair to be a rename if more than 90% of the file hasn’t changed. Without a % sign, the number is to be read as a fraction, with a decimal point before it. I.e., -M5 becomes 0.5, and is thus the same as -M50%. Similarly, -M05 is the same as -M5%. To limit detection to exact renames, use -M100%. The default similarity index is 50%.
-C[<n>], --find-copies[=<n>] Detect copies as well as renames. See also --find-copies-harder. If n is specified, it has the same meaning as for -M<n>.
--find-copies-harder For performance reasons, by default, -C option finds copies only if the original file of the copy was modified in the same changeset. This flag makes the command inspect unmodified files as candidates for the source of copy. This is a very expensive operation for large projects, so use it with caution. Giving more than one -C option has the same effect.
-D, --irreversible-delete Omit the preimage for deletes, i.e. print only the header but not the diff between the preimage and /dev/null. The resulting patch is not meant to be applied with patch or git apply; this is solely for people who want to just concentrate on reviewing the text after the change. In addition, the output obviously lacks enough information to apply such a patch in reverse, even manually, hence the name of the option.
When used together with -B, omit also the preimage in the deletion part of a delete/create pair.
-l<num> The -M and -C options involve some preliminary steps that can detect subsets of renames/copies cheaply, followed by an exhaustive fallback portion that compares all remaining unpaired destinations to all relevant sources. (For renames, only remaining unpaired sources are relevant; for copies, all original sources are relevant.) For N sources and destinations, this exhaustive check is O(N^2). This option prevents the exhaustive portion of rename/copy detection from running if the number of source/destination files involved exceeds the specified number. Defaults to diff.renameLimit. Note that a value of 0 is treated as unlimited.
--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]] Select only files that are Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type (i.e. regular file, symlink, submodule, ...) changed (T), are Unmerged (U), are Unknown (X), or have had their pairing Broken (B). Any combination of the filter characters (including none) can be used. When * (All-or-none) is added to the combination, all paths are selected if there is any file that matches other criteria in the comparison; if there is no file that matches other criteria, nothing is selected.
Also, these upper-case letters can be downcased to exclude. E.g. --diff-filter=ad excludes added and deleted paths.
Note that not all diffs can feature all types. For instance, copied and renamed entries cannot appear if detection for those types is disabled.
-S<string> Look for differences that change the number of occurrences of the specified string (i.e. addition/deletion) in a file. Intended for the scripter’s use.
It is useful when you’re looking for an exact block of code (like a struct), and want to know the history of that block since it first came into being: use the feature iteratively to feed the interesting block in the preimage back into -S, and keep going until you get the very first version of the block.
Binary files are searched as well.
-G<regex> Look for differences whose patch text contains added/removed lines that match <regex>.
To illustrate the difference between -S<regex> --pickaxe-regex and -G<regex>, consider a commit with the following diff in the same file:
+ return frotz(nitfol, two->ptr, 1, 0); ... - hit = frotz(nitfol, mf2.ptr, 1, 0);
While git log -G"frotz\(nitfol" will show this commit, git log -S"frotz\(nitfol" --pickaxe-regex will not (because the number of occurrences of that string did not change).
Unless --text is supplied patches of binary files without a textconv filter will be ignored.
See the pickaxe entry in gitdiffcore(7) for more information.
--find-object=<object-id> Look for differences that change the number of occurrences of the specified object. Similar to -S, just the argument is different in that it doesn’t search for a specific string but for a specific object id.
The object can be a blob or a submodule commit. It implies the -t option in git-log to also find trees.
--pickaxe-all When -S or -G finds a change, show all the changes in that changeset, not just the files that contain the change in <string>.
--pickaxe-regex Treat the <string> given to -S as an extended POSIX regular expression to match.
-O<orderfile> Control the order in which files appear in the output. This overrides the diff.orderFile configuration variable (see git‐config(1)). To cancel diff.orderFile, use -O/dev/null.
The output order is determined by the order of glob patterns in <orderfile>. All files with pathnames that match the first pattern are output first, all files with pathnames that match the second pattern (but not the first) are output next, and so on. All files with pathnames that do not match any pattern are output last, as if there was an implicit match-all pattern at the end of the file. If multiple pathnames have the same rank (they match the same pattern but no earlier patterns), their output order relative to each other is the normal order.
<orderfile> is parsed as follows:
• Blank lines are ignored, so they can be used as separators for readability.
• Lines starting with a hash ("#") are ignored, so they can be used for comments. Add a backslash ("\") to the beginning of the pattern if it starts with a hash.
• Each other line contains a single pattern.
Patterns have the same syntax and semantics as patterns used for fnmatch(3) without the FNM_PATHNAME flag, except a pathname also matches a pattern if removing any number of the final pathname components matches the pattern. For example, the pattern "foo*bar" matches "fooasdfbar" and "foo/bar/baz/asdf" but not "foobarx".
--skip-to=<file>, --rotate-to=<file> Discard the files before the named <file> from the output (i.e. skip to), or move them to the end of the output (i.e. rotate to). These were invented primarily for use of the git difftool command, and may not be very useful otherwise.
-R Swap two inputs; that is, show differences from index or on-disk file to tree contents.
--relative[=<path>], --no-relative When run from a subdirectory of the project, it can be told to exclude changes outside the directory and show pathnames relative to it with this option. When you are not in a subdirectory (e.g. in a bare repository), you can name which subdirectory to make the output relative to by giving a <path> as an argument. --no-relative can be used to countermand both diff.relative config option and previous --relative.
-a, --text Treat all files as text.
--ignore-cr-at-eol Ignore carriage-return at the end of line when doing a comparison.
--ignore-space-at-eol Ignore changes in whitespace at EOL.
-b, --ignore-space-change Ignore changes in amount of whitespace. This ignores whitespace at line end, and considers all other sequences of one or more whitespace characters to be equivalent.
-w, --ignore-all-space Ignore whitespace when comparing lines. This ignores differences even if one line has whitespace where the other line has none.
--ignore-blank-lines Ignore changes whose lines are all blank.
-I<regex>, --ignore-matching-lines=<regex> Ignore changes whose all lines match <regex>. This option may be specified more than once.
--inter-hunk-context=<lines> Show the context between diff hunks, up to the specified number of lines, thereby fusing hunks that are close to each other. Defaults to diff.interHunkContext or 0 if the config option is unset.
-W, --function-context Show whole function as context lines for each change. The function names are determined in the same way as git diff works out patch hunk headers (see Defining a custom hunk-header in gitattributes(5)).
--ext-diff Allow an external diff helper to be executed. If you set an external diff driver with gitattributes(5), you need to use this option with git‐log(1) and friends.
--no-ext-diff Disallow external diff drivers.
--textconv, --no-textconv Allow (or disallow) external text conversion filters to be run when comparing binary files. See gitattributes(5) for details. Because textconv filters are typically a one-way conversion, the resulting diff is suitable for human consumption, but cannot be applied. For this reason, textconv filters are enabled by default only for git‐ diff(1) and git‐log(1), but not for git‐format‐patch(1) or diff plumbing commands.
--ignore-submodules[=<when>] Ignore changes to submodules in the diff generation. <when> can be either "none", "untracked", "dirty" or "all", which is the default. Using "none" will consider the submodule modified when it either contains untracked or modified files or its HEAD differs from the commit recorded in the superproject and can be used to override any settings of the ignore option in git‐config(1) or gitmodules(5). When "untracked" is used submodules are not considered dirty when they only contain untracked content (but they are still scanned for modified content). Using "dirty" ignores all changes to the work tree of submodules, only changes to the commits stored in the superproject are shown (this was the behavior until 1.7.0). Using "all" hides all changes to submodules.
--src-prefix=<prefix> Show the given source prefix instead of "a/".
--dst-prefix=<prefix> Show the given destination prefix instead of "b/".
--no-prefix Do not show any source or destination prefix.
--line-prefix=<prefix> Prepend an additional prefix to every line of output.
--ita-invisible-in-index By default entries added by "git add -N" appear as an existing empty file in "git diff" and a new file in "git diff --cached". This option makes the entry appear as a new file in "git diff" and non-existent in "git diff --cached". This option could be reverted with --ita-visible-in-index. Both options are experimental and could be removed in future.
For more detailed explanation on these common options, see also gitdiffcore(7).
GENERATING PATCH TEXT WITH -P Running git‐diff(1), git‐log(1), git‐show(1), git‐diff‐ index(1), git‐diff‐tree(1), or git‐diff‐files(1) with the -p option produces patch text. You can customize the creation of patch text via the GIT_EXTERNAL_DIFF and the GIT_DIFF_OPTS environment variables (see git(1)), and the diff attribute (see gitattributes(5)).
What the -p option produces is slightly different from the traditional diff format:
1. It is preceded with a "git diff" header that looks like this:
diff --git a/file1 b/file2
The a/ and b/ filenames are the same unless rename/copy is involved. Especially, even for a creation or a deletion, /dev/null is not used in place of the a/ or b/ filenames.
When rename/copy is involved, file1 and file2 show the name of the source file of the rename/copy and the name of the file that rename/copy produces, respectively.
2. It is followed by one or more extended header lines:
old mode <mode> new mode <mode> deleted file mode <mode> new file mode <mode> copy from <path> copy to <path> rename from <path> rename to <path> similarity index <number> dissimilarity index <number> index <hash>..<hash> <mode>
File modes are printed as 6-digit octal numbers including the file type and file permission bits.
Path names in extended headers do not include the a/ and b/ prefixes.
The similarity index is the percentage of unchanged lines, and the dissimilarity index is the percentage of changed lines. It is a rounded down integer, followed by a percent sign. The similarity index value of 100% is thus reserved for two equal files, while 100% dissimilarity means that no line from the old file made it into the new one.
The index line includes the blob object names before and after the change. The <mode> is included if the file mode does not change; otherwise, separate lines indicate the old and the new mode.
3. Pathnames with "unusual" characters are quoted as explained for the configuration variable core.quotePath (see git‐ config(1)).
4. All the file1 files in the output refer to files before the commit, and all the file2 files refer to files after the commit. It is incorrect to apply each change to each file sequentially. For example, this patch will swap a and b:
diff --git a/a b/b rename from a rename to b diff --git a/b b/a rename from b rename to a
5. Hunk headers mention the name of the function to which the hunk applies. See "Defining a custom hunk-header" in gitattributes(5) for details of how to tailor to this to specific languages.
COMBINED DIFF FORMAT Any diff-generating command can take the -c or --cc option to produce a combined diff when showing a merge. This is the default format when showing merges with git‐diff(1) or git‐ show(1). Note also that you can give suitable --diff-merges option to any of these commands to force generation of diffs in specific format.
A "combined diff" format looks like this:
diff --combined describe.c index fabadb8,cc95eb0..4866510 --- a/describe.c +++ b/describe.c @@@ -98,20 -98,12 +98,20 @@@ return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1; }
- static void describe(char *arg) -static void describe(struct commit *cmit, int last_one) ++static void describe(char *arg, int last_one) { + unsigned char sha1[20]; + struct commit *cmit; struct commit_list *list; static int initialized = 0; struct commit_name *n;
+ if (get_sha1(arg, sha1) < 0) + usage(describe_usage); + cmit = lookup_commit_reference(sha1); + if (!cmit) + usage(describe_usage); + if (!initialized) { initialized = 1; for_each_ref(get_name);
1. It is preceded with a "git diff" header, that looks like this (when the -c option is used):
diff --combined file
or like this (when the --cc option is used):
diff --cc file
2. It is followed by one or more extended header lines (this example shows a merge with two parents):
index <hash>,<hash>..<hash> mode <mode>,<mode>..<mode> new file mode <mode> deleted file mode <mode>,<mode>
The mode <mode>,<mode>..<mode> line appears only if at least one of the <mode> is different from the rest. Extended headers with information about detected contents movement (renames and copying detection) are designed to work with diff of two <tree-ish> and are not used by combined diff format.
3. It is followed by two-line from-file/to-file header
--- a/file +++ b/file
Similar to two-line header for traditional unified diff format, /dev/null is used to signal created or deleted files.
However, if the --combined-all-paths option is provided, instead of a two-line from-file/to-file you get a N+1 line from-file/to-file header, where N is the number of parents in the merge commit
--- a/file --- a/file --- a/file +++ b/file
This extended format can be useful if rename or copy detection is active, to allow you to see the original name of the file in different parents.
4. Chunk header format is modified to prevent people from accidentally feeding it to patch -p1. Combined diff format was created for review of merge commit changes, and was not meant to be applied. The change is similar to the change in the extended index header:
@@@ <from-file-range> <from-file-range> <to-file-range> @@@
There are (number of parents + 1) @ characters in the chunk header for combined diff format.
Unlike the traditional unified diff format, which shows two files A and B with a single column that has - (minus — appears in A but removed in B), + (plus — missing in A but added to B), or " " (space — unchanged) prefix, this format compares two or more files file1, file2,... with one file X, and shows how X differs from each of fileN. One column for each of fileN is prepended to the output line to note how X’s line is different from it.
A - character in the column N means that the line appears in fileN but it does not appear in the result. A + character in the column N means that the line appears in the result, and fileN does not have that line (in other words, the line was added, from the point of view of that parent).
In the above example output, the function signature was changed from both files (hence two - removals from both file1 and file2, plus ++ to mean one line that was added does not appear in either file1 or file2). Also eight other lines are the same from file1 but do not appear in file2 (hence prefixed with +).
When shown by git diff-tree -c, it compares the parents of a merge commit with the merge result (i.e. file1..fileN are the parents). When shown by git diff-files -c, it compares the two unresolved merge parents with the working tree file (i.e. file1 is stage 2 aka "our version", file2 is stage 3 aka "their version").
EXAMPLES git show v1.0.0 Shows the tag v1.0.0, along with the object the tags points at.
git show v1.0.0^{tree} Shows the tree pointed to by the tag v1.0.0.
git show -s --format=%s v1.0.0^{commit} Shows the subject of the commit pointed to by the tag v1.0.0.
git show next~10:Documentation/README Shows the contents of the file Documentation/README as they were current in the 10th last commit of the branch next.
git show master:Makefile master:t/Makefile Concatenates the contents of said Makefiles in the head of the branch master.
DISCUSSION Git is to some extent character encoding agnostic.
• The contents of the blob objects are uninterpreted sequences of bytes. There is no encoding translation at the core level.
• Path names are encoded in UTF-8 normalization form C. This applies to tree objects, the index file, ref names, as well as path names in command line arguments, environment variables and config files (.git/config (see git‐ config(1)), gitignore(5), gitattributes(5) and gitmodules(5)).
Note that Git at the core level treats path names simply as sequences of non-NUL bytes, there are no path name encoding conversions (except on Mac and Windows). Therefore, using non-ASCII path names will mostly work even on platforms and file systems that use legacy extended ASCII encodings. However, repositories created on such systems will not work properly on UTF-8-based systems (e.g. Linux, Mac, Windows) and vice versa. Additionally, many Git-based tools simply assume path names to be UTF-8 and will fail to display other encodings correctly.
• Commit log messages are typically encoded in UTF-8, but other extended ASCII encodings are also supported. This includes ISO-8859-x, CP125x and many others, but not UTF-16/32, EBCDIC and CJK multi-byte encodings (GBK, Shift-JIS, Big5, EUC-x, CP9xx etc.).
Although we encourage that the commit log messages are encoded in UTF-8, both the core and Git Porcelain are designed not to force UTF-8 on projects. If all participants of a particular project find it more convenient to use legacy encodings, Git does not forbid it. However, there are a few things to keep in mind.
1. git commit and git commit-tree issues a warning if the commit log message given to it does not look like a valid UTF-8 string, unless you explicitly say your project uses a legacy encoding. The way to say this is to have i18n.commitEncoding in .git/config file, like this:
[i18n] commitEncoding = ISO-8859-1
Commit objects created with the above setting record the value of i18n.commitEncoding in its encoding header. This is to help other people who look at them later. Lack of this header implies that the commit log message is encoded in UTF-8.
2. git log, git show, git blame and friends look at the encoding header of a commit object, and try to re-code the log message into UTF-8 unless otherwise specified. You can specify the desired output encoding with i18n.logOutputEncoding in .git/config file, like this:
[i18n] logOutputEncoding = ISO-8859-1
If you do not have this configuration variable, the value of i18n.commitEncoding is used instead.
Note that we deliberately chose not to re-code the commit log message when a commit is made to force UTF-8 at the commit object level, because re-coding to UTF-8 is not necessarily a reversible operation.
GIT Part of the git(1) suite
Git 2.40.1 05/18/2023 GIT-SHOW(1)

Git-Show-Ref

This is the help message for git-show-ref:

Shell
$ man git-show-ref
GIT-SHOW-REF(1)               Git Manual               GIT-SHOW-REF(1)
NAME git‐show‐ref - List references in a local repository
SYNOPSIS git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference] [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [<pattern>...] git show-ref --exclude-existing[=<pattern>]
DESCRIPTION Displays references available in a local repository along with the associated commit IDs. Results can be filtered using a pattern and tags can be dereferenced into object IDs. Additionally, it can be used to test whether a particular ref exists.
By default, shows the tags, heads, and remote refs.
The --exclude-existing form is a filter that does the inverse. It reads refs from stdin, one ref per line, and shows those that don’t exist in the local repository.
Use of this utility is encouraged in favor of directly accessing files under the .git directory.
OPTIONS --head Show the HEAD reference, even if it would normally be filtered out.
--heads, --tags Limit to "refs/heads" and "refs/tags", respectively. These options are not mutually exclusive; when given both, references stored in "refs/heads" and "refs/tags" are displayed.
-d, --dereference Dereference tags into object IDs as well. They will be shown with "^{}" appended.
-s, --hash[=<n>] Only show the SHA-1 hash, not the reference name. When combined with --dereference the dereferenced tag will still be shown after the SHA-1.
--verify Enable stricter reference checking by requiring an exact ref path. Aside from returning an error code of 1, it will also print an error message if --quiet was not specified.
--abbrev[=<n>] Abbreviate the object name. When using --hash, you do not have to say --hash --abbrev; --hash=n would do.
-q, --quiet Do not print any results to stdout. When combined with --verify this can be used to silently check if a reference exists.
--exclude-existing[=<pattern>] Make git show-ref act as a filter that reads refs from stdin of the form "^(?:<anything>\s)?<refname>(?:\^{})?$" and performs the following actions on each: (1) strip "^{}" at the end of line if any; (2) ignore if pattern is provided and does not head-match refname; (3) warn if refname is not a well-formed refname and skip; (4) ignore if refname is a ref that exists in the local repository; (5) otherwise output the line.
<pattern>... Show references matching one or more patterns. Patterns are matched from the end of the full name, and only complete parts are matched, e.g. master matches refs/heads/master, refs/remotes/origin/master, refs/tags/jedi/master but not refs/heads/mymaster or refs/remotes/master/jedi.
OUTPUT The output is in the format: <SHA-1 ID> <space> <reference name>.
$ git show-ref --head --dereference 832e76a9899f560a90ffd62ae2ce83bbeff58f54 HEAD 832e76a9899f560a90ffd62ae2ce83bbeff58f54 refs/heads/master 832e76a9899f560a90ffd62ae2ce83bbeff58f54 refs/heads/origin 3521017556c5de4159da4615a39fa4d5d2c279b5 refs/tags/v0.99.9c 6ddc0964034342519a87fe013781abf31c6db6ad refs/tags/v0.99.9c^{} 055e4ae3ae6eb344cbabf2a5256a49ea66040131 refs/tags/v1.0rc4 423325a2d24638ddcc82ce47be5e40be550f4507 refs/tags/v1.0rc4^{} ...
When using --hash (and not --dereference) the output format is: <SHA-1 ID>
$ git show-ref --heads --hash 2e3ba0114a1f52b47df29743d6915d056be13278 185008ae97960c8d551adcd9e23565194651b5d1 03adf42c988195b50e1a1935ba5fcbc39b2b029b ...
EXAMPLES To show all references called "master", whether tags or heads or anything else, and regardless of how deep in the reference naming hierarchy they are, use:
git show-ref master
This will show "refs/heads/master" but also "refs/remote/other-repo/master", if such references exists.
When using the --verify flag, the command requires an exact path:
git show-ref --verify refs/heads/master
will only match the exact branch called "master".
If nothing matches, git show-ref will return an error code of 1, and in the case of verification, it will show an error message.
For scripting, you can ask it to be quiet with the "--quiet" flag, which allows you to do things like
git show-ref --quiet --verify -- "refs/heads/$headname" || echo "$headname is not a valid branch"
to check whether a particular branch exists or not (notice how we don’t actually want to show any results, and we want to use the full refname for it in order to not trigger the problem with ambiguous partial matches).
To show only tags, or only proper branch heads, use "--tags" and/or "--heads" respectively (using both means that it shows tags and heads, but not other random references under the refs/ subdirectory).
To do automatic tag object dereferencing, use the "-d" or "--dereference" flag, so you can do
git show-ref --tags --dereference
to get a listing of all tags together with what they dereference.
FILES .git/refs/*, .git/packed-refs
SEE ALSO git‐for‐each‐ref(1), git‐ls‐remote(1), git‐update‐ref(1), gitrepository‐layout(5)
GIT Part of the git(1) suite
Git 2.40.1 05/18/2023 GIT-SHOW-REF(1)

View all refs that are a HEAD in a repo:

Shell
$ git show-ref --abbrev=8 --head
d9eaf137 HEAD
d9eaf137 refs/heads/master
d9eaf137 refs/remotes/origin/HEAD
d9eaf137 refs/remotes/origin/master
e57fd0ba refs/stash
c05d0d37 refs/tags/1 

Show all references called master, including tags, heads and any other refs, including remote refs:

Shell
$ git show-ref --abbrev=8 --head master
d9eaf137 HEAD
d9eaf137 refs/heads/master
d9eaf137 refs/remotes/origin/master 

Show the SHA for HEAD:

Shell
$ git show-ref -s --head HEAD
d9eaf1372978872c232c2875c7376f4e9e2dbd7f
d9eaf1372978872c232c2875c7376f4e9e2dbd7f 

Git-Symbolic-Ref

The help message is:

git help symbolic-ref
GIT-SYMBOLIC-REF(1)           Git Manual           GIT-SYMBOLIC-REF(1)
NAME git‐symbolic‐ref - Read, modify and delete symbolic refs
SYNOPSIS git symbolic-ref [-m <reason>] <name> <ref> git symbolic-ref [-q] [--short] [--no-recurse] <name> git symbolic-ref --delete [-q] <name>
DESCRIPTION Given one argument, reads which branch head the given symbolic ref refers to and outputs its path, relative to the .git/ directory. Typically you would give HEAD as the <name> argument to see which branch your working tree is on.
Given two arguments, creates or updates a symbolic ref <name> to point at the given branch <ref>.
Given --delete and an additional argument, deletes the given symbolic ref.
A symbolic ref is a regular file that stores a string that begins with ref: refs/. For example, your .git/HEAD is a regular file whose contents is ref: refs/heads/master.
OPTIONS -d, --delete Delete the symbolic ref <name>.
-q, --quiet Do not issue an error message if the <name> is not a symbolic ref but a detached HEAD; instead exit with non-zero status silently.
--short When showing the value of <name> as a symbolic ref, try to shorten the value, e.g. from refs/heads/master to master.
--recurse, --no-recurse When showing the value of <name> as a symbolic ref, if <name> refers to another symbolic ref, follow such a chain of symbolic refs until the result no longer points at a symbolic ref (--recurse, which is the default). --no-recurse stops after dereferencing only a single level of symbolic ref.
-m Update the reflog for <name> with <reason>. This is valid only when creating or updating a symbolic ref.
NOTES In the past, .git/HEAD was a symbolic link pointing at refs/heads/master. When we wanted to switch to another branch, we did ln -sf refs/heads/newbranch .git/HEAD, and when we wanted to find out which branch we are on, we did readlink .git/HEAD. But symbolic links are not entirely portable, so they are now deprecated and symbolic refs (as described above) are used by default.
git symbolic-ref will exit with status 0 if the contents of the symbolic ref were printed correctly, with status 1 if the requested name is not a symbolic ref, or 128 if another error occurs.
GIT Part of the git(1) suite
Git 2.40.1 05/18/2023 GIT-SYMBOLIC-REF(1)

Obtain the value of your HEAD:

Shell
$ git symbolic-ref HEAD
refs/heads/master 

Set the value of HEAD to the test branch. (This is what git branch test does).

Shell
$ git symbolic-ref HEAD refs/heads/test
$ cat .git/HEAD ref: refs/heads/test

Git-Update-Index

This is the help message:

Shell
$ git help update-index
GIT-UPDATE-INDEX(1)           Git Manual           GIT-UPDATE-INDEX(1)
NAME git‐update‐index - Register file contents in the working tree to the index
SYNOPSIS git update-index [--add] [--remove | --force-remove] [--replace] [--refresh] [-q] [--unmerged] [--ignore-missing] [(--cacheinfo <mode>,<object>,<file>)...] [--chmod=(+|-)x] [--[no-]assume-unchanged] [--[no-]skip-worktree] [--[no-]ignore-skip-worktree-entries] [--[no-]fsmonitor-valid] [--ignore-submodules] [--[no-]split-index] [--[no-|test-|force-]untracked-cache] [--[no-]fsmonitor] [--really-refresh] [--unresolve] [--again | -g] [--info-only] [--index-info] [-z] [--stdin] [--index-version <n>] [--verbose] [--] [<file>...]
DESCRIPTION Modifies the index. Each file mentioned is updated into the index and any unmerged or needs updating state is cleared.
See also git‐add(1) for a more user-friendly way to do some of the most common operations on the index.
The way git update-index handles files it is told about can be modified using the various options:
OPTIONS --add If a specified file isn’t in the index already then it’s added. Default behaviour is to ignore new files.
--remove If a specified file is in the index but is missing then it’s removed. Default behavior is to ignore removed file.
--refresh Looks at the current index and checks to see if merges or updates are needed by checking stat() information.
-q Quiet. If --refresh finds that the index needs an update, the default behavior is to error out. This option makes git update-index continue anyway.
--ignore-submodules Do not try to update submodules. This option is only respected when passed before --refresh.
--unmerged If --refresh finds unmerged changes in the index, the default behavior is to error out. This option makes git update-index continue anyway.
--ignore-missing Ignores missing files during a --refresh
--cacheinfo <mode>,<object>,<path>, --cacheinfo <mode> <object> <path> Directly insert the specified info into the index. For backward compatibility, you can also give these three arguments as three separate parameters, but new users are encouraged to use a single-parameter form.
--index-info Read index information from stdin.
--chmod=(+|-)x Set the execute permissions on the updated files.
--[no-]assume-unchanged When this flag is specified, the object names recorded for the paths are not updated. Instead, this option sets/unsets the "assume unchanged" bit for the paths. When the "assume unchanged" bit is on, the user promises not to change the file and allows Git to assume that the working tree file matches what is recorded in the index. If you want to change the working tree file, you need to unset the bit to tell Git. This is sometimes helpful when working with a big project on a filesystem that has very slow lstat(2) system call (e.g. cifs).
Git will fail (gracefully) in case it needs to modify this file in the index e.g. when merging in a commit; thus, in case the assumed-untracked file is changed upstream, you will need to handle the situation manually.
--really-refresh Like --refresh, but checks stat information unconditionally, without regard to the "assume unchanged" setting.
--[no-]skip-worktree When one of these flags is specified, the object name recorded for the paths are not updated. Instead, these options set and unset the "skip-worktree" bit for the paths. See section "Skip-worktree bit" below for more information.
--[no-]ignore-skip-worktree-entries Do not remove skip-worktree (AKA "index-only") entries even when the --remove option was specified.
--[no-]fsmonitor-valid When one of these flags is specified, the object name recorded for the paths are not updated. Instead, these options set and unset the "fsmonitor valid" bit for the paths. See section "File System Monitor" below for more information.
-g, --again Runs git update-index itself on the paths whose index entries are different from those from the HEAD commit.
--unresolve Restores the unmerged or needs updating state of a file during a merge if it was cleared by accident.
--info-only Do not create objects in the object database for all <file> arguments that follow this flag; just insert their object IDs into the index.
--force-remove Remove the file from the index even when the working directory still has such a file. (Implies --remove.)
--replace By default, when a file path exists in the index, git update-index refuses an attempt to add path/file. Similarly if a file path/file exists, a file path cannot be added. With --replace flag, existing entries that conflict with the entry being added are automatically removed with warning messages.
--stdin Instead of taking list of paths from the command line, read list of paths from the standard input. Paths are separated by LF (i.e. one path per line) by default.
--verbose Report what is being added and removed from index.
--index-version <n> Write the resulting index out in the named on-disk format version. Supported versions are 2, 3 and 4. The current default version is 2 or 3, depending on whether extra features are used, such as git add -N.
Version 4 performs a simple pathname compression that reduces index size by 30%-50% on large repositories, which results in faster load time. Version 4 is relatively young (first released in 1.8.0 in October 2012). Other Git implementations such as JGit and libgit2 may not support it yet.
-z Only meaningful with --stdin or --index-info; paths are separated with NUL character instead of LF.
--split-index, --no-split-index Enable or disable split index mode. If split-index mode is already enabled and --split-index is given again, all changes in $GIT_DIR/index are pushed back to the shared index file.
These options take effect whatever the value of the core.splitIndex configuration variable (see git‐config(1)). But a warning is emitted when the change goes against the configured value, as the configured value will take effect next time the index is read and this will remove the intended effect of the option.
--untracked-cache, --no-untracked-cache Enable or disable untracked cache feature. Please use --test-untracked-cache before enabling it.
These options take effect whatever the value of the core.untrackedCache configuration variable (see git‐ config(1)). But a warning is emitted when the change goes against the configured value, as the configured value will take effect next time the index is read and this will remove the intended effect of the option.
--test-untracked-cache Only perform tests on the working directory to make sure untracked cache can be used. You have to manually enable untracked cache using --untracked-cache or --force-untracked-cache or the core.untrackedCache configuration variable afterwards if you really want to use it. If a test fails the exit code is 1 and a message explains what is not working as needed, otherwise the exit code is 0 and OK is printed.
--force-untracked-cache Same as --untracked-cache. Provided for backwards compatibility with older versions of Git where --untracked-cache used to imply --test-untracked-cache but this option would enable the extension unconditionally.
--fsmonitor, --no-fsmonitor Enable or disable files system monitor feature. These options take effect whatever the value of the core.fsmonitor configuration variable (see git‐config(1)). But a warning is emitted when the change goes against the configured value, as the configured value will take effect next time the index is read and this will remove the intended effect of the option.
-- Do not interpret any more arguments as options.
<file> Files to act on. Note that files beginning with . are discarded. This includes ./file and dir/./file. If you don’t want this, then use cleaner names. The same applies to directories ending / and paths with //
USING --REFRESH --refresh does not calculate a new sha1 file or bring the index up to date for mode/content changes. But what it does do is to "re-match" the stat information of a file with the index, so that you can refresh the index for a file that hasn’t been changed but where the stat entry is out of date.
For example, you’d want to do this after doing a git read-tree, to link up the stat index details with the proper files.
USING --CACHEINFO OR --INFO-ONLY --cacheinfo is used to register a file that is not in the current working directory. This is useful for minimum-checkout merging.
To pretend you have a file at path with mode and sha1, say:
$ git update-index --add --cacheinfo <mode>,<sha1>,<path>
--info-only is used to register files without placing them in the object database. This is useful for status-only repositories.
Both --cacheinfo and --info-only behave similarly: the index is updated but the object database isn’t. --cacheinfo is useful when the object is in the database but the file isn’t available locally. --info-only is useful when the file is available, but you do not wish to update the object database.
USING --INDEX-INFO --index-info is a more powerful mechanism that lets you feed multiple entry definitions from the standard input, and designed specifically for scripts. It can take inputs of three formats:
1. mode SP type SP sha1 TAB path
This format is to stuff git ls-tree output into the index.
2. mode SP sha1 SP stage TAB path
This format is to put higher order stages into the index file and matches git ls-files --stage output.
3. mode SP sha1 TAB path
This format is no longer produced by any Git command, but is and will continue to be supported by update-index --index-info.
To place a higher stage entry to the index, the path should first be removed by feeding a mode=0 entry for the path, and then feeding necessary input lines in the third format.
For example, starting with this index:
$ git ls-files -s 100644 8a1218a1024a212bb3db30becd860315f9f3ac52 0 frotz
you can feed the following input to --index-info:
$ git update-index --index-info 0 0000000000000000000000000000000000000000 frotz 100644 8a1218a1024a212bb3db30becd860315f9f3ac52 1 frotz 100755 8a1218a1024a212bb3db30becd860315f9f3ac52 2 frotz
The first line of the input feeds 0 as the mode to remove the path; the SHA-1 does not matter as long as it is well formatted. Then the second and third line feeds stage 1 and stage 2 entries for that path. After the above, we would end up with this:
$ git ls-files -s 100644 8a1218a1024a212bb3db30becd860315f9f3ac52 1 frotz 100755 8a1218a1024a212bb3db30becd860315f9f3ac52 2 frotz
USING “ASSUME UNCHANGED” BIT Many operations in Git depend on your filesystem to have an efficient lstat(2) implementation, so that st_mtime information for working tree files can be cheaply checked to see if the file contents have changed from the version recorded in the index file. Unfortunately, some filesystems have inefficient lstat(2). If your filesystem is one of them, you can set "assume unchanged" bit to paths you have not changed to cause Git not to do this check. Note that setting this bit on a path does not mean Git will check the contents of the file to see if it has changed — it makes Git to omit any checking and assume it has not changed. When you make changes to working tree files, you have to explicitly tell Git about it by dropping "assume unchanged" bit, either before or after you modify them.
In order to set "assume unchanged" bit, use --assume-unchanged option. To unset, use --no-assume-unchanged. To see which files have the "assume unchanged" bit set, use git ls-files -v (see git‐ls‐files(1)).
The command looks at core.ignorestat configuration variable. When this is true, paths updated with git update-index paths... and paths updated with other Git commands that update both index and working tree (e.g. git apply --index, git checkout-index -u, and git read-tree -u) are automatically marked as "assume unchanged". Note that "assume unchanged" bit is not set if git update-index --refresh finds the working tree file matches the index (use git update-index --really-refresh if you want to mark them as "assume unchanged").
Sometimes users confuse the assume-unchanged bit with the skip-worktree bit. See the final paragraph in the "Skip-worktree bit" section below for an explanation of the differences.
EXAMPLES To update and refresh only the files already checked out:
$ git checkout-index -n -f -a && git update-index --ignore-missing --refresh
On an inefficient filesystem with core.ignorestat set
$ git update-index --really-refresh (1) $ git update-index --no-assume-unchanged foo.c (2) $ git diff --name-only (3) $ edit foo.c $ git diff --name-only (4) M foo.c $ git update-index foo.c (5) $ git diff --name-only (6) $ edit foo.c $ git diff --name-only (7) $ git update-index --no-assume-unchanged foo.c (8) $ git diff --name-only (9) M foo.c
1. forces lstat(2) to set "assume unchanged" bits for paths that match index. 2. mark the path to be edited. 3. this does lstat(2) and finds index matches the path. 4. this does lstat(2) and finds index does not match the path. 5. registering the new version to index sets "assume unchanged" bit. 6. and it is assumed unchanged. 7. even after you edit it. 8. you can tell about the change after the fact. 9. now it checks with lstat(2) and finds it has been changed.
SKIP-WORKTREE BIT Skip-worktree bit can be defined in one (long) sentence: Tell git to avoid writing the file to the working directory when reasonably possible, and treat the file as unchanged when it is not present in the working directory.
Note that not all git commands will pay attention to this bit, and some only partially support it.
The update-index flags and the read-tree capabilities relating to the skip-worktree bit predated the introduction of the git‐ sparse‐checkout(1) command, which provides a much easier way to configure and handle the skip-worktree bits. If you want to reduce your working tree to only deal with a subset of the files in the repository, we strongly encourage the use of git‐ sparse‐checkout(1) in preference to the low-level update-index and read-tree primitives.
The primary purpose of the skip-worktree bit is to enable sparse checkouts, i.e. to have working directories with only a subset of paths present. When the skip-worktree bit is set, Git commands (such as switch, pull, merge) will avoid writing these files. However, these commands will sometimes write these files anyway in important cases such as conflicts during a merge or rebase. Git commands will also avoid treating the lack of such files as an intentional deletion; for example git add -u will not stage a deletion for these files and git commit -a will not make a commit deleting them either.
Although this bit looks similar to assume-unchanged bit, its goal is different. The assume-unchanged bit is for leaving the file in the working tree but having Git omit checking it for changes and presuming that the file has not been changed (though if it can determine without stat’ing the file that it has changed, it is free to record the changes). skip-worktree tells Git to ignore the absence of the file, avoid updating it when possible with commands that normally update much of the working directory (e.g. checkout, switch, pull, etc.), and not have its absence be recorded in commits. Note that in sparse checkouts (setup by git sparse-checkout or by configuring core.sparseCheckout to true), if a file is marked as skip-worktree in the index but is found in the working tree, Git will clear the skip-worktree bit for that file.
SPLIT INDEX This mode is designed for repositories with very large indexes, and aims at reducing the time it takes to repeatedly write these indexes.
In this mode, the index is split into two files, $GIT_DIR/index and $GIT_DIR/sharedindex.<SHA-1>. Changes are accumulated in $GIT_DIR/index, the split index, while the shared index file contains all index entries and stays unchanged.
All changes in the split index are pushed back to the shared index file when the number of entries in the split index reaches a level specified by the splitIndex.maxPercentChange config variable (see git‐config(1)).
Each time a new shared index file is created, the old shared index files are deleted if their modification time is older than what is specified by the splitIndex.sharedIndexExpire config variable (see git‐config(1)).
To avoid deleting a shared index file that is still used, its modification time is updated to the current time every time a new split index based on the shared index file is either created or read from.
UNTRACKED CACHE This cache is meant to speed up commands that involve determining untracked files such as git status.
This feature works by recording the mtime of the working tree directories and then omitting reading directories and stat calls against files in those directories whose mtime hasn’t changed. For this to work the underlying operating system and file system must change the st_mtime field of directories if files in the directory are added, modified or deleted.
You can test whether the filesystem supports that with the --test-untracked-cache option. The --untracked-cache option used to implicitly perform that test in older versions of Git, but that’s no longer the case.
If you want to enable (or disable) this feature, it is easier to use the core.untrackedCache configuration variable (see git‐ config(1)) than using the --untracked-cache option to git update-index in each repository, especially if you want to do so across all repositories you use, because you can set the configuration variable to true (or false) in your $HOME/.gitconfig just once and have it affect all repositories you touch.
When the core.untrackedCache configuration variable is changed, the untracked cache is added to or removed from the index the next time a command reads the index; while when --[no-|force-]untracked-cache are used, the untracked cache is immediately added to or removed from the index.
Before 2.17, the untracked cache had a bug where replacing a directory with a symlink to another directory could cause it to incorrectly show files tracked by git as untracked. See the "status: add a failing test showing a core.untrackedCache bug" commit to git.git. A workaround for that is (and this might work for other undiscovered bugs in the future):
$ git -c core.untrackedCache=false status
This bug has also been shown to affect non-symlink cases of replacing a directory with a file when it comes to the internal structures of the untracked cache, but no case has been reported where this resulted in wrong "git status" output.
There are also cases where existing indexes written by git versions before 2.17 will reference directories that don’t exist anymore, potentially causing many "could not open directory" warnings to be printed on "git status". These are new warnings for existing issues that were previously silently discarded.
As with the bug described above the solution is to one-off do a "git status" run with core.untrackedCache=false to flush out the leftover bad data.
FILE SYSTEM MONITOR This feature is intended to speed up git operations for repos that have large working directories.
It enables git to work together with a file system monitor (see git‐fsmonitor‐‐daemon(1) and the "fsmonitor-watchman" section of githooks(5)) that can inform it as to what files have been modified. This enables git to avoid having to lstat() every file to find modified files.
When used in conjunction with the untracked cache, it can further improve performance by avoiding the cost of scanning the entire working directory looking for new files.
If you want to enable (or disable) this feature, it is easier to use the core.fsmonitor configuration variable (see git‐ config(1)) than using the --fsmonitor option to git update-index in each repository, especially if you want to do so across all repositories you use, because you can set the configuration variable in your $HOME/.gitconfig just once and have it affect all repositories you touch.
When the core.fsmonitor configuration variable is changed, the file system monitor is added to or removed from the index the next time a command reads the index. When --[no-]fsmonitor are used, the file system monitor is immediately added to or removed from the index.
CONFIGURATION The command honors core.filemode configuration variable. If your repository is on a filesystem whose executable bits are unreliable, this should be set to false (see git‐config(1)). This causes the command to ignore differences in file modes recorded in the index and the file mode on the filesystem if they differ only on executable bit. On such an unfortunate filesystem, you may need to use git update-index --chmod=.
Quite similarly, if core.symlinks configuration variable is set to false (see git‐config(1)), symbolic links are checked out as plain files, and this command does not modify a recorded file mode from symbolic link to regular file.
The command looks at core.ignorestat configuration variable. See Using "assume unchanged" bit section above.
The command also looks at core.trustctime configuration variable. It can be useful when the inode change time is regularly modified by something outside Git (file system crawlers and backup systems use ctime for marking files processed) (see git‐config(1)).
The untracked cache extension can be enabled by the core.untrackedCache configuration variable (see git‐config(1)).
NOTES Users often try to use the assume-unchanged and skip-worktree bits to tell Git to ignore changes to files that are tracked. This does not work as expected, since Git may still check working tree files against the index when performing certain operations. In general, Git does not provide a way to ignore changes to tracked files, so alternate solutions are recommended.
For example, if the file you want to change is some sort of config file, the repository can include a sample config file that can then be copied into the ignored name and modified. The repository can even include a script to treat the sample file as a template, modifying and copying it automatically.
SEE ALSO git‐config(1), git‐add(1), git‐ls‐files(1)
GIT Part of the git(1) suite
Git 2.40.1 05/18/2023 GIT-UPDATE-INDEX(1)

Git-update-index is a huge command. Here are two use cases:

Adding File

Similar to git add, git update-index --add adds a file in the working tree to the index. Call git write-tree to write the objects to the git database. Note that this does not make a commit. Here are the steps to make a commit using low-level git commands:

Shell
$ git update-index --add new.txt
$ SHA1="$( git write-tree }"
$ echo 'First commit' | git commit-tree $SHA1

Hiding Changes to Files and Directories from Git

If you need to make a temporary change to a file, and you do not want to commit the change, git update-index has a handy option: --assume-unchanged. This option causes git to temporarily ignore changes to that tracked file or directory. Git considers the changes to the files and directories you specify to be hidden, even though the file system does not consider the file to be hidden. Use it like this:

Shell
$ git update-index --assume-unchanged path/to/file.txt

Next time you run git status you will see that git is no longer aware of the edit. Any future changes to those files or directories will be ignored (hidden).

Shell
$ git commit -am "This is a comment"
$ git push

Actually, git has not forgotten about the file, it is merely ignoring changes to the hidden file. The -v option of the git-ls-files command causes the output to indicate hidden files with the h flag:

Shell
$ git ls-files -v
h path/to/file.txt 

To restore the file’s changes to being noticed by git again, use the --no-assume-unchanged option:

Shell
$ git update-index --no-assume-unchanged path/to/file.txt

You can read more about this option here.

Git-Update-Ref

The help message is:

git help update-ref
GIT-UPDATE-REF(1)             Git Manual             GIT-UPDATE-REF(1)
NAME git‐update‐ref - Update the object name stored in a ref safely
SYNOPSIS git update-ref [-m <reason>] [--no-deref] (-d <ref> [<oldvalue>] | [--create-reflog] <ref> <newvalue> [<oldvalue>] | --stdin [-z])
DESCRIPTION Given two arguments, stores the <newvalue> in the <ref>, possibly dereferencing the symbolic refs. E.g. git update-ref HEAD <newvalue> updates the current branch head to the new object.
Given three arguments, stores the <newvalue> in the <ref>, possibly dereferencing the symbolic refs, after verifying that the current value of the <ref> matches <oldvalue>. E.g. git update-ref refs/heads/master <newvalue> <oldvalue> updates the master branch head to <newvalue> only if its current value is <oldvalue>. You can specify 40 "0" or an empty string as <oldvalue> to make sure that the ref you are creating does not exist.
It also allows a "ref" file to be a symbolic pointer to another ref file by starting with the four-byte header sequence of "ref:".
More importantly, it allows the update of a ref file to follow these symbolic pointers, whether they are symlinks or these "regular file symbolic refs". It follows real symlinks only if they start with "refs/": otherwise it will just try to read them and update them as a regular file (i.e. it will allow the filesystem to follow them, but will overwrite such a symlink to somewhere else with a regular filename).
If --no-deref is given, <ref> itself is overwritten, rather than the result of following the symbolic pointers.
In general, using
git update-ref HEAD "$head"
should be a lot safer than doing
echo "$head" > "$GIT_DIR/HEAD"
both from a symlink following standpoint and an error checking standpoint. The "refs/" rule for symlinks means that symlinks that point to "outside" the tree are safe: they’ll be followed for reading but not for writing (so we’ll never write through a ref symlink to some other tree, if you have copied a whole archive by creating a symlink tree).
With -d flag, it deletes the named <ref> after verifying it still contains <oldvalue>.
With --stdin, update-ref reads instructions from standard input and performs all modifications together. Specify commands of the form:
update SP <ref> SP <newvalue> [SP <oldvalue>] LF create SP <ref> SP <newvalue> LF delete SP <ref> [SP <oldvalue>] LF verify SP <ref> [SP <oldvalue>] LF option SP <opt> LF start LF prepare LF commit LF abort LF
With --create-reflog, update-ref will create a reflog for each ref even if one would not ordinarily be created.
Quote fields containing whitespace as if they were strings in C source code; i.e., surrounded by double-quotes and with backslash escapes. Use 40 "0" characters or the empty string to specify a zero value. To specify a missing value, omit the value and its preceding SP entirely.
Alternatively, use -z to specify in NUL-terminated format, without quoting:
update SP <ref> NUL <newvalue> NUL [<oldvalue>] NUL create SP <ref> NUL <newvalue> NUL delete SP <ref> NUL [<oldvalue>] NUL verify SP <ref> NUL [<oldvalue>] NUL option SP <opt> NUL start NUL prepare NUL commit NUL abort NUL
In this format, use 40 "0" to specify a zero value, and use the empty string to specify a missing value.
In either format, values can be specified in any form that Git recognizes as an object name. Commands in any other format or a repeated <ref> produce an error. Command meanings are:
update Set <ref> to <newvalue> after verifying <oldvalue>, if given. Specify a zero <newvalue> to ensure the ref does not exist after the update and/or a zero <oldvalue> to make sure the ref does not exist before the update.
create Create <ref> with <newvalue> after verifying it does not exist. The given <newvalue> may not be zero.
delete Delete <ref> after verifying it exists with <oldvalue>, if given. If given, <oldvalue> may not be zero.
verify Verify <ref> against <oldvalue> but do not change it. If <oldvalue> is zero or missing, the ref must not exist.
option Modify behavior of the next command naming a <ref>. The only valid option is no-deref to avoid dereferencing a symbolic ref.
start Start a transaction. In contrast to a non-transactional session, a transaction will automatically abort if the session ends without an explicit commit. This command may create a new empty transaction when the current one has been committed or aborted already.
prepare Prepare to commit the transaction. This will create lock files for all queued reference updates. If one reference could not be locked, the transaction will be aborted.
commit Commit all reference updates queued for the transaction, ending the transaction.
abort Abort the transaction, releasing all locks if the transaction is in prepared state.
If all <ref>s can be locked with matching <oldvalue>s simultaneously, all modifications are performed. Otherwise, no modifications are performed. Note that while each individual <ref> is updated or deleted atomically, a concurrent reader may still see a subset of the modifications.
LOGGING UPDATES If config parameter "core.logAllRefUpdates" is true and the ref is one under "refs/heads/", "refs/remotes/", "refs/notes/", or a pseudoref like HEAD or ORIG_HEAD; or the file "$GIT_DIR/logs/<ref>" exists then git update-ref will append a line to the log file "$GIT_DIR/logs/<ref>" (dereferencing all symbolic refs before creating the log name) describing the change in ref value. Log lines are formatted as:
oldsha1 SP newsha1 SP committer LF
Where "oldsha1" is the 40 character hexadecimal value previously stored in <ref>, "newsha1" is the 40 character hexadecimal value of <newvalue> and "committer" is the committer’s name, email address and date in the standard Git committer ident format.
Optionally with -m:
oldsha1 SP newsha1 SP committer TAB message LF
Where all fields are as described above and "message" is the value supplied to the -m option.
An update will fail (without changing <ref>) if the current user is unable to create a new log file, append to the existing log file or does not have committer information available.
GIT Part of the git(1) suite
Git 2.40.1 05/18/2023 GIT-UPDATE-REF(1)

The following creates a new branch called my_branch at the current HEAD. This will create a file called .git/refs/heads/my_branch.

Shell
$ git update-ref refs/heads/my_branch HEAD

The above is equivalent to:

Shell
$ git branch my_branch

Git-Write-Tree

This is the help message:

Shell
$ git help write-tree
GIT-WRITE-TREE(1)             Git Manual             GIT-WRITE-TREE(1)
NAME git‐write‐tree - Create a tree object from the current index
SYNOPSIS git write-tree [--missing-ok] [--prefix=<prefix>/]
DESCRIPTION Creates a tree object using the current index. The name of the new tree object is printed to standard output.
The index must be in a fully merged state.
Conceptually, git write-tree sync()s the current index contents into a set of tree files. In order to have that match what is actually in your directory right now, you need to have done a git update-index phase before you did the git write-tree.
OPTIONS --missing-ok Normally git write-tree ensures that the objects referenced by the directory exist in the object database. This option disables this check.
--prefix=<prefix>/ Writes a tree object that represents a subdirectory <prefix>. This can be used to write the tree object for a subproject that is in the named subdirectory.
GIT Part of the git(1) suite
Git 2.40.1 05/18/2023 GIT-WRITE-TREE(1)


* indicates a required field.

Please select the following to receive Mike Slinn’s newsletter:

You can unsubscribe at any time by clicking the link in the footer of emails.

Mike Slinn uses Mailchimp as his marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp’s privacy practices.