[Biojava-dev] Git Rebase workflow
Spencer Bliven
sbliven at ucsd.edu
Wed Jun 12 20:25:20 UTC 2013
>From the activity on github, it looks like everyone is enjoying the new git
system. Andreas and I recently ran into a tricky merge case, so I wanted to
share a technique for keeping up-to-date with the master branch without
unnecessary merges–the rebase
workflow<http://randyfay.com/content/rebase-workflow-git>
.
When you're working in a local fork and want to bring in the latest changes
(in preparation for merging new development back, for instance), you have
two changes:
1. Merge changes from the main repository into your development branch
(usually via 'git pull')
2. Use rebase to apply your changes on top of the changes from the main
repository.
This second option is similar to running 'svn pull' to get recent changes
in subversion, since you can run it daily without making your history a tangled
mess <https://github.com/biojava/biojava/network>. There are a couple
benefits over the standard merge workflow most people have been using.
- No unnecessary merge commits. Only use a merge when adding a major new
feature, not for just synchronizing changes
- Cleaner histories when viewing the network graph
- Decreased chance of conflict when merging
The following link explains it better than I could in an email, but I'll
give a summary of the commands I use.
http://randyfay.com/content/rebase-workflow-git
Setup: I call my git fork 'origin' and the biojava repository 'main':
$ git remote -v
main https://github.com/biojava/biojava.git (fetch)
main https://github.com/biojava/biojava.git (push)
origin https://github.com/sbliven/biojava-sbliven.git (fetch)
origin https://github.com/sbliven/biojava-sbliven.git (push)
First, fetch (don't pull!) recent changes
git fetch --all
Unless you do development elsewhere, you should be in sync with origin, but
not main
$ git branch --all -v
master 9b62b02 New Feature!
remotes/main/master b58307a Latest biojava
remotes/origin/master 9b62b02 New Feature!
Preliminaries out of the way, do the rebase. This basically rewrites your
current branch to pretend that all the edits occurred after the edits in
the main branch. You may have to resolve some conflicts manually as with a
merge.
*$ git rebase main/master*
First, rewinding head to replay your work on top of it...
Applying: Master branch
At the end, you will still have all the changes made locally, but
main/master will be the direct parent of the new master. This means that
merging back into main can be accomplished as a simple fast-forward merge.
Rather than doing a pull request for each small modification, just update
using the fetch/rebase combination and push your changes directly to
biojava.
$ git push main master
One important point that makes some people nervous about this workflow is
that it changes all the hashes of the rebased commits. So if the old
commits were shared with anyone else, they will also have to rebase their
changes. However, as long as no one else uses your personal github fork,
you can be certain that nothing refers to the old commits. Just force
github to accept the new hash.
$ git push -f origin master
Just never, ever do a push -f to the main repository or rebase any branch
of the main repository. Doing so will cause serious confusion for other
developers.
-Spencer
More information about the biojava-dev
mailing list