The need for a simplified guide on git for teams
For the past few weeks, a few of my friends got started using git and github for their projects, some started afresh, some came from SVN background. Despite knowing all the basic commands (push, pull, checkout, merge) they found themselves confused in actually putting those together to best work for their teams.
I started using git about a year ago, but I only started to really get a sense of the best practices since a few months back while working simultaneously in a team of 3 on master branch of the Rails backend for Denso.
Even long-time git users found it hard to explain all the concepts to a beginner clearly especially on rebasing topic. The problem is that there are so many materials you can easily find on Google, *however*, they are mostly too advanced like this one, or usually in separate articles.
In other words, the resources I found on Google don’t tell you what the hell it is and how to apply it in in layman terms, they tell you how it works, how nodes are moved and stuff, which you honestly don’t care!
So, out of frustration of having to explain it again and again, I hope this post will help you visualizing the 3 very important concepts for your team and something you can copy & paste it to your next hire.
Note: This post is not meant for the absolute beginners, I’m assuming you have been working with git for some time: knowing how to create/clone a repo, commit changes, push, pull, create branch, switch branch, merge, adding/removing remote repos. If you are looking for a beginner git guide, I suggest this excellent summary from StackOverflow.
The github graph
Below is a sample of github’s graph, an excellent tool to visualize the team’s effort. I use it daily and seriously cannot live without it. This shows an example three-day period of commits.
Take your time, there’s nothing really new about this. I only added some annotations make it clear later on this post.
Learn git CLI by heart, stop using GUI
The first and most important practice of git is learn all the git commands by heart and use them, do not rely on GUI for git, because I tried some of the clients, even GitHub for Mac, and sometimes they introduce more junks than just your commits. It will get *extremely messy* when you need to do stuff like merging and branching.
I use CLI for all the git actions (push,pull,rebase,branch,checkout,merge) except
git commit. For committing changes, I use GitX because I can selectively select the lines to be part of a single commit. Plus, I can see in realtime, the files affected without having to type
git status all the time.
Branch out, merge often, keep in sync
The picture above shows that I’m working on my_branch branch. So one of the common question I’m asked is when should I branch out. There are pretty clear rules about keeping your codes in a separate branch from master branch:
- You are about to make a major or disruptive change
- You are about to make some changes that might not be used
- You want to experiment on something that you are not sure it will work
- When you are told to branch out, others might have something they need to do in master
After branching out, you should keep in-sync with the master branch, because eventually you need to merge it back to master. In order to avoid a huge complicated mess of conflicts when merging back, you should commit often, merge often. As a simple illustration, the picture below shows the same graph before but with different annotations.
Compare with this with previous diagram, you can see that at the begining of each working day, I pull the changes from master into my branch (merge). I do this often and sometimes solve a few minor conflicts along the way. At the end of 2nd day. I merge my branch back into master without a single conflict! Smooth like butter.
The syntax is simply:
git checkout my_branch // Just to make sure I'm on the right branch git pull origin master // Read: pull the changes from origin/master into my current local branch my_branch
Another practice is rebasing the changes in master to your branch, however as you can see I’m striking this out because I found it extremely confusing, I do not use this method because it won’t show up as nice arrows on your github’s graph. You should just forget about I’m ever writing this after reading the next section
The mysterious & forever confusing ‘rebase’
This is my own definition, it’s not technically correct, but take it and it will make your life so much easier: (on current branch) git rebasing is taking all your local changes since the last push and put them ahead of other people’s changes regardless of the date you made the commit.
Base on that,
git pull --rebase means pulling all the new changes made by others, then taking all my changes that are not yet pushed, and put them ahead of other people’s changes on the current branch.
So why am I striking out again, because I do not want you to remember this: It is not technically correct because rebasing can work across branches, but it is too confusing to be used that way. Just stick to the current branch
The picture above shows the effect of git rebasing when done correctly.
Below are the sequence I use everytime for rebasing:
git commit -am 'My changes' // While i'm working on my machine // <-- My colleague did a "git push" here git pull --rebase // So before I can push, i need to rebase // Another syntax: git pull --rebase origin my_branch git push // Now my changes are on top
The focus of this is the
pull command, with additional
Before you wonder, yes, that is all you need to know about rebasing. Just one extra parameter. That’s it! Stop your mind from wandering because it is only that simple.
Perhaps you also wonder why people can’t explain it simply that way? Because git rebasing is indeed a lot more complicated, but for small team, I suggest that git rebasing to be used only on the current branch to avoid introducing extra commits as shown in the diagram above.
- Stop using GUI for git, seriously, it’s not that many commands
- Be safe, branch out, commit often, merge often
- Git rebase to be used on the current branch
git pull --rebase