In this tutorial, you will learn how to:
mainBefore we get started, we’re going to create a git alias to
conveniently run git log with options that will display a
succinct graphical view of all branches in our repo:
git config --global alias.graph "log --all --graph --oneline --decorate"
Open your terminal to your blog repo
(cd blog), and try running it:
git graph
q to exit git graph)main branch and the
origin/main remote branch.
HEAD label pointing to your
main branch.
HEAD indicates the branch that our repo has
checked-out, which has two key implications:
HEAD represents the current version of the files in our
directory - any file changes will be compared to HEADgit commit, the new commit will have the
current HEAD commit as its parent, and the
HEAD branch will be updated to point to the new commit
HEAD like the head on a spinning hard disk -
it points to the data that is currently being read or written.origin/HEAD, which just indicates the
default branch for new clones of the origin
remote.We can keep our work isolated from the main branch while
it is still a work-in-progress by committing to a separate branch.
To do so, let’s create a new branch for some additions to the README:
git branch readme-additions
We can see our newly created branch in the graph; it points to the
same commit as whatever branch HEAD was pointing to:
git graph
Now let’s check-out our new branch:
git switch readme-additions
We can confirm our current branch by again checking the graph and
also by checking git status:
git graph
git status
Now let’s make some changes on our new branch, open up the README:
nano README.md
And add more information at the bottom of the file:
## Built with
* Markdown
Save and exit nano (Ctrl + x,
y, Enter), then add and commit the README:
git status
git add README.md
git status
# We'll use a shortcut to write the message inline
git commit -m "Add tool info to README"
git status
Now let’s see what that’s done to the graph:
git graph
Success! The new commit has been added to the
readme-additions branch, but not main.
Now let’s switch back to the main branch, again
confirming the change to HEAD in the graph and status:
git switch main
git graph
git status
When we look at the log from main, we don’t see that
commit:
git log
And when we look at the README, we don’t see our latest additions:
cat README.md
mainNow that we’ve finished the work on our feature branch let’s
merge it back into main.
This is as simple as running:
git merge readme-additions
main, so we will be
updating the main branch by merging in
readme-additionsNow let’s see what that’s done to the graph:
git graph
We can see that main has been updated to the same commit
as readme-additions, and the README on main
now has the additions:
cat README.md
Notice that Git told us this was a fast-forward merge:
main branch with the latest commits fetched from
origin/main.Let’s see what happens when a fast-forward merge is not possible.
First off, let’s undo that previous merge by resetting the
main branch to point to the same commit as
origin/main again:
git reset --hard origin/main
git graph
IMPORANT: git reset is a dangerous
command because it can delete both commits and uncommitted changes.
We’ll learn more about it in the next lesson.
Now let’s add a commit directly to the main branch, as
if someone else had merged in some changes while we were still working
on readme-additions:
nano README.md
Change the README’s title to something else:
# My Awesome Blog
Save and exit nano (Ctrl + x,
y, Enter), then add and commit the README:
git status
git add README.md
git status
# We'll use a shortcut to write the message inline
git commit -m "Update README title"
git status
Now let’s look at the graph:
git graph
main that doesn’t exist in
readme-additionsmain cannot be fast-forwarded to
readme-additionsgit log can be used to check which commits exist
in one branch but not another with the “two dots” syntax:# Commits in readme-additions but not main
git log main..readme-additions
# Commits in main but not readme-additions
git log readme-additions..main
Now what happens when we merge :
git merge readme-additions
Ctrl + x,
y, Enter)Now check the graph:
git graph
main branch has been updated to point to the new
merge commit.So what does the README look like now on the main
branch?
cat README.md
Because each branch had made changes to different parts of the same file, Git was able to combine both sets of changes into a single file without us having to do anything!
But what if both branches had changed the same part of the same file?
Let’s find out!
Again, let’s undo the previous merge and the commit we made on
main by resetting the main branch to
point to the same commit as origin/main again:
git reset --hard origin/main
git graph
Now let’s make a commit directly on main again, but this
time editing the same part of the file as our commit on
readme-additions:
nano README.md
Add some different content to the bottom of the file:
## Thanks
* Git
Save and exit nano (Ctrl + x,
y, Enter), then add and commit the README:
git status
git add README.md
git status
# We'll use a shortcut to write the message inline
git commit -m "Add thanks to README"
git status
Look at the graph, and you should see the branches diverging again:
git graph
Now let’s see what happens when we try to merge
readme-additions into main:
git merge readme-additions
git status
README.md is an unmerged path where
both branches made modificationsgit diff README.md
HEAD, which is
main)readme-additions)git merge --abortq to exit git diff)nano README.md
To resolve this conflict, let’s remove the conflict markers and combine the two changes into one:
## Thanks
* Git
* Markdown
nano (Ctrl + x,
y, Enter)git status:git status
The README is still unmerged, let’s check git diff
again:
git diff README.md
readme-additions will effectively lose
Built with but gain Thanks and
Gitmain will effectively gain
MarkdownWe can now add our resolution:
git add README.md
git status
The resolution is now staged and ready to be committed, so let’s complete the merge with a merge commit:
git commit
Ctrl + x,
y, Enter)git status
git graph
To wrap-up, let’s undo the last merge and commit on
master by resetting again:
git reset --hard origin/main
git graph
main
in order to avoid unnecessary merge commits.