show | How to Use Git Show With Examples

0
29

Table of Contents

What Does Git Show Do?

The git show command is a powerful tool that allows developers to display the contents of Git objects within a Git repository.

As you add and commit your code changes, Git tracks these changes using four main types of Git objects: Blobs, Trees, Commits, and Tags. Git stores these objects in its object database, which is located inside the hidden .git / folder.

The git show command is used to display the contents of any of these four object types:

  1. Blobs: Displays the plain contents stored in the blob file.
  2. Trees: Displays shows the filename and directory names stored within the tree file.
  3. Commits: Displays the commit information much as you’d see in Git log, plus a textual diff of the changes in that commit.
  4. Tags: Displays same thing as it does in (3) for commits, since a git tag is just a label for a commit.

Each of these Git object types can be queried using git show. This can be a very useful tool in your Git workflow. Now let’s discuss the usage and output in more detail.

Git Show Basic Usage

The basic syntax for git show is as follows:

git show <options> <object>

We’ll discuss some neat options later in the article. For now let’s focus on the <object> parameter.

The object parameter defaults to HEAD. Git HEAD usually references the most recent commit on the active branch, except in the case of a detached head state.

Therefore, if you run git show on its own (with no <object> specified), you will be querying the last commit on the current branch. Remember, a branch is just a named reference to a commit. You can think of a branch as a label that points to a particular commit that signifies the tip of that branch.

Here is an example of the default output when running the git show command:

> git show
commit 95ae37c781422885846a38535fde3bc19aa6659d (HEAD -> master)
Author: Initial Commit LLC <example@domain.com>
Date:   Sun Apr 10 00:36:24 2022 -0400

    test

diff --git a/dir1/dir1file1.ext b/dir1/dir1file1.ext
index e69de29..30d74d2 100644
--- a/dir1/dir1file1.ext
+++ b/dir1/dir1file1.ext
@@ -0,0 +1 @@
+test
 No newline at end of file

As mentioned, this is equivalent to running git show HEAD. The output provides a combined diff format. It tells us the commit details of the HEAD commit, along with a textual diff of the changes included in that commit. This can be useful when you want a git diff output in addition to the commit info supplied by git log.

In Git, commits and other objects such as blobs and trees can be referenced based on their unique ids. You are probably most familiar with the commit ids listed when running the git log command. Git generates these ids by compressing the content that makes up your changes and then hashing it with a SHA-1 hashing algorithm.

Some Git commands, including git show <object> can take any of these ids as arguments. When they do, they are referred to as revision parameters. This means that we can supply the command with the id of any SHA-1 identifier stored in Git’s database. It could be a commit id, blob id, or a tree id.

It could even be a label that points to one of the aforementioned id types. Those labels could be branch names (which are moving labels that point to branch tip commits), tags (which point to specific commits), or other refs like HEAD.

We could use git show with the revision parameter set as follows: git show 95ae37c. This would show the same output as what we saw above, since 95ae37c are the first few characters of the same commit pointed to by HEAD in the previous example.

Git will locate the proper object as long as your id is not ambiguous. This means you can supply the first few characters of your SHA-1 object id as the revision parameter instead of the whole unwieldy thing.

Let’s quickly illustrate the output when supplied with a blob, tree, and tag as revision parameters.

Here is an example of git show <blob id>. In this example, the SHA-1 supplied represents a blob file with the word “test” written inside. Note how the file content is simply printed:

> git show 30d74d2
test

If we supply a tree id instead, it will display the object type treefollowed by the filenames and directories pointed to by that tree (ie the tree’s “content”):

> git show 687294b
tree 687294b

dir1/
file1.ext
file2.ext

Notice that we were able to retrieve each type of object with its abbreviated SHA-1 hash. Since tag and branch names are simply labels that point to commits, they provide the same output as our commit example above.

If you want to view a range of commits, you can use the .. operator like: “git show 1c002dd..HEAD”. This will return the textual diff as well as other log data related to commits within the range of the two provided revisions. Be sure to enter the revisions in ascending order, or you’ll get you an empty return.

Git Show Options

Below we’ll list some common Git options you may find useful. This includes prettying up the command output, specifying the encoding, expanding tabs, and dealing with notes.

--pretty[=<format>]
--format=<format>

--abbrev-commit
Shortens the length of the commit ID for a smaller output.

--no-abbrev-commit
Overrides any abbreviated formats for commit ID and shows the full 40 character ID. 

--oneline
Displays output on a single line. A shortcut to the built-in pretty format:  --pretty=oneline --abbrev-commit

