By Kevin Kononenko07 Mar 2017Tutorials
If you understand how auto companies release new versions of cars, then you can learn the basics of version control system Git, explains Kevin Kononenko
When you are working with a team of developers for the first time, learning Git can be incredibly challenging. It seems like an entirely new sharing system, like Google Docs on steroids. Merges? Branches? Remote repos? Each piece has a purpose, but learning them all at once will lead to many long nights.
And just when you think you get the hang of it, you face the dreaded merge conflict. You relive it all again, this time with your team barking at you.
Git is a version control system that is part of pretty much every modern development process. There is one other system that works in a similar way.
Auto companies release new versions of car models every year, with slightly updated features. Car designers and engineers have a year-long cycle to plan and execute the features for the latest version. Along the way, each team must make sure their changes support the changes from other teams.
In this tutorial, I will show you how to use all the basic Git concepts and commands. Let’s get into it!
You are working on a team to release the Honda New Sedan 2018. New Sedan has been one of Honda's most popular vehicles for the last 20 years, and your team is under pressure to make it even better.
You are the body designer. In other words, you need to create a body design that works in tandem with the new features that the interiors team is putting in the car. Although you might have a great plan, it has to work together with all the new gadgets that the interiors team is working on.
How can you organise your workflow, so it accommodates all parties?
As you are developing the body for the 2018 version, there are really four versions of the design that exist at any given time.
The New Sedan 2017 is out on the market and the only version the customers know about. This represents the live version.
Every team contributes to the latest prototype of the 2018 sedan. This is the version that will eventually go live once all parties agree. This represents the remote repo.
You have developed the latest complete version of the body that you have yet to present to the team. It takes into account suggestions you have gotten from other teams. But you still need their final approval before adding it to the latest prototype. This represents the local repo.
And finally, you have an untested plan that is on your drafting paper or in a clay model. It has not even been reviewed yet to see if it meets all criteria. But you think it could be even better than all your previous designs! This is the staging area.
Each stage represents a different level of commitment to the body design.
Similarly, in your codebase, your code passes through four stages before it goes live. Just like in the car design process, this is a good thing! You would not want to draft up a car design, say “this looks great!” and immediately decide that it must be the final 2018 design. The entire team must decide if your design works in harmony with the changes they are making. It is a democratic process!
We can use Git commands to show the different stages of review that your design must go through before it goes live. Each stage lowers the risk that you will make a decision that conflicts with features built by another team.
Let’s start at the bottom.
With git add, you are declaring that you have finished a full design that you feel good about. Yes, it still needs to undergo testing, but it is a finished thought. The code enters the staging area.
When you are committing, that means that you feel fully confident in the design. You have put it through all the standard tests, and perhaps you have tweaked it a couple times. Added some chrome to the side mirrors, added a spoiler… any type of change that you felt was needed. Now you feel confident that it could be the next big thing for the 2018 New Sedan. So you commit it, and now you are ready to present to the other teams. The code is copied from the staging area into the local repo.
This is a big step! You are now ready to present to the executives, the interiors team and the safety/quality control team. This will determine whether your new design meets everyone’s standards. If they can’t work with your design, you will need to scrap it and start over. If this design can make it to the next step, everybody will need to live with it. So it better be good!
This is a big step because it copies your code from the local repo, which only you work on, into the remote repo, which is the latest prototype for the car. If you push a design that conflicts with the work of the other teams… they are going to be pissed! They will need to scramble to change their work to account for your changes.
When we talk about actual software development, the remote repo is hosted in the cloud, while the local repo is hosted on your machine. This makes it really easy to communicate the latest version between teams… but creates the risk that you will push changes that everyone will download and break their hard work! Don’t worry, you can come back from this.
This part is outside the scope of this tutorial, but it is important to include. This happens after all the teams are happy with the new features they added, and they all fit together and pass the tests without safety violations. The car is now ready for mass production. The factories will stop building the 2017 model, and start building 2018. Deploy is not an actual git command, but stands for the process of putting the final version live.
So far, all of our work has assumed that we are building just one new version of the car at a time. But in reality, New Sedan actually has three variations – a coupe, a convertible and a hybrid. These versions share most of the same features and components, but they have slightly different body designs. And when you are working on the 2018 New Sedan, you are really working on four slightly different versions.
It would not make sense to set up a new repository for each version since they have so much in common, so git uses branches. Branches allow us to maintain multiple versions of the same code base. Each branch of the New Sedan might have a few slight differences – a retractable roof, a hybrid engine or two doors.
This is the command you use to create a new branch. After you create a branch, you can commit/push changes to that particular branch just like the original branch, which is called the master. As the designer, you would want to create new branches for each version, and update the designs individually, while maintaining all the core components from the Sedan.
Okay, so let’s say that the consumer research team reports that there is no longer enough demand in the market for a convertible to justify a 2018 model. But, it would be nice to have a sunroof in the main Sedan to satisfy some of that community.
A merge allows you to integrate two of your branches. This will eliminate one of the branches, but will bring the features of that branch into the new, single branch.
You would merge the convertible into the Sedan branch, in this case, the master branch.
There is one other type of merge that you will face. You also need to merge remote changes with the local directory via git pull.
Let’s say that the interiors teams is updating the car dashboard. They talk to a bunch of other employees about it, but not you. Since they have approval from the others, they add it to the current prototype for the 2018 New Sedan. In other words, they push their changes to the remote repo.
As it turns out, this new dashboard will not fit into your latest designs. But they never consulted you on it!
Since you are a diligent employee, you are always checking the latest version of the prototype in the remote repo. Just in case someone made changes and forgot to tell you about them. You retrieve the latest changes via a git pull, and… the dreaded merge conflict occurs.
A merge conflict means that the latest updates in the remote repo do not agree with your latest body designs. You had been building the body around a more horizontal dashboard, but since they made the interiors team add this new fancy dashboard… your body design will not work.
The interiors team pushed their changes to the remote repo, and now you need to deal with the fallout. You have two options:
Change your body design, so that it can fit the new dashboard. Then push an updated version to resolve the conflict.
In an ideal world, a merge conflict would never happen. But in reality they happen despite the best efforts of the team. The good news is that Git can track them and quickly point out what exact lines are in conflict, so you can trace the issue.
Hopefully by this point you understand why Git is so darn important! It will take some practice to get the commands right. But you will eventually fall in love with the simplicity of using one line of Git to quickly diagnose an error or communicate a change to your team.
If you have any further questions, hit me up on Twitter @devmanual or email me at kevin (at) rtfmanual.io.
Kevin is the founder of Manual, a series of blogs and interactive tutorials that teach code via analogy.
Kevin is a self-taught web developer, and has been searching for a way to help others on the journey of learning code. He loves football and long conversations about psychology.