Utilizing Git to dive into huge code bases - Git SVN Tips
Unfortunately there are still projects not on dvsc like git. That’s especially true for enterprise customers which are at least stuck on Subversion if not worse.
So the first thing I do on new projects I join:
<code class="bash"> git svn clone -s svn-url </code>
Or installing Git if I have to work on customer provided machines. That’s even more important than the rest of a development environment like an IDE.
From experience I find it especially useful to experiment with new code basis utilizing Git. Grown and big projects aren’t easy to understand architecturally and implementation wise without digging deep. With the help of Git you can jump right in, without fear and without messing everything up or having too much unrevertable local changes. Just commit early and often! By doing it locally, in experimental branches you can try and learn. Before you publish something to a wider audience (svn) you can reorder, cherrypick and change everything or parts of it. Git is my tool of choice to get my hands dirty with legacy code (new one too of course).
Some useful tips on how I use Git-SVN:
SVN history is linear, so you can’t use branches and merge the usual git-way without thinking.
What often happens to me is that I implement a new feature, do some refactorings on my way etc and an urgant bug report comes along. But I commited on master, don’t want to push it to SVN yet since it’s not finished yet and might not be stable. What to do? git svn dcommit would push all my local master commits to svn. The solution:
<code class="bash"> git branch featureA </code> <tt> |svn | master ---o---o---o---o---o---o---o---o---o---o | featureA </tt>
Now both branches featureA and master point to the latest commit. But we want master to point to an earlier commit. Let’s say the last 10 commits aren’t in SVN yet and the last 8 are experimental, so 2 could be pushed.
<code class="bash"> git reset --hard HEAD~8 </code>
<code class="bash"> git reset --hard sha-hash-of-commit-to-point-to </code>
Now my master is in the state it was in 8 commits ago and my experimental changes are still in featureA branch.
<tt> |svn | master ---o---o---o---o---o---o---o---o---o---o | featureA </tt>
I can continue with fixing that critical bug, commit and svn dcommit. Have a look on how your history look with gitk –all.
<tt> | svn ---o---o---o master / ---o---o---o \---o---o---o---o---o---o---o | featureA </tt>
Dcommit rebased 3 commits and especially if there were some more upstream svn commits, I want to base my experimental stuff ontop of this. So I do a
<code class="bash"> git checkout featureA git rebase master </code> <tt> | master ---o---o---o---o---o---o---o---o---o---o---o | svn | featureA </tt>
Even if I could live without the upstream changes on my featureA branch for now, I’d need a rebase later anyway, so I can do it in advance. That’s because the history wouldn’t be linear anymore by doing a three-way merge of my featureA into master without rebasing.
When I’m satisfied and with featureA and nothing changed in master I can
<code class="bash"> git checkout master git merge featureA git branch -d featureA </code>
And since it’s a fast-forward merge can continue to push it to SVN
<code class="bash"> git svn dcommit </code> <tt> | master ---o---o---o---o---o---o---o---o---o---o---o | svn </tt>
If something did change in master I just do another rebase before the merge.
If I come to the conclusion that my experimental branch was just for learning purpose and only one or two useful refactoring or unit-test improving commits I take only these to master and abandon the branch.
<code class="bash"> git checkout master git cherry-pick sha-of-one-commit git cherry-pick sha-of-another </code>
If I’m overall satisfied with the results of my experimental branch, but not with commit messages, how the commits are ordered and maybe their scope, I use git rebases interactive mode
<code class="bash"> git rebase -i sha-after-this-commit </code>
reordering commits, splitting commits, editing commit messages, squashing multiple commits together.
There are endless more possibilities to get a better grip on your code-base.