Mike Slinn
Mike Slinn

Low-Level Git Commands

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

This page is part of the git collection, categorized under Git.

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.

Shell
$ git help cat-file
GIT-CAT-FILE(1)              Git Manual              GIT-CAT-FILE(1)

NAME
       git-cat-file - Provide content or type and size information
       for repository objects

SYNOPSIS
       git cat-file <type> <object>
       git cat-file (-e | -p) <object>
       git cat-file (-t | -s) [--allow-unknown-type] <object>
       git cat-file (--batch | --batch-check | --batch-command) [--batch-all-objects]
                    [--buffer] [--follow-symlinks] [--unordered]
                    [--textconv | --filters]
       git cat-file (--textconv | --filters)
                    [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]

DESCRIPTION
       In its first form, the command provides the content or the
       type of an object in the repository. The type is required
       unless -t or -p is used to find the object type, or -s is
       used to find the object size, or --textconv or --filters is
       used (which imply type "blob").

       In the second form, a list of objects (separated by
       linefeeds) is provided on stdin, and the SHA-1, type, and
       size of each object is printed on stdout. The output format
       can be overridden using the optional <format> argument. If
       either --textconv or --filters was specified, the input is
       expected to list the object names followed by the path name,
       separated by a single whitespace, so that the appropriate
       drivers can be determined.

OPTIONS
       <object>
           The name of the object to show. For a more complete list
           of ways to spell object names, see the "SPECIFYING
           REVISIONS" section in gitrevisions(7).

       -t
           Instead of the content, show the object type identified
           by <object>.

       -s
           Instead of the content, show the object size identified
           by <object>.

       -e
           Exit with zero status if <object> exists and is a valid
           object. If <object> is of an invalid format exit with
           non-zero and emits an error on stderr.

       -p
           Pretty-print the contents of <object> based on its type.

       <type>
           Typically this matches the real type of <object> but
           asking for a type that can trivially be dereferenced from
           the given <object> is also permitted. An example is to
           ask for a "tree" with <object> being a commit object that
           contains it, or to ask for a "blob" with <object> being a
           tag object that points at it.

       --textconv
           Show the content as transformed by a textconv filter. In
           this case, <object> has to be of the form
           <tree-ish>:<path>, or :<path> in order to apply the
           filter to the content recorded in the index at <path>.

       --filters
           Show the content as converted by the filters configured
           in the current working tree for the given <path> (i.e.
           smudge filters, end-of-line conversion, etc). In this
           case, <object> has to be of the form <tree-ish>:<path>,
           or :<path>.

       --path=<path>
           For use with --textconv or --filters, to allow specifying
           an object name and a path separately, e.g. when it is
           difficult to figure out the revision from which the blob
           came.

       --batch, --batch=<format>
           Print object information and contents for each object
           provided on stdin. May not be combined with any other
           options or arguments except --textconv or --filters, in
           which case the input lines also need to specify the path,
           separated by whitespace. See the section BATCH OUTPUT
           below for details.

       --batch-check, --batch-check=<format>
           Print object information for each object provided on
           stdin. May not be combined with any other options or
           arguments except --textconv or --filters, in which case
           the input lines also need to specify the path, separated
           by whitespace. See the section BATCH OUTPUT below for
           details.

       --batch-command, --batch-command=<format>
           Enter a command mode that reads commands and arguments
           from stdin. May only be combined with --buffer,
           --textconv or --filters. In the case of --textconv or
           --filters, the input lines also need to specify the path,
           separated by whitespace. See the section BATCH OUTPUT
           below for details.

           --batch-command recognizes the following commands:

           contents <object>
               Print object contents for object reference <object>.
               This corresponds to the output of --batch.

           info <object>
               Print object info for object reference <object>. This
               corresponds to the output of --batch-check.

           flush
               Used with --buffer to execute all preceding commands
               that were issued since the beginning or since the
               last flush was issued. When --buffer is used, no
               output will come until a flush is issued. When
               --buffer is not used, commands are flushed each time
               without issuing flush.

       --batch-all-objects
           Instead of reading a list of objects on stdin, perform
           the requested batch operation on all objects in the
           repository and any alternate object stores (not just
           reachable objects). Requires --batch or --batch-check be
           specified. By default, the objects are visited in order
           sorted by their hashes; see also --unordered below.
           Objects are presented as-is, without respecting the
           "replace" mechanism of git-replace(1).

       --buffer
           Normally batch output is flushed after each object is
           output, so that a process can interactively read and
           write from cat-file. With this option, the output uses
           normal stdio buffering; this is much more efficient when
           invoking --batch-check or --batch-command on a large
           number of objects.

       --unordered
           When --batch-all-objects is in use, visit objects in an
           order which may be more efficient for accessing the
           object contents than hash order. The exact details of the
           order are unspecified, but if you do not require a
           specific order, this should generally result in faster
           output, especially with --batch. Note that cat-file will
           still show each object only once, even if it is stored
           multiple times in the repository.

       --allow-unknown-type
           Allow -s or -t to query broken/corrupt objects of unknown
           type.

       --follow-symlinks
           With --batch or --batch-check, follow symlinks inside the
           repository when requesting objects with extended SHA-1
           expressions of the form tree-ish:path-in-tree. Instead of
           providing output about the link itself, provide output
           about the linked-to object. If a symlink points outside
           the tree-ish (e.g. a link to /foo or a root-level link to
           ../foo), the portion of the link which is outside the
           tree will be printed.

           This option does not (currently) work correctly when an
           object in the index is specified (e.g.  :link instead of
           HEAD:link) rather than one in the tree.

           This option cannot (currently) be used unless --batch or
           --batch-check is used.

           For example, consider a git repository containing:

               f: a file containing "hello\n"
               link: a symlink to f
               dir/link: a symlink to ../f
               plink: a symlink to ../f
               alink: a symlink to /etc/passwd

           For a regular file f, echo HEAD:f | git cat-file --batch
           would print

               ce013625030ba8dba906f756967f9e9ca394464a blob 6

           And echo HEAD:link | git cat-file --batch
           --follow-symlinks would print the same thing, as would
           HEAD:dir/link, as they both point at HEAD:f.

           Without --follow-symlinks, these would print data about
           the symlink itself. In the case of HEAD:link, you would
           see

               4d1ae35ba2c8ec712fa2a379db44ad639ca277bd blob 1

           Both plink and alink point outside the tree, so they
           would respectively print:

               symlink 4
               ../f

               symlink 11
               /etc/passwd

