Git-Mastery: Lessons

T1L6. Examining the Revision History


It is useful to visualize the commit timeline, called the revision graph.

This lesson covers that part.

Git commits form a timeline, as each corresponds to a point in time when you asked Git to save a snapshot of the tracked files prepared in the staging area. Except for the initial commit, each commit links to at least one previous commit, forming a structure that we can traverse.
A timeline of commits can have a name. Such a named timeline is called a branch. By default, Git names the initial branch master -- though many now use main instead. You'll learn more about branches in future lessons. For now, just be aware that the commits you create in a new repo will be on a branch called main (or master) by default.

gitGraph
    %%{init: { 'theme': 'default', 'gitGraph': {'mainBranchName': 'main (or master)'}} }%%
    commit id: "Add fruits.txt"
    commit id: "Update fruits.txt"
    commit id: "Add colours.txt"
    commit id: "..."

Git can show you the list of commits in a repo's history.

HANDS-ON: Viewing the list of commits

Preparation

Option 1: Create a fresh sandbox using the Git-Mastery app

  • Navigate inside the gitmastery-exercises folder.
  • Run the gitmastery download hp-list-commits command.

The sandbox will be set up inside the gitmastery-exercises/hp-list-commits folder.


Option 2: Continue with the sandbox from the previous hands-on practical

1 View the list of commits, which should show only the commit you just created.

 CLI

Navigate into the repo folder and run the git log command to see the commit history.

cd hp-list-commits/things
git log
commit ... (HEAD -> main)
Author: ... <...@...>
Date:   ...

Add fruits.txt

Use the Q key to exit the output screen of the git log command.

Note how the output includes details about the commit you just created. You can ignore most of them for now, but notice that it also shows the commit message you provided.

Sourcetree

Expand the BRANCHES menu and click main to view the history graph, which contains only one node at the moment, representing the commit you just added. For now, ignore the label main attached to the commit.

2 Create a few more commits (i.e., a few rounds of add/edit files → stage → commit), and observe how the list of commits grows.

 CLI

Here is an example list of bash commands to add two commits while observing the list of commits after each commit.

echo "figs" >> fruits.txt  # add another line to fruits.txt
git add fruits.txt  # stage the updated file
git commit -m "Insert figs into fruits.txt"  # commit the changes
git log  # check commits list

echo "a file for colours" >> colours.txt  # add a colours.txt file
echo "a file for shapes" >> shapes.txt  # add a shapes.txt file
git add colours.txt shapes.txt  # stage both files in one go
git commit -m "Add colours.txt, shapes.txt"  # commit the changes
git log  # check commits list

You can copy-paste a list of commands (such as the commands above), including any comments, to the terminal. After that, press Enter to run them in sequence.

zsh users: If the terminal reports an error because of comments starting with #, you may need to enable the interactive comments feature in your terminal (e.g., add the line setopt INTERACTIVE_COMMENTS to your ~/.zshrc).

The output of the final git log should be something like this:

commit ... (HEAD -> main)
Author: ... <...@...>
Date:   ...

    Add colours.txt, shapes.txt

commit ...
Author: ... <...@...>
Date:   ...

    Insert figs into fruits.txt

commit ...
Author: ... <...@...>
Date:   ...

    Add fruits.txt

SIDEBAR: Working with the 'less' pager

Some Git commands -- such as git log -- may show their output through a pager. A pager is a program that lets you view long text one screen at a time, so you don't miss anything that scrolls off the top. For example, git log output will temporarily hide the current terminal content and enter a pager view that shows the output one screen at a time. When you exit the pager, the git log output will disappear from view, and the previous content of the terminal will reappear.

command 1
output 1

git log


commit f761ea63738a...
Author: ... <...@...>
Date:   Sat ...

    Add colours.txt

By default, Git uses a pager called less. Below are some useful commands for the less pager.

Command Description
q Quit less and return to the terminal
or j Move down one line
or k Move up one line
Space Move down one screen
b Move up one screen
G Go to the end of the content
g Go to the beginning of the content
/pattern Search forward for pattern (e.g., /fix)
n Repeat the last search (forward)
N Repeat the last search (backward)
h Show help screen with all less commands

If you'd rather see the output directly, without using a pager, you can add the --no-pager flag to the command, for example:

git --no-pager log

You can also configure Git not to use less, to use a different pager, or to fine-tune how less behaves. For example, you can reduce Git's use of the pager (recommended) by using the following command:

git config --global core.pager "less -FRX"

