.. title: Git! Branching and Merging
.. date: 2019-08-01
.. slug: git-branching-and-merging
.. updated: 2019-08-01
.. status: published
.. tags: git, revision-control
.. category: revision-control
.. authors: Elia el Lazkani
.. description: Explaining branches, branching and merging strategies.
.. type: text

In the previous post about ``git``, we had a look at what ``git`` is and got our feet wet with a bit of it.
In this post, I will be moving forward with the topic, I will be talking about branches, how to work with them and finally what merging is and how it works.

.. TEASER_END

Requirements
============

The same requirement we had from the last post, obviously ``git``.

Branching and Merging
=====================

What is a branch?
-----------------

``git`` `documentation <https://git-scm.com/book/en/v1/Git-Branching-What-a-Branch-Is>`_ describes it as:

    "A branch in Git is simply a lightweight movable pointer to one of the[se] commits."

Usually, people coming from *svn* think of **branches** differently. In ``git``, a branch is simply a pointer to a commit.

So let's verify that claim to see if it's true.

Remember our example repository from the last post ? We'll be using it here.

First let's create a new branch.

.. code:: text

   $ git checkout -b mybranch
   Switched to a new branch 'mybranch'

That was simple, wasn't it ?
Alright, let's test our hypothesis.

.. code:: text

   $ git log
   commit 643a353370d74c26d7cbf5c80a0d73988a75e09e (HEAD -> mybranch, master)
   Author: John Doe <johndoe@example.com>
   Date:   Thu Aug 1 19:50:45 2019 +0200

       Second commit

The commit is, of course, different because this is a different computer with a different repository from scratch. Anyway, it seems from the log message that both *mybranch* and *master* are pointing to same commit ``SHA``. Technically they are pointing to **HEAD**.

Now let's continue and add a new commit.

.. code:: text

   $ echo "" >> README.md
   $ git add README.md
   $ git commit -m "Adding an empty line"
   [mybranch b30f4e0] Adding an empty line
    1 file changed, 1 insertion(+)

After this last commit, let's check the log

.. code:: text

   $ git log
   commit b30f4e0fa8f3b5c9f041c9ad1be982b2fed80851 (HEAD -> mybranch)
   Author: John Doe <johndoe@example.com>
   Date:   Thu Aug 1 20:28:05 2019 +0200

        Adding an empty line

    commit 643a353370d74c26d7cbf5c80a0d73988a75e09e (master)
    Author: John Doe <johndoe@example.com>
    Date:   Thu Aug 1 19:50:45 2019 +0200

        Second commit

From reading the output of log, we can see that the *master* branch points to a different commit than *mybranch*.

To visualize this, let's look at it in a different way.

.. code:: text

   $ git log --graph --oneline --all
   * b30f4e0 (HEAD -> mybranch) Adding an empty line
   * 643a353 (master) Second commit

What the above suggests is that our two branches have different contents at this stage. In other words, if I switch back to the *master* branch what do you think we will find in ``README.md`` ?

.. code:: text

   $ git checkout master
   Switched to branch 'master'
   $ cat README.md
   # Example

   This is an example repository.
   This repository is trying to give you a hands on experience with git to complement the post.
   $

And if we switch back to *mybranch*.

.. code:: text

   $ git checkout mybranch
   Switched to branch 'mybranch'
   $ cat README.md
   # Example

   This is an example repository.
   This repository is trying to give you a hands on experience with git to complement the post.

   $


Let's add another commit to make easier to see the changes than an empty line.

.. code:: text

   $ echo "Let's add a line to mybranch." >> README.md
   $ git add README.md
   $ git commit -m "Adding more commits to mybranch"
   [mybranch f25dd5d] Adding more commits to mybranch
    1 file changed, 1 insertion(+)

Now let's check the tree again.

.. code:: text

   $ git log --graph --oneline --all
   * f25dd5d (HEAD -> mybranch) Adding more commits to mybranch
   * b30f4e0 Adding an empty line
   * 643a353 (master) Second commit

Let's also check the difference between our *master* branch and *mybranch*.

.. code:: text

   $ git diff master mybranch
   diff --git a/README.md b/README.md
   index b4734ad..f07e71e 100644
   --- a/README.md
   +++ b/README.md
   @@ -2,3 +2,5 @@

    This is an example repository.
    This repository is trying to give you a hands on experience with git to complement the post.
   +
   +Let's add a line to mybranch.

The ``+`` suggests an addition and ``-`` suggests a deletion of a line. As we can see from the ``+`` shown before the two lines added to the ``README.md`` file, *mybranch* has these additions.

You can read more about ``git`` branches in the ``git`` `documentation <https://git-scm.com/book/en/v1/Git-Branching-What-a-Branch-Is>`_ page.

What is merging ?
-----------------

That's all fine so far, but how do I get these changes from *mybranch* to the *master* branch ?

The answer to that is also as easy as all the steps taken so far. ``git`` merges **from** a branch you specify **to** the branch you are currently on.

.. code:: text

   $ # Checking which branch we are on
   $ git branch
     master
   * mybranch
   $ # We are on mybranch and we need to put these changes into master
   $ # First we need to move to our master branch
   $ git checkout master
   Switched to branch 'master'
   $ # Now we can merge from mybranch
   $ git merge mybranch
   Updating 643a353..f25dd5d
   Fast-forward
    README.md | 2 ++
    1 file changed, 2 insertions(+)

As we can see. The changes in *mybranch* have been merged into the *master* branch.

.. code:: text

   $ git log
   commit f25dd5da3e6f91d117177782a5811d5086f66799 (HEAD -> master, mybranch)
   Author: John Doe <johndoe@example.com>
   Date:   Thu Aug 1 20:43:57 2019 +0200

       Adding more commits to mybranch

   commit b30f4e0fa8f3b5c9f041c9ad1be982b2fed80851
   Author: John Doe <johndoe@example.com>
   Date:   Thu Aug 1 20:28:05 2019 +0200

       Adding an empty line

   commit 643a353370d74c26d7cbf5c80a0d73988a75e09e
   Author: John Doe <johndoe@example.com>
   Date:   Thu Aug 1 19:50:45 2019 +0200

       Second commit

Merging Strategies
==================

I'll explain to you how I like to work and my personal merging strategy. I will keep out some details as they use concepts that are more advanced than what has been discussed so far.

*master* branch
---------------

To me, the *master* branch stays always up to date with the **remote** *master* branch. In other words, I do not make commits against the *master* branch in the project I'm working on.

branch
------

If I want to work on the project, I start by updating the *master* branch and then branching it as we've seen before. The name of the branch is always indicative on what it holds, or what kind of work I am doing on it.

As long as I am working on my dev branch, I keep updating the *master* branch and then porting the changes into my dev branch. This way, at the end the code is compatible and I am testing with the latest version of the code. This is very helpful and makes merging later a breeze.

merging
-------

After my work is done, I push my branch to the remote server and ask for the maintainer of the project to merge my changes into the *master* branch after reviewing it, of course. To explain this in a very simple manner, all that mumbo jumpo talk previously simply means someone else did the merge into master.


Conclusion
==========

In this post, I talked about what are branches. We went ahead and worked a little bit with branches and then mentioned merging. At the end of the post I talked a bit about my merging strategy.

In the next post, I will be talking about remotes.
