Git Branching and Merging

Branching: Branching is a new feature which is available in the modern version control system, The branch is used to store the history of commits.

Merging: Merging is nothing but combining the sequences of different commits into a unified commits history, is called as merging the branches.



Forking and Cloning with Git

Basics concept of Branching

Branching is a new feature which is available in the modern version control system, The branch is used to store the history of commits.

Git is having default branch called the master branch, we can create a new branch with an existing branch, we normally use a specific tag or commits as a starting point.

If we won't specify any starting point, then the branch is created with HEAD as its starting point. Where every branch is referenced by HEAD, which points to the latest commit in the branch.

Whenever you make a commit, HEAD is updated with the latest commit, Usually, a branch is used to work on the new feature, once the feature is completed we will merge back to the master branch.

  • So let's open Git Bash command prompt and go to the project folder and then move to your Git repository.
  • The best practice is to do a git status before starting with the new project.
  • Hence Git will tell us that we are on a clean working directory and you can also see that, we are on the master branch and also that we are currently up-to-date with the origin/master.
    BCB-git-status

So, here we are creating a new feature branch and once the feature is completed, we are integrating back to the master branch.

To start off with the branches first, am going to list out all the branches which are present in our Git repository by using git branch -a.

Where "-a" parameter will list out all the branches including both Local and the Remote branches and git branch will recognize the current active branch by putting an asterisk before the branch name.
BCB-git-branch-a

To create a new branch, we will use the command git branch <new branch name>, I am going to create a new branch called mynewbranch, git branch mynewbranch


So if you pass the command git branch -a, it will list the new branch, and the asterisk is still on the master branch only, so to switch that we will use the checkout command.
BCB-creating-mynew-branch

So, let's use git checkout mynewbranch, it will switch branch to the mynewbranch, and then the asterisk will move on to mynewbranch.
BCB-switch-mynewbranch

Now you can see the whole history by using the command, git log --oneline --decorate , If you observe, the first commit which is listed here is the last commit with several labels associated with it, like HEAD, which usually points to the last commit on the current branch.

And also we have origin/master, origin/head, mynewbranch, and the master branch, Here HEAD and origin/head points to the last commit on their respective branches in both Remote and Local.

Master branch is the branch where we are working with from long and mynewbranch is just now we had created Since we have not made any changes and hence all the branch labels are pointing to the same commit.
BCB-oneline

The branches are just pointers and new branch won't start without any particular commits other than from master.

Hence we are going back to the master branch by using the git checkout command as, git checkout master
BCB-git-checkout-master

We can also rename the branch by using the command line, git branch -m where "-m" move old branch name to the new branch name like from mynewbranch to newbranch git branch -m mynewbranch newbranch, so now, mynewbranch has simply named as newbranch
BCB-move

And if we want to delete the branch which is of no longer used and also you cannot delete any branch which is currently you are on, before deleting, first move on to different one and then you can delete it. git branch -d <branch name>

Here am going to delete newbranch, git branch -d newbranch
BCB-delete-newbranch

To check whether it has removed or not, you can use the command, git branch -a so, as I told you before, it will list all the existing branches.
BCB-git-branch-a-list

Git Push Operation

Merging In Git

Merging is nothing but combining the sequences of different commits into a unified commits history, is called as merging the branches.

The Merge command is used to integrate changes from another branch and combining all the integrated changes into a single commit, instead of treating them as individual commits.

There are two kinds of Merging:

  • Fast Forward Merge
  • Three Way Merge

Fast Forward Merge:

This kind of merging happens only when the master branch has not diverged and there should be a linear path between the branches that we wanted to merge.

Let us consider an example: there two branches called Master branch another one is Fatty branch if the master branch is in the same direction without any diversion, then instead of creating a new commit, the master branch will point to the last commit of the Fatty branch, So now all the commits from Fatty branch are available in master branch.
Before Merging:

FF-Merging-before-merge

After Merge:

FF-merging-after-merge

Threeway Merge:

When there is not any linear path between the two branches, then Git will join those two branches by using the extra commit, so this is called a three-way branch

Before Merging:

TW-before-merge

After Merge:

TW-after-merging

Git Tracked Files

Git Fast Forward Merging

