In order to utilize Git’s full potential, we should be using branches to house our sets of changes. Typically you want a branch to be as atomic as possible. The goal is to have your branch contain a specific set of work (which can be eventually squashed down to a single commit) which will eventually be pushed on to the master branch. There are a lot of great resources on this topic (especially this one: http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging) but I wanted to focus on some very simple and entry level use cases.
When you create a branch it will be tracking against some other branch, by default it is the master branch.
Ex. 1 – Creating a branch and pushing it back to master
The simple example below is a graphical example of creating a new branch called “steve_branch” from master. 4 commits are made on this branch by Steve and then pushed back to the master branch.
Commands:
git checkout -b steve_branch origin/master
Creates a new branch from the master branch named steve_branch
git push origin HEAD:master
Takes the head of the working branch (assuming it is steve_branch) and pushes it to master. (Note: always good to rebase before performing this action which is explained in the next example)
Ex. 2 – Rebasing Before Pushing
The example above works great if there is no one else developing against master… but that is almost NEVER the case. In this example, we’ll go through a similar flow, but account for the fact that someone else is working on the branch. In this example user John creates the branch john_branch does work more quickly then Steve and pushes it up to master. When Steve is done, he then needs rebase his branch (to get the latest from master) before pushing to master. Since you are tracking against the master branch, it is always a good idea to be as close to it as you can with the exception of the commits you are about to add.
Pull Requests
Commands:
git fetch
Pull the latest changes to the master branch locally (to what is known as the staging area). NOTE: This does not mean they are applied, but simply means they are locally available and ready to be applied… the next step
git checkout -b steve_branch origin/master
Take the latest (locally available) changes from the master branch and merge them with the current branch (steve_branch). Once that is complete, take Steve’s set of commits and place them at the HEAD of the branch.
Ex 3. Full command set
Just because I like to use examples to drill home the point and for those who are new to get, this example is simply an extension of either of the previous examples, but focusing more on the possible commands Steve may have used in either scenario.
Commands In Order:
1. Fetch – Fetching keeps your local repository up to date. It’s a good idea to fetch before doing actions that involve other branches.
git fetch
2. Create a new branch – Regardless of the branch you were on, this will create a new one from master and make it your current active branch
git checkout -b steve_branch origin/master
3. Do some work to the branch (No git commands here, this just represents some work being done to generate a change set.)
4. Add – Add the work to the staging area (think of this as the area that houses the “stuff” you’re about to commit)
git add .
NOTE: The “.” used above means take all changes in the current directory from the command line. This could just as easily be targeted to only specific file or files
5. Commit – This basically finalizes this change set as a commit on your branch (in this case steve_branch) this does not exist anywhere but your local branch at this piont.
git commit -m "This is a commit message about what I did"
NOTE: The note after the -m is a commit message. You should always include a commit message about what the purpose of the commit is.
6. Fetch – We fetch again because some time has elapsed since we created the branch and others may have pushed some work to the master branch.
git fetch
7. Rebase – We want to make sure that if there were changes to the master branch we merge them in and place our work on top (since it does occur chronologically afterward). This does not hurt us if there are no changes. Rebasing often can avoid a lot of code conflicts. When conflicts can’t be avoided, regular rebasing may have made resolving them a lot easier.
git rebase origin/master
8. Push – We’re done doing work on our branch and want to push it to the master branch.
git push origin HEAD:master
NOTE: The command above assumes you are in the branch (steve_branch) that your work exists in and it is in a state you are ready to introduce to the master branch.
Hopefully these examples have made it easier to understand a few simple branching examples and given you the tools to experiment some with your own branches. As with anything technical, what is described above is NOT the only way to do branching, but just a simple and easy to follow one. Git provides a lot of flexibility in how you can create, modify, merge, and push branches/commits so be careful. And as always RTM http://git-scm.com/documentation (I’ll leave the “F” out because I’m a nice guy).