Explanation: -FRX is shorthand for combining the following three flags.

  • -F : Quits if the output fits on one screen (don't show pager unnecessarily)
  • -R : Shows raw control characters (for colored Git output)
  • -X : Keeps content visible after quitting the pager (so output stays on the terminal)
Sourcetree

To see the list of commits, click on the History item (listed under the WORKSPACE section) on the menu on the right edge of Sourcetree.

After adding two more commits, the list of commits should look something like this:

done!

The Git data model consists of two types of entities: objects and refs (short for references). In this lesson, you will encounter examples of both.

A Git commit graph (also called a revision graph) is a visualization of a repo's revision history, consisting of one or more branches. First, let us work with a simpler revision graph that has one branch, such as the one below.

C3
|
C2
|
C1

  • Nodes in the revision graph represent commits. A commit is one of four main types of Git objects. For completeness, the other three are:
    • blob (short for binary large object): stores the contents of a file
    • tree: represents a directory and records the hierarchy of its contents by referencing blobs and other trees
    • tag (specifically, annotated tag): a label-like object that can store additional metadata and point to a specific commit
  • A commit is identified by its SHA value. A SHA (Secure Hash Algorithm) value is a unique identifier generated by Git to represent each commit. In the usual Git repository format, it is produced by applying SHA-1 (i.e., one of the algorithms in the SHA family of cryptographic hash functions) to the contents of the commit object. It's a 40-character hexadecimal string (e.g., f761ea63738a67258628e9e54095b88ea67d95e2) that acts like a fingerprint, ensuring that every commit can be referenced unambiguously. That is, every commit has a unique hash value. Tell me more about the use of SHA
  • A commit is a full snapshot of all tracked files, based on the versions prepared in the staging area at commit time. That means each commit (except the initial commit) is based on another 'parent' commit. Some commits can have multiple parent commits -- we'll cover that later.

Because every commit has a unique hash, the commit hash values in our examples will differ from your own commit hash values when you follow our hands-on practicals.

Edges in the revision graph represent links between a commit and its parent commit(s). In some revision graph visualizations, you might see arrows (instead of lines) showing how each commit points to its parent commit.

C3
C2
C1

Git uses refs to name and keep track of various points in a repository's history. These refs are essentially named pointers that can serve as bookmarks to reach a certain point in the revision graph using the ref name.

C3 mainHEAD
|
C2
|
C1

In the revision graph above, there are two refs main and  HEAD.

  • main is a branch ref. A branch ref points to the latest commit on a branch. In this visualization, the commit shown alongside the ref is the one it points to, i.e., C3.
    When you create a new commit, the branch ref of the branch moves to the new commit.
    You'll be learning more about Git branches in a later lesson.
  • HEAD is a special ref that typically points to the current branch and moves along with that branch ref. In this example, it is pointing to the main branch.
    In certain cases, the HEAD may point directly to a specific commit instead of a branch. This situation is called a 'detached HEAD'; a later lesson covers it.
HANDS-ON: View the revision graph

Target Use Git to examine the revision graph of a simple repo.

Preparation

Option 1: Create a fresh sandbox using the Git-Mastery app

  • Navigate inside the gitmastery-exercises folder.
  • Run the gitmastery download hp-view-graph command.

The sandbox will be set up inside the gitmastery-exercises/hp-view-graph folder.


Option 2: Continue with the sandbox from the previous hands-on practical

 CLI

1 First, use a simple git log to view the list of commits.

git log
commit f761ea63738a... (HEAD -> main)
Author: ... <...@...>
Date:   Sat ...

    Add colours.txt, shapes.txt

commit 2bedace69990...
Author: ... <...@...>
Date:   Sat ...

    Insert figs into fruits.txt

commit d5f91de5f0b5...
Author: ... <...@...>
Date:   Fri ...

    Add fruits.txt

Below is the visual representation of the same revision graph. As you can see, the log output shows the refs slightly differently, but you can still match them to the same refs.

C3 mainHEADAdd colours.txt, shapes.txt
|
C2Insert figs into fruits.txt
|
C1Add fruits.txt

2 Use the --oneline flag to get a more concise view. Note how the commit SHA has been truncated to the first seven characters (the first seven characters of a commit SHA are enough for Git to identify a commit).

git log --oneline
f761ea6 (HEAD -> main) Add colours.txt, shapes.txt
2bedace Insert figs into fruits.txt
d5f91de Add fruits.txt

3 The --graph flag makes the result closer to a graphical revision graph. Note the * that indicates a node in a revision graph.

git log --oneline --graph
* f761ea6 (HEAD -> main) Add colours.txt, shapes.txt
* 2bedace Insert figs into fruits.txt
* d5f91de Add fruits.txt

The --graph option is more useful when examining a revision graph with multiple parallel branches (branches will be covered in a later lesson).

Sourcetree

Click History to see the revision graph.

  • In some versions of Sourcetree, the HEAD ref may not be shown -- it is implied that the HEAD ref points to the same commit as the current branch ref.

done!

EXERCISE: log-and-order