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:


   git svn clone -s svn-url

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:


   git branch featureA

      |svn                                | master
   ---o---o---o---o---o---o---o---o---o---o
                                          | featureA

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.


   git reset --hard HEAD~8

or


   git reset --hard sha-hash-of-commit-to-point-to

Now my master is in the state it was in 8 commits ago and my experimental changes
are still in featureA branch.


      |svn    | master
   ---o---o---o---o---o---o---o---o---o---o
                                          | featureA

I can continue with fixing that critical bug, commit and svn dcommit. Have a look on how your history look with gitk –all.


                  | svn
       ---o---o---o master
      /
   ---o---o---o
               \---o---o---o---o---o---o---o
                                           | featureA

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


   git checkout featureA
   git rebase master

                  | master
   ---o---o---o---o---o---o---o---o---o---o---o
                  | svn                       | featureA

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


   git checkout master
   git merge featureA
   git branch -d featureA

And since it’s a fast-forward merge can continue to push it to SVN


   git svn dcommit

                                              | master
   ---o---o---o---o---o---o---o---o---o---o---o
                                              | svn

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.


   git checkout master
   git cherry-pick sha-of-one-commit
   git cherry-pick sha-of-another

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


   git rebase -i sha-after-this-commit

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.