I had my very first introduction to Git in 2012. While I worked on a development team of one, namely me, I did not really have much need for all of the features Git has to offer. I was not collaborating with other developers at that point.
I played around with Git, learned the basic command line functions and workflow. I thought it was a very useful tool for teams of programmers and developers, but I had a difficult time adopting Git into my own single developer workflow on a daily basis. I failed to see the benefits at that time.
2013 and 2014 brought about many changes to my business and my own project development and management strategies. I started managing a small team of people, some of them by remote. I thought this was the right time to really dive into Git and adopt the best practices regarding remote development teams, local resources and managing multiple projects simultaneously.
Today, I use Git everyday. I push changes, pull updates, make pull requests and share code and ideas with other developers in a very meaningful way. All of this day-to-day interaction tracked by the incredibly powerful version control system we call Git.
Personally, I subscribe to the feature branch workflow methodology of Git. What does that mean exactly? Well, each time a developer pulls a new feature item from the project's development storyboard, that person creates a new feature branch.
$ git branch new-feature-name
This strategy keeps all software changes off our master branch. In fact, I never work directly on the master branch. Many of our projects only merge fully baked and tested changes into the production branch. Every change, even the most basic changes, like a change to a template is feature branched first before work actually begins. Branches can be created and discarded with relative ease. In my projects, each project contains the following branch workflow.
- Master (default)
Once I have this set up and in place on all of the necessary servers, we begin feature branching.
The git branch command lets you create, list, rename and kill feature branches. Branching allows you to switch back and forth between branches with a simple command.
Git checkout and Git merge are an especially important part of Git branch workflow and these components are very tightly integrated with each other.
Let's start running some Git commands in our SagittariusA* repository.
List all branches:
$ git branch master *development staging production testing
Create a new branch:
$ git branch supermassive-blackhole
Create a new branch and checkout in one step:
$ git branch -b supermassive-blackhole
Rename a branch:
$ git branch -m <new-branch-name>
Delete a feature branch:
$ git branch -D supermassive-blackhole
Git does all of this branching with very little overhead. In traditional version control systems, like SVN, the repository has to copy all of the files to the new branch in the tree. However, in Git, the repo only stores a reference to the new branch and moves the pointer to the branch tip. This is what makes Git so fast and easy to use.
Now make changes to the project's source code by adding a new branch for our blackhole app. We add some new files and make a few commits. Our blackhole app adds has some useful new features in our application.
Our QA team has written some tests to ensure the new app is returning the correct data formats and the new features are fully tested prior to merging those changes in to the production branch.
Commit the new blackhole app changes.
$ git add blackhole/tests.py $ git add blackhole/app.py $ git add blackhole/forms.py $ git add blackhole/models.py $ git add blackhole/views.py $ git add blackhole/urls.py $ git st On branch supermassive-blackhole $ git commit -m "New blackhole application files"
Our project repository now looks like this...
We are now ready to merge our new feature branch into our testing branch.
$ git checkout testing $ git merge supermassive-blackhole --no-ff Merge made by 'recursive' strategy.
Now that the new feature branch has been tested and merged into the project's testing branch, our team is busy pounding away at the new features in the application.
No errors are found and the team is eager to launch these new items in the production system so our users can begin taking full advantage of the new features.
Whew, sprint much?
We log into the production server via SSH and from our production server terminal, we issue a pull in order to pull the changes to testing branch.
$ git pull origin testing $ git checkout production On branch 'production' $ git merge testing --no-ff Merge made by recursive strategy
Feature branch workflow is the easiest Git strategy to follow as it keeps all of our code isolated in individual containers. It prevents mixing new code with old code until we are absolutely ready to integrate.
But what happens if our merge results in a conflict?
That is a great topic for another article.
Resolving Merge Conflicts in Git.