“Git” Intermediate (Branch, Checkout, Merge, Tag, Bare Repository)
In the ‘Git Fundamentals’ article, we talked about how Git was invented, its architecture and the basic commands to get started. In the “Github fundamentals” we talked about how to set up Git to work with a remote repository and other Github features on offer.
In this article, we’ll build our knowledge of intermediate Git features that will help us maintain our Code more efficiently. Also, these skills will be handy while working in a continuous release environment with parallel teams working on separate features, and they all get released at different time scales.
Git provides an ecosystem to handle such use-cases with the chain of commands which are tightly integrated with each other to provide the complete parallelism and code maintenance capabilities.
Branch
Nearly every version control system has the feature of branches. Simply put, they are alternate timelines of your repository on which you can perform separate code changes. Your “mainstream” branch stays unaffected with those changes. You can choose to merge it with the mainstream whenever you wish to. Till that time they have a parallel existence.

In Git, the mainstream branch is called “the Master”. Other branches can be created from any commit version of the Master branch to start an independent line of development be it a little or a big feature or a hotfix.
The branch command let us perform the following tasks,
- Listing of all branches for this repository
- Creation of a new branch
- Deletion of a branch
- Renaming a branch
Checkout
Checkout is a versatile feature. You can think of it as a time travel machine that allows us to look at what we did in our past (the previous commit states of the current repository) or allows us to look at what is going on in the parallel universes (the other branches of the current repository).
The checkout command plays a duel role.
On branches it lets us do the following things,
- Check-out an existing branch.
- Switching between different branches and the Master.
- Shorthand command to create a new branch and check-out the same in one step.
- Option to create a new branch with its base as either the current HEAD or any other previous commits or any other branch.
On previous commits it lets us do the following things,
- Allow us to Go back to the previous commits.
But there’s one big catch. When we use checkout to go back to the previous commit, we enter into a “Detached HEAD” state. The repository is in a state of limbo. It has no existence. Because we are no longer in any branch or in the HEAD. If you went back to just take a look at those changes, then it’s all cool, but if you plan to make changes there, then Watch Out.
*Any changes you make on this timeline will be lost forever.* They will be picked up by Git’s periodic garbage collector engine.
To preserve those changes you must create a new branch and save them there.
Merge
Working in parallel branches is all smooth sailing but eventually, you would want your feature (when it’s finished) to get integrated with the Master. Some people prefer to merge them after the release, some prefer to merge them with the Master and make the release from the Master branch.
Whatever may be your taste, the merging is a very critical tool in largescale project development. If not handled properly, you are at risk of making the mess of your repository. Unknowingly deleting the code that was needed or adding the code which wasn’t.
The merge command is at your disposal to perform the hard yards.
Merging can happen in two ways,
Fast forward merge
This is the easiest and sweetest of the merge which is not likely to run into any conflicts. This will happen when there is a linear path between the source and the destination. The destination has not deviated into another timeline.

Three-Way Merge
This is the tougher of the lot. This is the most likely scenario in the large scale product development. It happens when the master and the branch have deviated to a different timeline since the time they forked. Both of them have new features or hotfixes, and they are likely to be done on the same portions of the file. This is called a three-way merge because we are merging three things, the HEAD of the feature branch, the HEAD of the Master branch and their common ancestor.

The merge is likely to run into conflicts. Git’s merging algorithm will try to resolve the conflicts on its own in most cases but there will be cases when Git doesn’t know how to resolve them. It will ask for manual intervention at that time.
When Git encounters a conflict during a merge, It will edit the content of the affected files with visual indicators that mark both sides of the conflicting content. These visual markers are: <<<<<<<, =======, and >>>>>>>.

Tag
The last piece of the puzzle is “tag”. Tags are named committed versions of your Master branch that usually went public as an independent release. Tags are created to preserve the released state of the Master branch. Once created, tags are not be tinkered with. They ought to be treated as the read-only copies, meant only for look-ups.
Tags are of two types,
Lightweight Tags
Lightweight tags are usually the bookmark tags. Only meant for private use. They do not add any associated metadata along with the tag. They are not created when the release went public. They are created when probably the release went to QA or for Beta testing.
Annotated Tags
Annotated tags are usually created when the release went public. They have all associated metadata for recording purposes. Along with the copy of the code and tag name, they store additional details like tagger name, email, date, etc.
The tag command helps with following things,
- List all available tags
- Create Lightweight tags
- Create Annotated tags
- Delete tags
Bare Repository
As mentioned earlier, every git local directory is a full-fledged repository in itself with a complete history and full version tracking capabilities. This increases the size of every repository you clone (local or remote), and also makes it slow, because the entire version history gets copied locally.
In many cases, the remote repository is used for code sharing. Nobody actually works on the remote repo directly. So, it is preferable to have it without the full version history i.e. having it ‘bare’.
The Bare repository only contains the latest copy of the code i.e. the code of the HEAD commit.
This concludes the Git Intermediate topic. As I mentioned earlier, Git is vast and offers a hell lot more than any other version control system. The initial learning curve can be a bit steep but once you scale it, and master it, you wouldn’t even remember how you struggled with it in the initial days.
