Published 2023-03-13.
Last modified 2023-05-15.
Time to read: 4 minutes.
git
collection.
This article discusses low-level git
commands.
It builds on the material presented in Git Concepts.
The commands are presented in alphabetical order.
Unfortunately, I do not say much of interest in this page between git-cat-file
(next),
and git-rev-parse
.
This page will be updated.
The version of git
used in this article is:
$ git --version git version 2.37.2
Git-Cat-File
Here is the help information for git-cat-file
.
$
Obtain Reference Type
This example obtains the type of a reference for .gitignore
at HEAD
:
$ exec git cat-file -t HEAD:.gitignore blob
Remember, a git blob
is just a stored file,
and a git tree
is just a stored directory.
Display File From SHA
Two syntaxes are possible to display the contents of a file, given its SHA:
$ git cat-file -p a997766
$ git cat-file a997766^{blob}
Display File by Commit and Name
This example lists the first 10 lines of the contents of the version of the
.gitignore
file at the HEAD
commit:
$ 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
$
Git-Describe
The help information is:
Here is an example:
$ 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:
$
To create a patch between HEAD
and the previous commit:
$
Git-Hash-Object
Computes the object id (oid) for an object, and optionally store it as a blog.
$
$ echo 'test content' | git hash-object --stdin d670460b4b4aece5915caf5c68d12f560a9fe3e4
Git-Log
Git log
is flexible and powerful.
Here is the help message
$
View the N Most Recent Commits
The following uses git-log
to view the commit message, the commit date, the branch,
the remote branch and author information of the most recent commit on the current branch:
$ git log -1 commit d9eaf1372978872c232c2875c7376f4e9e2dbd7f Author: Mike Slinn <mslinn@mslinn.com> Date: Mon May 15 14:29:46 2023 -0400
this is a comment
Similarly, git log -N
returns information about the
N
most recent commits.
$ git log -3 commit 795e7d363e0677ebf64ff02fc8e2e03bccf1ff9f (HEAD -> master, origin/master, origin/HEAD) Author: Mike SlinnDate: Thu Jul 13 14:20:50 2023 -0400
this is a comment
commit c0b0e51264c6077815241c8d0c584f2746cd30ab Author: Mike SlinnDate: Thu Jul 13 14:03:44 2023 -0400
yet another comment
commit a34f1b489ae450edec45acfedd46177135ae4bd6 Author: Mike SlinnDate: Thu Jul 13 14:02:54 2023 -0400
yay, another comment
Find Commit Of the First Version of a File
To get information about the first commit that has a specific file in it:
$ git log --diff-filter=A -- README.md commit c8c92b5f19e49402aa367d470fb89b289ae788f0 Author: Mike SlinnDate: Sat Jul 11 21:11:38 2020 -0400
This is the comment
To specify a file path, do not provide a leading slash. For example, write the path this way:
$ git log --diff-filter=A -- path/to/file.ext
Do not write it this way:
$ git log --diff-filter=A -- /path/to/file.ext
Obtain Commit SHA Containing the First Version of a File
To get the hash of the first commit that has the file in it:
$ git log --format="%h" --diff-filter=A -- path/to/file.ext c8c92b5
To get 9 digits of the hash, use the --abbrev
option:
$ git log --format="%h" --abbrev=9 --diff-filter=A -- path/to/file.ext c8c92b5f1
Git-Ls-Files
Here is the help information for git-ls-files
.
$
Git-Ls-Tree
Git ls-tree
shows the contents of a tree object.
This is the git-ls-tree
man page:
$
-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:
$ 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:
$ 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:
$ 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.
$
There are several ways to discover the SHA
of the HEAD
commit:
$ git rev-parse HEAD d9eaf1372978872c232c2875c7376f4e9e2dbd7f
$ $ git rev-parse --symbolic-full-name HEAD refs/heads/master
$ git rev-parse refs/heads/master d9eaf1372978872c232c2875c7376f4e9e2dbd7f
$ git rev-parse --short HEAD d9eaf137
$ git rev-parse --short master d9eaf137
$ git rev-parse --short refs/heads/master d9eaf137
$ git rev-parse --short @ d9eaf137
Read about accessing parent commits.
You can get the SHA of the penultimate commit (the parent of HEAD
),
and the SHA of the commit before that:
$ 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
:
$ git rev-parse --short HEAD@{1} e4e53f69
Git-Show
This is the help message for git-show
:
$
Git-Show-Ref
This is the help message for git-show-ref
:
$
View all refs that are a HEAD
in a repo:
$ 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:
$ git show-ref --abbrev=8 --head master d9eaf137 HEAD d9eaf137 refs/heads/master d9eaf137 refs/remotes/origin/master
Show the SHA
for HEAD
:
$ git show-ref -s --head HEAD d9eaf1372978872c232c2875c7376f4e9e2dbd7f d9eaf1372978872c232c2875c7376f4e9e2dbd7f
Git-Symbolic-Ref
The help message is:
Obtain the value of your HEAD
:
$ git symbolic-ref HEAD refs/heads/master
Set the value of HEAD to the test
branch.
(This is what git branch test
does).
$ git symbolic-ref HEAD refs/heads/test
$ cat .git/HEAD ref: refs/heads/test
Git-Update-Index
This is the help message:
$
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:
$ 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:
$ 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).
$ 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:
$ 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:
$ 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:
The following creates a new branch called my_branch
at the current HEAD
.
This will create a file called .git/refs/heads/my_branch
.
$ git update-ref refs/heads/my_branch HEAD
The above is equivalent to:
$ git branch my_branch
Git-Write-Tree
This is the help message:
$