Welcome back! Be sure to check out the first past of this series before you jump into this one.
Let's start with a brief reminder of the last post:
To summarize: every time we stage a file, a blob object is created, storing the content of each file. Its name is the SHA-1 of the file's content and it’s stored under
.git/objects. Whenever we commit the changes to the repository, we create two new kinds of files: a tree, which stores more information about the files changed under it and a commit, with all the information about who saved the snapshot and why (the message!).
We took a quick look at the
.git/objects folder in your repository in our last post. Today, we are going to look at
.git/refs and the concept of local branches.
Now that we have a working repository, we can introduce a little bit of theory. A branch in Git is simply a lightweight movable pointer to one of your commits. The default branch name in Git is master. As you start making commits, you’re given a master branch that points to the last commit you made. Every time you commit, the master branch pointer moves forward automatically.
Internally, a branch is just a file in your
.git/refs/ folder that contains the SHA-1 id of a commit. Before we commited the new_file, this was the structure under
And this happened after the commit:
Can we take a loot at that
master file? Of course!
If we take a look at the log, just to be sure, we can see that it is in fact the id of the first commit that we made.
To get some content in our repository, and to check that what we just said really works, let's add another file:
We have confirmed that the pointer "moves" whenever we make a commit, so let's bring another branch into this:
We used the
git branch command to create a new branch. Can we just add commits to it?
What happened there?
- We got a new file called new_branch.
- We made a new commit that was supposed to be on the new branch, but!
- We found out that both new_branch and master point to this last commit.
Why did master update? Creating a new branch doesn't mean you are working on it. Git utilizes a special pointer called HEAD to know in which branch you are working on. If we take a look at it, before we switched branches
we can see that it contains a reference to another reference, in this case your master ref file. We'll use the
git checkout command to switch branches and add a new file to test it:
HEAD updated to the new branch after
checkout. You can look at this on your log too (HEAD -> current_branch):
After we looked at how we can diverge our work, we'll take a look at merging. The
git merge new_branch command will replay the changes made on the new_branch branch since it diverged from master until its current commit on top of master, and record the result in a new commit. So what happened to our ref files?
Now the both point to the same commit, and HEAD still points to master from the checkout. If we continue working on this branch, we can see in our log that new_branch will be left behind.
Now that we introduced the basics of branching, we'll take a look at a couple of git workflows. First, you must know that there is no standardized process on how to interact with Git. You can commit after each new word on a file, or make and merge branches for every file, for all Git cares. Use it however works for you and your team.
The core idea behind the Feature Branch Workflow is that all feature development should take place in a dedicated branch instead of the master branch. This encapsulation makes it easy for multiple developers to work on a particular feature without disturbing the main codebase.
From Atlassian's Git Feature Branch Workflow
Its just that simple! Whenever you need to add some feature to your project, you checkout a new branch, commit anything that you need there, and then merge it into the main branch.
This workflow is the idea of Vincent Driessen on 2010. You really should read that post, as its really nicely explained!
Gitflow doesn’t add any new concepts or commands beyond what’s required for the previous workflow. It assigns very specific roles to different branches and defines how and when they should interact. In addition to feature branches, it uses individual branches for preparing, maintaining, and recording releases.
After this post, the plan is to continue the branch topic with remote branches, reset, and rebasing.
I'm interested to know what do you think, if you have any comment or suggestion! Thanks for stopping by, see you again soon!