Git Basics. Working with Branches
This tutorial was commissioned as a test task: create a Git introduction based on a YouTube video. View it nicely formatted at https://arterm-sedov.gitbook.io/git-tutorial-sample/
Introduction
Prerequisites
This tutorial assumes knowledge of the following foundational topics:
Git commit
Working tree
Staging area
Creating a Git repo
These and several other essential topics are covered in the following video: Introduction to Git — Core Concepts
For more details on using Git, you can also refer to the Pro Git book by Scott Chacon: https://git-scm.com/book/en/v2
This tutorial also relies on Vim text editor commands, while you can use your preferred editor.
Setting up a Git Repo
To complete this tutorial you will need to create a Git repo and add some text files to work with version control.
For the tutorial, we will create a repo with a fake network automation project consisting of one folder: netauto
, and two files: S1
and S2
.
Start a new git repo, using the following commands in your terminal:
Create a file named
S1
:
Enter the following content in the
S1
file and save it:
Stage and commit the
S1
file:
Duplicate the
S1
file to theS2
file.Stage and commit the
S2
file:
Check your two commits:
Check Git status:
You should see that Git created and named the master
branch automatically in your new repo.
Branch Definition
Branches separate different versions of the same files and allow you to work on them in parallel.
Edits on one branch are independent of work on other branches. This allows you to have branches for different purposes: a production branch, a development branch, and a bug-fix branch.
You can incorporate or merge changes from a branch into other branches.
To understand how a branch is implemented let's see its visual representation in the commit graph.
The diagram below shows the newly created repo with two commits. See Setting up a Git Repo.
A Git branch is essentially a pointer to a 40-digit hexadecimal SHA-1 hash of a commit. In this tutorial, we will refer to the first 7 characters of these hashes.
When you are on a certain branch, every time you make a commit, the branch moves up to your latest commit.
HEAD Definition
Git knows which branch you are using a special pointer called HEAD.
HEAD normally points to a branch and not directly to a commit. Sometimes HEAD is called a symbolic pointer.
So far, you only have the first branch: master
, and HEAD points to it.
In Git terminology, the HEAD pointer tells you what you have checked out.
So from the diagram above you can see that the master branch is checked out.
To see the labeled commit graph in the terminal use some additional options with the git log
command:
This command shows that you are on the second commit due to the HEAD pointer. The HEAD pointer is pointing to the master
branch. This tells that you have the master
branch checked out.
Tip
You can save the git log --all --decorate --oneline --graph
command as an alias called graph
for future use:
Creating Branches
To create new branches use the git branch <branch_name>
command.
The branches will be instantiated where the HEAD pointer is.
Start two new branches:
SDN
andauth
.View all branches using the
git branch
command.
You now have three branches: master
, auth
, SDN
.
There is an asterisk next to the master branch, and it is green. This indicates that you have the master
branch checked out. More precisely, the HEAD pointer points to the master branch.
View the decorated commit graph:
You can see all three branches pointing to the same commit: create S2
.
The HEAD is attached to the master
branch since you have the master
branch checked out.
Checking out and Working on Branches
You have three branches: master
, SDN
, and auth
.
Checkout the
SDN
branch and view the commit graph and Git status:
When you checked out the SDN
branch, the HEAD pointer moved to point to the SDN
branch. Now the graph
alias command shows HEAD has moved and points to SDN
. The git status
command shows the same.
While you're are on the
SDN
branch, edit theS1
file by adding an SDN controller IP (for example, using thevi S1
command):
Stage and commit that change:
Since you have the SDN
branch checked out, only the SDN
branch moved up to the new commit. The master and auth branches stay where they are: at the previous commit.
See the newest change, the SDN controller IP is there:
Now let's work on the
auth
branch and see the resulting commit graph:
The checkout
command moved the HEAD pointer from SDN
to auth
.
See that the newly added
sdn_controller
line is not present anymore in theS1
file using thecat S1
command.
Git replaced your working tree and staging area to match the commit the auth
branch is associated with. At this earlier commit, you don't have the SDN controller change.
While on the
auth
branch, make a different change to theS1
file to map the S1 switch to an authentication server:
See that you've modified the
S1
file in the working tree:
Stage and commit that change using a shortcut option
-a
with thegit commit
command, that stages all tracked files, that have been modified:
View the resulting commit graph:
You have created a new commit, and only the auth
branch moved to it.
You have started at the SDN for S1
commit. Master is still pointing to this commit.
From this base, you branched out in two different directions:
You have checked out the
SDN
branch and added an SDN controller IP.Then you checked out the
auth
branch and added an authentication server IP.
You have ended up with 3 branches: auth
, SDN
, and master
, pointing to different commits.
The content of the S1
file will be different depending on which branch you checkout.
Merging branches
Now let's say your work is done on the SDN
and auth
branches, and you want to integrate these changes back into the master
branch: to merge your new changes into the master
branch.
We will talk about two types of merges:
Fast-Forward Merge
Let's get the SDN controller config into your master
branch.
To merge SDN into master, use the git merge
command.
The commit where you added the SDN controller is 6889e71
. The SDN
branch is pointing to it.
This commit's parent is 4fe9c36
. This is where the master
branch is.
Since there is a direct path from master
to SDN
, Git can perform a so-called fast-forward merge.
During the fast-forward merge Git just moves the master
branch to where SDN
is: the master
just has to catch up with the SDN
.
Even if there were multiple commits between the two branches, there is still a fast-forward merge: you just need a direct path.
Check the status to see that you're still on the
auth
branch.Check out the
master
branch.See, shows what will change when you merge
SDN
intomaster
:
The git diff
command shows that the S1
file in the master
branch will get the sdn_controller
line from the SDN
branch.
From the master branch merge SDN, see the resulting
S1
file and graph:
Git confirms you have done a fast-forward merge.
Git has added one line to S1, and cat S1
shows this.
With the graph
alias command, you see that the master
branch is caught up with the SDN
branch: Git has moved the pointer to the same commit where SDN
is.
As you don't need two branches pointing to the same commit, you can delete the
SDN
branch. See Deleting Branches.
3-Way Merge
Now that you've merged and deleted the SDN
branch let's do the same for the auth
branch.
Looking at the commit graph, you can see there is no direct path from the master
branch to the auth
branch. Git can not do a fast-forward merge this time. For this case, a 3-way merge will happen.
To merge master
and auth
, you can't just move the master
pointer to the ff29a74
commit. If you did that, you would lose the SDN
changes made in the 6889e71
commit.
You need to merge these branches into a new commit called a merge commit. To make this merge commit, Git looks at three commits:
First, the base commit
4fe9c36
the two branches started from.Then the last commit of each branch:
ff29a74
and6889e71
.
Check Git status, merge the
auth
branch, and see the resulting graph:
The output does not say fast-forward
merge like when merging the SDN
branch. Now it says “Merge made by the 'ort' strategy.”
The graph
alias command shows the merge commit bf80100
joining the two branches.
Now check that you can safely delete the auth branch and delete it:
Deleting Branches
You can safely delete merged branches keeping all changes to their files.
You can also force-delete unmerged branches losing all their changes.
Before deleting the branch see what commits are merged into it:
The SDN branch was merged earlier, so you can delete it:
If you try to delete a branch that was not yet merged, Git will not allow this:
To delete the branch that was not merged and lose all its changes use the upper case
-D
option:
Git Command Reference
git log
— view git history.git log --all --decorate --oneline --graph
— view commit history graph.git branch <branch-name>
— create a branch.git checkout <branch-name>
— checkout a branch/move head pointergit commit -a -m "commit message"
— commit all modified and tracked files in one command (bypass separategit add
command).git diff master..SDN
— diff between 2 branches.git merge <branch-name>
— merge branches (fast-forward and 3-way merges).git branch --merged
— see branches merged into the current branch.
Last updated