--encoding=<encoding>
Allows the modification of the default encoding from UTF8.

--expand-tabs=<n>
--expand-tabs
--no-expand-tabs
Replace tabs with spaces in the log message output. The value of n will determine how many spaces the tabs expand to. n defaults to 4 spaces.

--notes=<ref>
--no-notes
Hides note metadata attached to objects.

-s
Suppresses the diff output from showing.

The options for git show also include an extensive array of diff formatting options.

Git Show Pretty Formats

Git offers the --pretty option for us to style and customize the output. We’ll show a few useful built-in formatting options and some methods for customizing your own formats that will really clean up your results. Here’s the basic syntax:

--pretty[=<format>]
--format=<format>

There are two main differences between using –pretty and –format:

  1. If you omit any formatting options, –pretty = ” will default to the medium format. Using –format requires you to provide at least one argument.
  2. –pretty allows you to insert custom text, and create your own custom formats inside git config. –format will throw an error if you attempt to add custom text.

Here’s a list of the built-in pretty formats:

'oneline'
Commit
<sha1> <title line>
Designed to be compact and concise, showing only that SHA-1 hash and the title.


'short'
Commit <sha1>
Author: <author>
<title line>
Includes multiple lines

'medium'
Commit <sha1>
Author: <author>
Date:   <author date>
<title line>
<full commit message>

'full'
Commit <sha1>
Author: <author>
Commit: <committer>
<title line>
<full commit message>

'fuller'
Commit <sha1>
Author:     <author>
AuthorDate: <author date>
Commit:     <committer>
CommitDate: <committer date>
<title line>
<full commit message>

'email'
From <sha1> <date>
From: <author>
Date: <author date>
Subject: [PATCH] <title line>
<full commit message>

To specify the ‘full’ format, use the following syntax:

git show --pretty='full'

To create your own custom pretty format that suppresses the textual diff, shows the author’s name in blue, author’s email in red, and the abbreviated commit hash, you could use this:

> git show -s --pretty='format:Name: %Cblue %an %nEmail: %Cred %ae %n %CresetHash: %h'
Name:  Initial Commit LLC
Email:  example@domain.com
Hash: dcf54d3

Git Show Diff Formats

The git show command comes with a huge set of options for formatting the textual diff. Diff formatting isn’t just about refining your query to return only the specific diffs you want to see – there’s also the option to make stylistic changes as well.

For instance, the --diff-merges option will determine whether output of diffs for merge commits shows. The will impact the display depending on whether the developer makes merge commits:

> git show --diff-merges=off

While the --color option is a stylistic modifier that determines when textual diffs are colored:

> git show --color=never

You can generate a raw diff format using the --raw option:

> git show --raw
commit 5dd997613d5b278295d858a2c17de24f4d5fab88 (HEAD -> master, origin/master, origin/HEAD)
Author: Jacob Stopak <jacob@initialcommit.io>
Date:   Mon Apr 11 08:06:06 2022 -0700

    Bump version to 0.1.87

:100644 100644 d6147db 56d4459 M        pom.xml

This includes the usual commit info plus the added, modified, or deleted file mode.

Another cool option is the unified diff format --unified=nwhere n is the number of lines to show on each side of (above and below) the changed content:

git show --unified=10

The options for diff formatting are extensive. If you’d like to take a look at an exhaustive list, head over to the git show docs and have a closer look.

Git Show Examples

We’ve already gone over some examples of git show, but let’s take a closer look at the output and what it means. Consider the following Git project tree:

git-show-example/
file1.ext
file2.ext
dir1/
    file3.ext

For the initial commit, suppose all the files are empty except file1.ext, which simply has ‘sample text’ written inside. If we run the raw command, here’s our return:

> git show

commit 467b53a4bd661e86409fb90c6b9529bf84f7406b (HEAD -> master)
Author: Initial Commit LLC <example@domain.com>
Date:   Sat Apr 9 18:37:50 2022 -0400

    Initial commit.
diff --git a/dir1/dir1file1.ext b/dir1/dir1file1.ext
new file mode 100644
index 0000000..e69de29
diff --git a/file1.ext b/file1.ext
new file mode 100644
index 0000000..679aa53
--- /dev/null
+++ b/file1.ext
@@ -0,0 +1 @@
+sample text
 No newline at end of file
diff --git a/file2.ext b/file2.ext
new file mode 100644
index 0000000..e69de29

As you can see, the first four lines are our commit information: object type and id, author, date, and full commit message, in that order. Then, the textual diff begins.