We had learned the basic concepts in branching and now, let's do some actual branching, committing and merging.

  • Let's go to your home directory and then into your Git repository.
  • So, do a git status, Git tells us that we are currently on a clean working directory followed by Master branch.
    FFM-git-status
  • Now check for the current branches in your repository by using the command, git branch, which will list Local branches.
    FFM-git-branch
  • And if we use git branch -a will list all the branches including the Remote branches.
    FFM-git-branch-a
  • So, let's create a new branch and switch to it, we can do this instead in two steps by using the one single command, git checkout -b title-change
  • Where -b parameter will create a new branch called title-change and checkout will be switched to that new branch.
    FFM-git-checkout-b-title-change
  • Git Prompt will reflect that you are on a title-change branch, and If you do a git status, Git will tell you that, you are on the title-change branch with a clean working directory.
    FFM-git-status-title-change
  • So, now edit the simple.html file, just make the changes into the title, from "simple Title" to "An Example Website" save then exist.
    FFM-an-example-website
  • Once again do the git status, Git shows that we are having a modified file.
    FFM-git-status-simple-html
  • So, let us commit this change, git commit -am "Changing Title of File" and press enter.
    FFM-git-commit-am
  • And if you do git log --oneline, you can see your last commit right up there.
    FFM-git-log-one-line
  • Thus we have committed changes in the title-change branch and hence let's move this to master.
  • The first thing to do this is, switched to the master branch by using the command git checkout master
    FFM-git-checkout-master
  • Now, we are in the Master branch and let's merge these changes into one unified branch called the master branch.
    FFM-after-switching-to-master
  • Before merging, try to know the differences which you have made and it is good to know the changes before any merge.
  • We may know the differences between the master branch and the title-change by using, git diff master title-change and press enter.
    FFM-git-diff
  • If you want to see this visually, our p4merge will bring it clearly and visually.
  • Let us do git difftool master title-change so, here you can compare the differences.
    FFM-git-difftool

Now, I can merge in my changes, type git merge and then the name of the branch you wanted to merge into the current branch git merge title-change

And now, Git will respond as merging is successful and updating and also you can see the HASH code of the commits which are involved in the merging.

Git also tells that, It was a Fast Forward merge and the file which is involved is simple.html, and there was a "1 file changed, 1 insertion(+), and 1 deletion(-), the way that Git sees a change on the same line is a line deletion and line insertion at the same place called Fast Forward Merge.
FFM-git-merge

This is because Git placed all the commits into the master branch as if we never branched away and also we have not done any additional work on the master branch before merging into master.

Let's do git log --oneline --graph --decorate , you can see that the HEAD is pointing to the last commit on the master branch and also to the title-change branch and master is currently pointing to that commit as well.
FFM-git-log-oneline-graph-decorate

  • List all the branches git branch, we have our master branch and title-change branch.
    FFM-list-all-branches
  • Since we have merged all the changes from a title-change branch into the master branch and hence title-change branch is no longer required, thus delete that branch by usinggit branch -d title-change
    FFM-delete-title-change
  • Let us do git branch, thus we have our master branch only.
    FFM-git-branch-list
  • And also if you do git log --oneline --graph --decorate, you can see that at the top commit, which is nothing but our last commit with only master and HEAD are pointing to that.
    FFM-git-log-one

Git Editing File

Disable Fast Forward Merge in Git

We know how to do a Fast Forward merging in Git, now, let us understand how to disable the Fast Forward Merge in Git and follow the below instructions:

  • Let us start from where you left off, so, you are in the current working directory with your Git Repository.
  • Let's do a git status, Git tells us that, we are on the master branch with a clean working directory.
    WFFM-git-status
  • List all the branches in your working directory, git branch, we have only a Master branch in it.
    WFFM-git-branch
  • Let us create a Local branch by the name called "add-copyright".
  • So, I will use the shortcut method as I told you before, git checkout -b add-copyright and press enter.
  • Now the branch has created and we had switched to that branch.
    WFFM-git-checkout
  • Check the branch list git branch , you can see that the add-copyright branch has listed over here and also you can see an asterisk next to it, this means that the current working directory is add-copyright.
    WFFM-git-branch-add-copyright
  • Modify the simple.html by adding copyright notice at the beginning of the simple.html file.
    WFFM-notepad-simple-html
  • If you do a git status, we have modified file, so let's add this file to the staging area and commit the changes.
    WFFM-git-status-simple-html
  • Here am going to use the shortcut method once again by using the -am a parameter in the commit command, git commit -am "Adding copyright notice"and press enter.
    WFFM-git-commit-am-simple-html
  • Go ahead and edit the README.md file as well, Add copyright notice at the bottom of the README.md file, save and then exist.
    WFFM-content-readme
  • So, am going to commit changes to the README.md file as well, git commit -am "Adding the copyright notice to the README.md file"
    WFFM-readme-am-commit
  • Thus, we have two commits as a part of this branch, if you do git log --oneline --graph --decorate you can see the copyright notice at the top, which is nothing but our last commit, press "q" and exit.
    WFFM-git-log-oneline-graph-decorate
  • Now, integrate the changes into Master branch, before that, first, switch back to the master branch git checkout master
    WFFM-git-checkout-master
  • We are on the master branch now.
    WFFM-git-branch-list
  • Now, let's start doing the merge and here am going to disable the Fast Forward merging by using the parameters --no-ff, git merge add-copyright --no-ff
  • We are going to end up with a merge commit message so the editor page will display Merge branch "add-copyright", save then close.
    WFFM-git-mergeWFFM-merge-commit-message
  • If you do a git log --oneline --graph -- decorate, we can see that the graph lines being preserved.
    WFFM-git-log
  • We have integrated the changes and hence, the add-copyright branch is no longer required and let's delete that branch using git branch -d add-copyright.
    WFFM-delete-branch
  • If you check the list of the branches git branch, the add-copyright branch has deleted.
    WFFM-git-branch-last-step
  • Once again, if you do git log --oneline --graph --decorate, you can see that the branching still occurs and we do not have the labels associated with it.
    WFFM-git-log-last