OUTPUT
       If -t is specified, one of the <type>.

       If -s is specified, the size of the <object> in bytes.

       If -e is specified, no output, unless the <object> is
       malformed.

       If -p is specified, the contents of <object> are
       pretty-printed.

       If <type> is specified, the raw (though uncompressed)
       contents of the <object> will be returned.

BATCH OUTPUT
       If --batch or --batch-check is given, cat-file will read
       objects from stdin, one per line, and print information about
       them. By default, the whole line is considered as an object,
       as if it were fed to git-rev-parse(1).

       When --batch-command is given, cat-file will read commands
       from stdin, one per line, and print information based on the
       command given. With --batch-command, the info command
       followed by an object will print information about the object
       the same way --batch-check would, and the contents command
       followed by an object prints contents in the same way --batch
       would.

       You can specify the information shown for each object by
       using a custom <format>. The <format> is copied literally to
       stdout for each object, with placeholders of the form %(atom)
       expanded, followed by a newline. The available atoms are:

       objectname
           The full hex representation of the object name.

       objecttype
           The type of the object (the same as cat-file -t reports).

       objectsize
           The size, in bytes, of the object (the same as cat-file
           -s reports).

       objectsize:disk
           The size, in bytes, that the object takes up on disk. See
           the note about on-disk sizes in the CAVEATS section
           below.

       deltabase
           If the object is stored as a delta on-disk, this expands
           to the full hex representation of the delta base object
           name. Otherwise, expands to the null OID (all zeroes).
           See CAVEATS below.

       rest
           If this atom is used in the output string, input lines
           are split at the first whitespace boundary. All
           characters before that whitespace are considered to be
           the object name; characters after that first run of
           whitespace (i.e., the "rest" of the line) are output in
           place of the %(rest) atom.

       If no format is specified, the default format is
       %(objectname) %(objecttype) %(objectsize).

       If --batch is specified, or if --batch-command is used with
       the contents command, the object information is followed by
       the object contents (consisting of %(objectsize) bytes),
       followed by a newline.

       For example, --batch without a custom format would produce:

           <oid> SP <type> SP <size> LF
           <contents> LF

       Whereas --batch-check='%(objectname) %(objecttype)' would
       produce:

           <oid> SP <type> LF

       If a name is specified on stdin that cannot be resolved to an
       object in the repository, then cat-file will ignore any
       custom format and print:

           <object> SP missing LF

       If a name is specified that might refer to more than one
       object (an ambiguous short sha), then cat-file will ignore
       any custom format and print:

           <object> SP ambiguous LF

       If --follow-symlinks is used, and a symlink in the repository
       points outside the repository, then cat-file will ignore any
       custom format and print:

           symlink SP <size> LF
           <symlink> LF

       The symlink will either be absolute (beginning with a /), or
       relative to the tree root. For instance, if dir/link points
       to ../../foo, then <symlink> will be ../foo. <size> is the
       size of the symlink in bytes.

       If --follow-symlinks is used, the following error messages
       will be displayed:

           <object> SP missing LF

       is printed when the initial symlink requested does not exist.

           dangling SP <size> LF
           <object> LF

       is printed when the initial symlink exists, but something
       that it (transitive-of) points to does not.

           loop SP <size> LF
           <object> LF

       is printed for symlink loops (or any symlinks that require
       more than 40 link resolutions to resolve).

           notdir SP <size> LF
           <object> LF

       is printed when, during symlink resolution, a file is used as
       a directory name.