Let’s replace the sample text with some code in file1.ext, commit the changes, then use git show and go over the diff output line by line. We will use the --oneline pretty format and the abbreviate commit option for truncating the details since our focus is on explaining the diff output:

> git show --abbrev-commit --pretty='oneline'

58f22e5 (HEAD -> master) Added sample function code.

diff --git a/file1.ext b/file1.ext
// The before and after file name, designated with the a and b, respectively, in the path.

index 679aa53..85f590d 100644
// The before and after blob revision, followed by the file mode (644 means executable)

--- a/file1.ext
// File that will have content removed.

+++ b/file1.ext
// File that will have content added.

@@ -1 +1,5 @@
// Lines to be removed and added.

-sample text
 No newline at end of file
// Actual content removed from file.

+function SampleFunction() 
+
+    console.log('Having fun!');
+
+
 No newline at end of file
// Actual content added to file.

We can gather some info from the diff output for another example. Earlier on we mentioned that you can use git show to query blob objects by their SHA-1 hash; let’s give that try:

> git show 85f590d 
function SampleFunction() 
    console.log('Having fun!');

As you can see, we successfully returned the contents of the blob, which reflects exactly what we last committed.

Now, let’s tag our latest commit. We’ll call our tag ‘v2.0’ and then try querying the tag using a few of our nifty formatting options we learned earlier:

Run the following command:

> git tag -a --abbrev-commit 'v2.0' -m 'Version 2.0 tag'
> git show 'v2.0' -s --abbrev-commit --pretty='oneline'

  tag v2.0

Version 2.0 tag
  58f22e5 (HEAD -> master, tag: v2.0) Added sample function code.

Awesome, we successfully returned some barebones metadata about the commit with by referencing the tag.

And last but not least, let’s check out an example of querying a tree object with git show. We already have our friendly named tag, so let’s query the tree pointed to by our tag and see what happens:

> git show v2.0^tree
tree v2.0^tree
 
dir1/
  file1.ext
  file2.ext

And there we have it – a successful return of all the files in our current tree.

How Can I See Commit Messages?

It is common to want to see only the full commit message associated with a commit. This can be done using the -s flag to suppress the textual diff and the --format=%s option to omit all commit details except for the commit log message:

> git show -s --format=%s
Added sample function code.

How Do I See All My Commits?

The git log command is best suited for listing all commit messages in your Git repo.

> git log --format=%s
Added sample function code.
Initial commit.

Git show is built to provide a more specific snapshot of the git repo history, for a specific object or range of objects. If you’d like to see a range of commit messages, this could be done using the .. operator we mentioned earlier. But it’s likely easier to use git log for this.

What is the Difference Between Git Log and Git Show?

The git show and git log commands are quite similar and have some overlapping features. The differences exist because they were created for slightly different purposes. The default behavior of git log gives a broader snapshot than git show does.

For example, a simple git log command displays a full log including details of every commit in your Git repository. On the other hand, git show displays only the last commit made in the repo and will include the textual diff by default.

Both commands have the ability to return a range of commits using the .. and ... operators. They can also both return textual diff. However, the default behavior of each is what you should consider when choosing which tool to use.

A good rule of thumb is that if you need a detailed look at one commit or small range of commits (or other individual Git objects), go with git show. Otherwise, you may consider using git log.

Summary

We’ve taken a comprehensive look at git show, a Git CLI tool used for returning detailed data on specific git objects or a range of git objects such as commits and blobs. This command defaults to returning the textual diff of commits, which makes it well suited for viewing code changes and reviewing patches within your repo.

We took a look at several formatting options, along with placeholders for customizing your output. We also discussed some of the ways you can customize the textual diff returned.

Although git log and git show are very similar tools, we demystified the overlapping capabilities of these two tools, and explained when one or the other is a more appropriate choice.

Using this command like a pro will enhance your understanding of Git and version control, and might impress some friends along the way!

Next Steps

If you’re interested in learning more about how Git works under the hood, check out our Baby Git Guidebook for Developers, which dives into Git’s code in an accessible way. We wrote it for curious developers to learn how Git works at the code level. To do this we documented the first version of Git’s code and discuss it in detail.

We hope you enjoyed this post! Feel free to shoot me an email at jacob@initialcommit.io with any questions or comments.

References

  1. Git SCM Command Docs – https://git-scm.com/docs/git-show
  2. Git SCM Git Revisions Docs – https://git-scm.com/docs/gitrevisions

Source

LEAVE A REPLY

Please enter your comment!
Please enter your name here