Automatic Merge in Git

Till now we have learned how to do Fast Forward merge and how to disable the Fast Forward merging, now let's understand how to make Git do an Automatic merge and what is the command we need to use, come let's go through it.

In this part, there will be an automatic merge that will result in a merge commit automatically, The first thing is to, go to your project folder and then get into your Git repository.

Here I have my starter-web-1/ repository, just check for git status, before moving forward. Git tells us that we are on the master branch with a clean working directory.
AM-git-status

  • List the current active branch by using, git branch, you can see only the Master branch.
    AM-git-branch
  • Go ahead and create another branch called sample-changes by using git checkout -b Sample-changes
    AM-git-checkout-sample-changes
  • Thus, our branch has created and we switched to that branch as well.
  • Let's do an ls, so that, you can see some files over there.
    AM-ls-humans-readme

Let's go ahead and edit some files in that separately, Start with a humans.txt file, open humans.txt by using the default editor and add some Team information details under the Team and save then exit.
AM-git-notepad-human

  • If you check for the git status, Git tells that we have a modified file and let's commit that file.
    AM-git-status-humans
  • Here am using the two-in-one command, means am going to add the file and as well as committing the file too, git commit -am "Adding team instructions to the humans.txt"
    AM-git-commit-amone
  • So, I have done some changes to the file, before going to merge these changes am going to switch back to the master branch git checkout master .
    AM-git-checkout-master
  • So, now you are on the master branch.
    AM-git-branch-master

While I am on my master branch, am going to edit or modify another file called README.md and this could be done by another developer or this could be done by making this change just by context switching or fixing something on the production.

Let's go ahead and edit the README file and add some text under the "How to Contribute" as "please fork Git repository and then issue the pull request for review" save and then exit.
AM-git-content-readme

  • Check for the git status , Git tells that, we have a modified file and let us commit that file.
    AM-git-status-readme
  • Again am using the two-in-one method, git commit -am "Adding instructions on how to commit"
    AM-git-commit-am-two
  • Let's do git log --oneline --graph --decorate --all, you can see that on the top, we have two commits, we have the commit on sample-changes that is different than the commit on the master branch.
    AM-git-log-all
  • From the master branch, am going to merge sample-changes, git merge sample-changes -m "merging changes from sample-changes branch" where -m parameter will result in the commit message and in the double quotes representing our commit message.
    AM-git-merge-sample-change

If you check by using the git log command git log --oneline --graph --decorate --all . You can see that the merge has happened and we have our commit message too, but the sample-changes is still preserved as a separate branch.
AM-git-log-m

  • Hence we have done with the simple-changes branch, and this branch is no longer required thus, we can delete this branch by using git branch -d sample-changes
    AM-git-delete-sample-change
  • So we had removed the sample-changes branch, and you can see only the master branch is itself intact.
    AM-git-branch-last
  • Let us check the humans.txt file, you can see that, your modifications are still there and also if you check out the README.md file the text under the How to contribute are still present.
    AM-last-check-humansAM-last-check-readme

Deleting a File in Git

How to Resolve Merge Conflict in Git

In this section am going to cover, how to resolve merge conflicts, most of the time, we will end up doing Fast Forward merges, or

Merges that could result in Fast Forwards or else Git is going to merge automatically however, sometimes we are going to run into the conflicts and need to resolve them. Now let us follow as below.

  • I am currently in the working directory of my Git repository.
  • If I do git status, Git tells us that we are on master branch with a clean working directory with several commits ahead of origin.
    RMC-git-status
  • Let us check for the branch list, git branch since I have a master branch only.
    RMC-git-branch
  • Let us create another branch called realwork, git checkout-b realwork, Now do some changes in simple.html in the realwork branch and switch back to the master branch and do similar changes in the same area.
    RMC-git-checkout-realwork
  • And this will result in the merge conflict, perhaps this might occur if you have two developers or the contributors who are working on the different branches and then they have to come together and changes are not compatible.
  • So, now we are on a realwork branch, and edit the simple.html file at the copyright section by adding some dummy text in the content area. save then exit
    RMC-notepad-content-simple
    Note: The Highlighted sections are edited in the above image.
  • If you do a git status, Git will tell us that, we have modified file.
    RMC-git-status-modified-simple
  • Add the file and also Commit the changes, git commit -am "Making changes to simple.html"
    RMC-git-commit-am
  • Now let's do a git status, so our Git directory is clean on this branch.
    RMC-git-status-realwrk
  • Now switch back to the master branch, git checkout master
    RMC-git-checkout-master
  • Edit the simple.html file, if you see, the contents of the file remain the same as if we never switched back to the realwork branch.
    RMC-git-changes