CAVEATS
       Note that the sizes of objects on disk are reported
       accurately, but care should be taken in drawing conclusions
       about which refs or objects are responsible for disk usage.
       The size of a packed non-delta object may be much larger than
       the size of objects which delta against it, but the choice of
       which object is the base and which is the delta is arbitrary
       and is subject to change during a repack.

       Note also that multiple copies of an object may be present in
       the object database; in this case, it is undefined which
       copy’s size or delta base will be reported.

GIT
       Part of the git(1) suite

Git 2.37.2                   04/24/2023              GIT-CAT-FILE(1)

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

shell Obtaining the type of a reference
$ exec git cat-file -t HEAD:.gitignore
blob 

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

shell Listing a file version
$ 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.37.2                   04/24/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.37.2                   04/24/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. A
           convenient way to produce the desired set of revisions is
           to use the ^@ suffix. For instance, if master names a
           merge commit, git diff master master^@ gives the same
           combined diff as git show master.

       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 on generating patches). 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.

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.37.2                   04/24/2023                  GIT-DIFF(1)

To create a patch between HEAD and the previous commit:

Shell
$ git diff HEAD HEAD~1
diff --git a/_includes/aboutRubyAuthor.html b/_includes/aboutRubyAuthor.html
index 3b1c2e6d..b7bd2fac 100644
--- a/_includes/aboutRubyAuthor.html
+++ b/_includes/aboutRubyAuthor.html
@@ -1,8 +1,9 @@
 <h2 id="about" class="clear">About the Author</h2>
-<img
-  class="right rounded shadow"
+{% img
+  align="right"
   src="/blog/images/svRuby/sdforum_ruby_690x565.webp"
-  style="height: auto; width: 25%;">
+  size="quartersize"
+%}
 <p>
   I, Mike Slinn, have been working with Ruby a long time now.
   Back in 2005 I was the product marketing manager at CodeGear
@@ -23,6 +24,5 @@
   if that interests you.
 </p>
 <p>
-  I currently enjoy writing <a href="/blog/index.html#Jekyll">Jekyll plugins</a> in Ruby for this website and others,
-  and Ruby utilities.
+  I currently enjoy writing <a href="/blog/index.html#Jekyll">Jekyll plugins</a> in Ruby for this website and others.
 </p>
diff --git a/collections/_ruby/1000-ruby-setup.html b/collections/_ruby/1000-ruby-setup.html
index 2a295f99..a640c827 100644
--- a/collections/_ruby/1000-ruby-setup.html
+++ b/collections/_ruby/1000-ruby-setup.html
@@ -547,13 +547,13 @@ Done installing documentation for rake after 0 seconds
     provides the <code>bundle</code> command, which
     lets you define the libraries that a project needs.
     It will automatically resolve version conflicts and
-    download all appropriate gems from the sources you provide.<br>
+    download all appropriate gems from the sources you provide.
     {% pre copyButton shell %}{% noselect %}gem install bundler{% endpre %}
   </li>
   <li>
     {% href https://ruby.github.io/rake/ <code>rake</code> %}
     is a Make-like program implemented in Ruby.
-    Tasks and dependencies are specified in standard Ruby syntax.<br>
+    Tasks and dependencies are specified in standard Ruby syntax.
     {% pre copyButton shell %}{% noselect %}gem install rake{% endpre %}
   </li>
   <li>A testing framework: <code>rspec</code>, <code>minitest</code>, <code>minispec</code>, <code>bacon</code>, <code>test::unit</code>, <code>cucumber</code>, <code>capybara</code>, etc.
diff --git a/collections/_ruby/10200-debugging-rackup.html b/collections/_ruby/10200-debugging-rackup.html
index 0e970326..82bf6cab 100644
--- a/collections/_ruby/10200-debugging-rackup.html
+++ b/collections/_ruby/10200-debugging-rackup.html
@@ -219,6 +219,3 @@ load {% href https://www.rubydoc.info/github/rubygems/rubygems/Gem.bin_path Gem.
 <p>
   Easy!
 </p>
-
-
-{% include aboutRubyAuthor.html %}
diff --git a/collections/_ruby/1200-rubocop-install.html b/collections/_ruby/1200-rubocop-install.html
index 3a564f0e..2b3e677f 100644
--- a/collections/_ruby/1200-rubocop-install.html
+++ b/collections/_ruby/1200-rubocop-install.html
@@ -73,8 +73,7 @@ title: Installing Rubocop As a Development Dependency
 {%endpre%}
 <p class="pullQuote">
     Bundler v2.1 happened years ago!
-    {% href https://bundler.io/v2.1/whats_new.html
-      label="<span class='code'>Bundler</span> behavior will change when 3.0 is released" %};
+    {% href https://bundler.io/v2.1/whats_new.html <span class="code">Bundler</span> behavior will change when 3.0 is released %};
     do not allow your projects to stop working because you followed misinformation.
 </p>
 <p>
@@ -1026,7 +1025,7 @@ SEE ALSO
 <!-- endregion -->
 
 
-<!-- #region Example: Persistant Setting -->
+<!-- #region -->
 <h2 id="use">Example: Persistant Setting</h2>
 <p>
   Let&rsquo;s use the above information to install a gem, including development dependencies.
@@ -1092,7 +1091,7 @@ Set for your local app (/mnt/f/work/my_app/.bundle/config): [:development] %}
 <!-- endregion -->
 
 
-<!-- #region Example: Environment Settings -->
+<!-- #region -->
 <h2 id="env">Example: Environment Settings</h2>
 <p>
   If you do not want to use persistent settings, but prefer instead to apply settings as needed,
@@ -1104,7 +1103,7 @@ Set for your local app (/mnt/f/work/my_app/.bundle/config): [:development] %}
 <!-- endregion -->
 
 
-<!-- #region Specifying Development Dependencies -->
+<!-- #region -->
 <h2 id="good">Specifying Development Dependencies</h2>
 <p>
   Going beyond what the official (and horribly misguided) installation instructions say,
@@ -1139,12 +1138,10 @@ spec.add_development_dependency 'pry'
   and are much less often invoked programatically, so this is not a problem.
 </p>
 {% pre copyButton Gemfile %}
-group :test, :development do
-  gem 'bundler'<span class="bg_yellow">, require: false</span>
-  gem 'rake'<span class="bg_yellow">, require: false</span>
-  gem 'rspec'<span class="bg_yellow">, require: false</span>
-  gem 'rubocop'<span class="bg_yellow">, require: false</span>
-end
+gem 'bundler', '~> 2.2.7'<span class="bg_yellow">, require: false</span>
+gem 'rake'<span class="bg_yellow">, require: false</span>
+gem 'rspec'<span class="bg_yellow">, require: false</span>
+gem 'rubocop', '~> 1.18.0'<span class="bg_yellow">, require: false</span> # rubocop-jekyll requires this older version
 {% endpre %}
 
 
@@ -1180,7 +1177,7 @@ end
 {% pre copyButton shell %}
 {% noselect %}bundle config --delete with
 
-{% noselect %}bundle
+{% noselect %}bundle install
 {% endpre %}
 
 
@@ -1191,7 +1188,7 @@ end
 {% pre copyButton shell %}
 {% noselect %}bundle config set --local with ''
 
-{% noselect %}bundle
+{% noselect %}bundle install
 {% endpre %}
 
 
@@ -1200,23 +1197,19 @@ end
     Ignore all configuration settings.
 </p>
 {% pre copyButton shell %}
-{% noselect %}BUNDLE_IGNORE_CONFIG=true bundle
+{% noselect %}BUNDLE_IGNORE_CONFIG=true bundle install
 {% endpre %}
 
 
 <h2 id="jekyll_standards">Jekyll Coding Standards</h2>
 <p>
-  Rubocop standards for Jekyll are provided by
+  Rubocop standards are provided by
   {% href https://github.com/jekyll/rubocop-jekyll rubocop-jekyll %},
   a gem containing a RuboCop extension that enforces common code style in Jekyll and Jekyll plugins.
   Here is an example of its suggestions:
 </p>
 {% img src="/blog/jekyll/plugins/rubocop_jekyll_message.webp" %}
 
-<p class="alert rounded shadow">
-  This gem has been updated, but I have not looked at the update yet.
-  The rest of this section is likely out of date.
-</p>
 <p>
   The standards are out of date.
   Ruby 2.4 is no longer a viable version, Ruby 2.5 or later must be used.
@@ -1365,5 +1358,3 @@ find "$( rbenv root )" -regex ".*/exe/$GEM" | sort
 {% endpre %}
 {% endcomment %}
 <!-- endregion -->
-
-{% include aboutRubyAuthor.html %}
diff --git a/collections/_ruby/12400-sinatra-db.html b/collections/_ruby/12400-sinatra-db.html
index 18e8fe53..fe90b15d 100644
--- a/collections/_ruby/12400-sinatra-db.html
+++ b/collections/_ruby/12400-sinatra-db.html
@@ -115,6 +115,3 @@ title: Database Frameworks for Sinatra
   User-centrinc product exposition ... so rare in F/OSS!
 </p>
 <!-- endregion -->
-
-
-{% include aboutRubyAuthor.html %}
diff --git a/collections/_ruby/12400-sinatraRequestExplorer.html b/collections/_ruby/12400-sinatraRequestExplorer.html
index dfb59da4..c58deed2 100644
--- a/collections/_ruby/12400-sinatraRequestExplorer.html
+++ b/collections/_ruby/12400-sinatraRequestExplorer.html
@@ -265,6 +265,3 @@ HTTP_USER_AGENT=curl/7.85.0
 {% pre copyButton crontab %}
 @reboot ruby /work/ruby/sinatra/SinatraRequestExplorer/main.rb
 {% endpre %}
-
-
-{% include aboutRubyAuthor.html %}
diff --git a/collections/_ruby/12600-sinatra-warden.html b/collections/_ruby/12600-sinatra-warden.html
index 09909a75..1bd31c5a 100644
--- a/collections/_ruby/12600-sinatra-warden.html
+++ b/collections/_ruby/12600-sinatra-warden.html
@@ -320,6 +320,3 @@ dependencies accordingly.
   and I will explain how that works in a future blog post.
 </p>
 <!-- endregion -->
-
-
-{% include aboutRubyAuthor.html %}
diff --git a/collections/_ruby/12800-sinatra-activerecord.html b/collections/_ruby/12800-sinatra-activerecord.html
index 1b406a52..586bdbf9 100644
--- a/collections/_ruby/12800-sinatra-activerecord.html
+++ b/collections/_ruby/12800-sinatra-activerecord.html
@@ -920,6 +920,3 @@ end
   without getting confused by Rails documentation when you encounter it.
 </p>
 <!-- endregion -->
-
-
-{% include aboutRubyAuthor.html %}
diff --git a/collections/_ruby/14200-solidus.html b/collections/_ruby/14200-solidus.html
index f11ab80e..ba14144b 100644
--- a/collections/_ruby/14200-solidus.html
+++ b/collections/_ruby/14200-solidus.html
@@ -1582,6 +1582,3 @@ Completed 200 OK in 65ms (Views: 33.0ms | ActiveRecord: 0.0ms | Allocations: 412
   <li>{% href https://keyua.org/blog/rails-vs-django-comparison/ Django vs Rails in 2022: Comparison Performance Frameworks %}</li>
 </ol>
 <!-- endregion -->
-
-
-{% include aboutRubyAuthor.html %}
diff --git a/collections/_ruby/4600-vscode-ext-jekyll.html b/collections/_ruby/4600-vscode-ext-jekyll.html
index 223216a8..1ddd45c4 100644
--- a/collections/_ruby/4600-vscode-ext-jekyll.html
+++ b/collections/_ruby/4600-vscode-ext-jekyll.html
@@ -69,5 +69,3 @@ title: Visual Studio Code Extensions for Jekyll Development
      Note: Bust A Gem relies on bundler and only works with Ruby projects that have a Gemfile.
   </li>
 </ol>
-
-{% include aboutRubyAuthor.html %}
diff --git a/collections/_ruby/5100-rubocop-vscode.html b/collections/_ruby/5100-rubocop-vscode.html
index ff4dc703..64e362ee 100644
--- a/collections/_ruby/5100-rubocop-vscode.html
+++ b/collections/_ruby/5100-rubocop-vscode.html
@@ -95,6 +95,3 @@ AllCops:
   NewCops: enable
   TargetRubyVersion: 2.5
 {% endpre %}
-
-
-{% include aboutRubyAuthor.html %}
diff --git a/collections/_ruby/6050-git-tree-impl.html b/collections/_ruby/6050-git-tree-impl.html
index 6be6c2a2..11e040d9 100644
--- a/collections/_ruby/6050-git-tree-impl.html
+++ b/collections/_ruby/6050-git-tree-impl.html
@@ -216,5 +216,3 @@ GitTree.command_replicate
   Simple, elegant, flexible and easy to understand modularity.
 </p>
 <!-- endregion -->
-
-{% include aboutRubyAuthor.html %}
diff --git a/collections/_ruby/6100-slim-templates.html b/collections/_ruby/6100-slim-templates.html
index 9ec4b9a9..eda16fc0 100644
--- a/collections/_ruby/6100-slim-templates.html
+++ b/collections/_ruby/6100-slim-templates.html
@@ -228,8 +228,7 @@ environment:
 </p>
 <p>
   To make the video, I installed the
-  {% href https://marketplace.visualstudio.com/items?itemName=tht13.html-preview-vscode
-    Visual Studio Code HTML Preview extension %}
+  {% href https://marketplace.visualstudio.com/items?itemName=tht13.html-preview-vscode Visual Studio Code HTML Preview extension %}
   by Thomas Haakon Townsend, which had 1,649,338 installations.
   While this is a generally useful extension,
   it enables the instantaneous display of the generated HTML in a render pane.
@@ -238,6 +237,3 @@ environment:
 {% pre copyButton shell %}
 {% noselect %}code --install-extension tht13.html-preview-vscode@0.2.5
 {% endpre %}
-
-
-{% include aboutRubyAuthor.html %}
diff --git a/collections/_ruby/6300-gem-templates.html b/collections/_ruby/6300-gem-templates.html
index 6a829a9c..2a1670a6 100644
--- a/collections/_ruby/6300-gem-templates.html
+++ b/collections/_ruby/6300-gem-templates.html
@@ -377,5 +377,3 @@ c5f6f14 v1.0.0
 bd9f1d4 test %}
 {% endpre %}
 <!-- endregion -->
-
-{% include aboutRubyAuthor.html %}
diff --git a/collections/_ruby/6550-gem-navel.html b/collections/_ruby/6550-gem-navel.html
index 09ff2827..0bd67b0b 100644
--- a/collections/_ruby/6550-gem-navel.html
+++ b/collections/_ruby/6550-gem-navel.html
@@ -292,6 +292,3 @@ spec = current_spec __FILE__
   {% href /jekyll/10200-jekyll-plugin-support.html#attribution <code>jekyll_plugin_support</code> subclass attribution feature %} works.
 </p>
 <!-- endregion -->
-
-
-{% include aboutRubyAuthor.html %}
diff --git a/collections/_ruby/index.html b/collections/_ruby/index.html
index 65ebdf14..72d2014a 100644
--- a/collections/_ruby/index.html
+++ b/collections/_ruby/index.html
@@ -44,6 +44,4 @@ title: Organized Ruby Articles
 </div>
 <!-- endregion -->
 
-{% include aboutRubyAuthor.html %}
-
 {% outline_js wrap_in_script_tag %}

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.37.2                   04/24/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>
           If no --decorate-refs is given, pretend as if all refs
           were included. For each candidate, 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.

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

       --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
           When given a range of commits to display (e.g.
           commit1..commit2 or commit2 ^commit1), only display
           commits that exist directly on the ancestry chain between
           the commit1 and commit2, i.e. commits that are both
           descendants of commit1, and ancestors of commit2.

       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
           Limit the displayed commits to those directly on the
           ancestry chain between the “from” and “to” commits in the
           given commit range. I.e. only display commits that are
           ancestor of the “to” commit and descendants of the “from”
           commit.

           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

       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: manu 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 similar to
           --date=rfc2822, with a few exceptions:

           •   there is no comma after the day-of-week

           •   the time zone is omitted when the local time zone is
               used

       --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
                   columns, padding spaces on the right if
                   necessary. Optionally truncate at the beginning
                   (ltrunc), the middle (mtrunc) or the end (trunc)
                   if the output is longer than N columns. Note that
                   truncating only works correctly with N >= 2.

               %<|(<N>)
                   make the next placeholder take at least until Nth
                   columns, padding spaces on the right if necessary

               %>(<N>), %>|(<N>)
                   similar to %<(<N>), %<|(<N>) respectively, but
                   padding spaces on the left

               %>>(<N>), %>>|(<N>)
                   similar to %>(<N>), %>|(<N>) respectively, except
                   that if the next placeholder takes more spaces
                   than given and there are spaces on its left, use
                   those spaces

               %><(<N>), %><|(<N>)
                   similar to %<(<N>), %<|(<N>) 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 on generating patches).

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

       log.date
           Default format for human-readable dates. (Compare the
           --date option.) Defaults to "default", which means to
           write dates like Sat May 8 19:35:34 2010 -0500.

           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.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.showRoot
           If false, git log and related commands will not treat the
           initial commit as a big creation event. Any root commits
           in git log -p output would be shown without a diff
           attached. The default is true.

       log.showSignature
           If true, git log and related commands will act as if the
           --show-signature option was passed to them.

       mailmap.*
           See git-shortlog(1).

       notes.displayRef
           Which refs, in addition to the default set by
           core.notesRef or GIT_NOTES_REF, to read notes from when
           showing commit messages with the log family of commands.
           See git-notes(1).

           May be an unabbreviated ref name or a glob and may be
           specified multiple times. 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,
           overridden by the GIT_NOTES_DISPLAY_REF environment
           variable, and overridden by the --notes=<ref> option.

GIT
       Part of the git(1) suite

Git 2.37.2                   04/24/2023                   GIT-LOG(1)

The following uses git-log to view the commit message, the commit date, the branch, the remote branch and author information:

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

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

OPTIONS
       -c, --cached
           Show cached files in the output (default)

       -d, --deleted
           Show deleted files in the output

       -m, --modified
           Show modified files in the output

       -o, --others
           Show other (i.e. untracked) files in the output

       -i, --ignored
           Show only ignored files in the output. When showing files
           in the index, print only those matched by an exclude
           pattern. When showing "other" files, 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.

       --no-empty-directory
           Do not list empty directories. Has no effect without
           --directory.

       -u, --unmerged
           Show unmerged files in the output (forces --stage)

       -k, --killed
           Show files on the filesystem that need to be removed due
           to file/directory conflicts for checkout-index to
           succeed.

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

       --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
           This feature is semi-deprecated. For scripting purpose,
           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 identifies the file status with the following
           tags (followed by a space) at the start of each line:

           H
               cached

           S
               skip-worktree

           M
               unmerged

           R
               removed/deleted

           C
               modified/changed

           K
               to be killed

           ?
               other

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

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

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.

       These exclude patterns come from these 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.37.2                   04/24/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.37.2                   04/24/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.

       --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, 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 then 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.37.2                   04/24/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 --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
                   columns, padding spaces on the right if
                   necessary. Optionally truncate at the beginning
                   (ltrunc), the middle (mtrunc) or the end (trunc)
                   if the output is longer than N columns. Note that
                   truncating only works correctly with N >= 2.

               %<|(<N>)
                   make the next placeholder take at least until Nth
                   columns, padding spaces on the right if necessary

               %>(<N>), %>|(<N>)
                   similar to %<(<N>), %<|(<N>) respectively, but
                   padding spaces on the left

               %>>(<N>), %>>|(<N>)
                   similar to %>(<N>), %>|(<N>) respectively, except
                   that if the next placeholder takes more spaces
                   than given and there are spaces on its left, use
                   those spaces

               %><(<N>), %><|(<N>)
                   similar to %<(<N>), %<|(<N>) 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 on generating patches).

       -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.37.2                   04/24/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.37.2                   04/24/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:

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

       -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.37.2                   04/24/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 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.37.2                   04/24/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:

Shell
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.37.2                   04/24/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.37.2                   04/24/2023            GIT-WRITE-TREE(1)