-
Notifications
You must be signed in to change notification settings - Fork 6
Git workflow
Generally speaking we try to maintain a development branch and a master branch. When the development branch reaches a particular milestone, we will look to push it to the master branch. In the event that this isn't a fast-forward merge (the development branch isn't an exact descendent of the head of the master branch, this could happen if we have bug fixes in the master branch for example), one person can just do a forceful merge:
git checkout development
git merge -s ours # this creates a merge where the development head will be the new head
git checkout master
git merge development
For the most part though, we will be working on topic branches off of the development branch.
git checkout development
git checkout -b my_topic_branch #creates new branch and checks it out
git push -u origin my_topic_branch // this will make it upstream tracked in github
# do work, commit to our branch...
Let's say the development branch has progressed since we created our new branch and we want to get those changes on our topic branch. The way to do this is to rebase our topic branch onto the development branch like so:
git checkout my_topic_branch
git rebase origin/development #alternatively, pull the development branch and then rebase locally
# resolve conflicts...
git push --force origin my_topic_branch
What this does is it replays your commits onto the topic branch as if they were applied to the head of the development branch and not off the commit you originally branched from. You then may have to resolve conflicts (which will modify your original commits to the topic branch). Once this is done, your local my_topic_branch is not a fast-forward of the remote my_topic_branch. So you must do a force push to get it to the remote. This means that one person should do this when everyone has agreed.
When your feature or bug fix is complete, you want to follow the same procedure as above to make the topic branch a fast-forward of the development branch. There are two options for merging it into the development branch. If the topic branch is insignificant and you would like to remove it after the merge then do the following:
# topic branch has been rebased to the head of the development branch
git checkout development
git merge my_topic_branch
git push origin development
Now all the commits onto the my_topic_branch have been merged into the development branch as a fast-forward so all our history is in the development branch. We are free to remove the topic branch.
What if we have a significant topic branch that we want to leave around to store all the history of those commits but we don't want to pollute the history of the development branch with so many commits? Here is how I suggest merging it into the development branch:
# topic branch has been rebased to the head of the development branch
git checkout development
git merge --no-ff my_topic_branch
git push origin development
This does a non-fast-forward merge into the development branch. An explicit commit is made to the development branch noting that we merged in the topic_branch. This single commit holds all the changes of the my_topic_branch. The my_topic_branch still holds the history of each separate commit onto that branch.
If you just made a commit or two to your local version of the development branch and want to push it but someone made a push first:
git pull --rebase
git push
see: http://randyfay.com/node/91 (the comments are of value too) and http://stackoverflow.com/questions/457927/git-workflow-and-rebase-vs-merge-questions