And hence Git will change out all the files that are in the working directory to reflect the current state of the branch you are going to.

Hence I switched back and forth between different branches or different references within Git. Git is managing my working folder for me.

So let us make some additional changes that are going to create conflict and add the title as A very powerful website.

We have made some more changes to the simple.html file, and these changes should conflict the other changes I made in another branch.
RMC-git-modify-simple-html

  • If you do git status , we have a modified file.
    RMC-git-statusss
  • This time, instead of using the two-in-one method, I am going to use git add simple.html
    RMC-git-add
  • I am going to commit by using the default editor git commit press enter, the default editor page will open, enter your commit message over there save then exit.
    RMC-git-commit-editor
  • You will see the commit message on the command prompt.
  • Now if you do git log --oneline --graph --decorate --all , so you can see that our work has diverged, and you can see that the realwork and master changes are different.
    RMC-git-log-diverged
  • So this is a great example to use a git difftool would be very helpful.
  • First, do git diff master realwork, so that we can see the comparison between the two branches thus we can see some conflicts over here.
    RMC-git-diff-master-realwork
  • And hence we can see this visually by using the git difftool master realwork
    RMC-git-difftool
  • Let's merge realwork with the master git merge realwork
    RMC-git-merge-realwork

Here, the first thing we can observe that Git trying to merge simple.html automatically but it could not do that instead resulted with conflict in the content as Automatic merge failed.

We have to fix the conflict, here we are merging against the master, so we are in the merging state. Neither we do not have a clean working directory nor in the staged area, we are in between the merging.

Let's go ahead and have look at the simple.html, you will recognize differences, probably if you are familiar with the other source control tools that are popular in the Linux or Unix.

Then you may be comfortable to understand what Git will mark up your file to show the differences but Git will modify the file showing the differences.
RMC-highliting-errors

Then go ahead and modify the file manually, earlier we set up the visual diff and mergetools so that we could do this with a graphical tool.

So, to invoke our graphical tool, to help resolve our merge conflict, type git mergetool, and that will launch the p4merge, P4Merge is a pretty nice three-way mergetool, that we can use to resolve the conflicts.
RMC-git-mergetool

  • Once you are done resolving merges and conflicts, save the file and exit by pressing "q"
  • Now let's commit the changes, git commit -m "Done resolving the merge conflicts"
    RMC-git-commit-m
  • Once you have done, you see that the prompt has changed from master to merging, it means that the master is out of the merging.
  • If I do a git status, you can see that I do have one untracked file and that's because during resolving the merge, Git will save off an original copy of the merge conflicts.
    RMC-git-status-orig
  • So that if something got lost you can revert those changes. However, I don't want to track .orig files.
  • So I'm going to add that to my ignore list notepad++ .gitignore so, this will capture any file that ends with .orig save then exit.
    RMC-gitignore
  • If you do a git status, now it is excluded the .orig.
    RMC-git-gitignore
  • So I'm going to add the new changes to .gitignore, git add .gitignore.
    RMC-git-status-gitignore
  • And then I'm going to commit with the commit message git commit -m "updating ignore file to exclude merge temp files"
    RMC-commit
  • Well, now let's do git branch, I still have realwork branch here. since I have done merge with that branch and hence it is no longer required, so delete that branch git branch -d realwork.
    RMC-delete
  • If you do git log --oneline --graph --decorate --all , you can see that the "Done resolving merge conflicts" is my merge commit, followed up by the latest commit, which I needed to update the ignore file to exclude those temp files.
    RMC-git-log-oneline

Git's History

Push Changes Back to Github

We have reached the end point of Branching and Merging, so let us clean up the working directory and push the changes back to the Github.

  • Let's start with the working directory of my Git repository.
  • If you do a git status, you can see the clean working directory, with some commits ahead.
    PB-git-status
  • Have a look at the branch list. git branch , so here I have only the Master.
    PB-git-branch
  • Now, go ahead and push the changes, but the best practice is to pull before push and hence, git pull origin master, as expected it is already up-to-date.
    PB-git-pull
  • Now push the changes, git push origin master so, we have done everything here.
    PB-git-push
  • And then go to the browser and refresh your Github account, you can see your last commit .gitignore to exclude the temporary files.
    PB-github-gitignore
  • If you see right there, you can see all your changes.
    PB-github-orig

Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions