Here is an (evolving) explanation of illustrating how Git refers to commits and branches
The text to the video (below it) provides additional tips not shown in the video.
NOTE: This is an early version and is undergoing revision now.
PROTIP: Print this picture and pin it on a wall for reference.
The most amazing thing about Git as a source version management system is that I can have the working directory of my repository be restored to any specific point in time.
I’ve seen a lot of ways people explain this in a way that … confused me.
So let me know if the following helps you better understand time travel using Git.
I show this DC Comics character, Flash (copyright DC Comics), running “super-fast” toward us because I see an analogy.
The sequence of images represent different versions of the same person, but at different points in time.
Each version is visually a little bigger as it gets closer to our viewpoint. The body closest to us is the most recent version. In Git, that most recent version is called HEAD.
The at sign (@) is a shortcut for HEAD.
Versions before HEAD we can reference in Git using a number of HEAD references with a caret or “hat” character.
Such references are what Git calls “commit-ish” because Git maintains versions using a chain of “commits”, a term borrowed from SQL database commands for saving a set of data.
The initial commit was established by a git init command which creates the database of version information. From there, a physical chain of commits leads us to the present, in a series of “parent” to “child” links.
- The first commit is the only one that does not have a parent. To obtain the hash of such commits: *
git rev-list --max-parents=0 HEAD
These ordinal number references can be used instead of carets in HEAD specifications.
This linkage is the mechanism that enables Git to tell us the difference of text content between two commits, of what has changed between two points in time.
git diff HEAD..HEAD~3
When we make a new commit, it’s added in front of the current HEAD and Git automatically points HEAD to that new commit.
Notice all the HEAD references have been re-numbered.
We issue the git checkout command to have Git magically re-establish our working directory as it was at a past moment in time.
Getting back to my analogy, new commits are added after text in a file is saved.
Let’s step back for minute. Commits are created to a branch “Master” is the default branch. «<
But we can alternatively issue a checkout command to define a new branch (called “branch1”) as the current branch, then new commits would be added to that branch.
This is how separate “parallel universes” can exist at the same time.
The git merge command combines changes made into a new commit under the long-running master branch.
Then the working branch can be deleted.
Git Flow Branches
These actions are the mechanisms used in what’s called the Git workflow.
The master branch is typically used for what is on production servers.
If there is an emergency hotfix needed, a hotfix branch is created.
A develop branch is used to develop the next release, and merging with the hotfix when appropriate.
Once it’s working, the feature branch is merged and be part of a release branch used for system QA testing.
Create a hotfix branch, then merge it into the release branch and integration branch.
Alternate picture: https://www.pinterest.com/pin/394627986075737189/
This is one of a series on Git and GitHub:
- Why Git? (file-based backups vs Git clone)
- Git Markdown text
- Git-client based workflows
- Git whoops (correct mistakes)
- Git rebase
- Git interactive merge (imerge)
- Git HEAD (Commitish references)
- Git custom commands
- Git utilities
- TFS vs GitHub
- GitHub REST API
- GitHub GraphQL API
- GitHub PowerShell API Programming
- GitHub GraphQL PowerShell Module