In this tutorial, you will learn how to:
main
Before 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 HEAD
git 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
main
Now 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-additions
Now 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-additions
main
cannot be fast-forwarded to
readme-additions
git 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 --abort
q
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
Git
main
will effectively gain
Markdown
We 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.