Friday, March 20, 2015

Source Code Control: Converting from VisualSVN to Git on BitBucket

By Steve Endow

I do a lot of development with Visual Studio, creating eConnect integrations and VS Tools integrations for Microsoft Dynamics GP.

Back in 2012 when I decided to finally setup a source code control solution, Subversion was one of the few source code systems I had heard of, other than the infamous and ancient Microsoft Visual SourceSafe.  I wasn't about to resurrect SourceSafe, and I found the 1.7 GB download for Team Foundation Server made quite a statement, telling me that I shouldn't bother with it.

After some searching, I found VisualSVN--a Windows implementation of the open source Subversion that seamlessly integrated into Visual Studio.  I was up and running in minutes and had a project checked in to my new repository shortly thereafter.

I've been using VisualSVN since February 2012 and love it.  It is simple, relatively obvious, very easy to use for typical tasks, and has been 100% reliable.  I haven't had a single issue with VisualSVN on the server or on my many development servers.  It has been flawless.

Best of all, VisualSVN has a free license for certain qualified users, so you can't beat the price.  For simple, linear development with a small number of users on a project, I highly recommend it.

With VisualSVN, typical day-to-day check-in and check-out operations are very simple and generally require one or two clicks in my single user environment.  However, I've had a few cases where I've needed to revert to older code or research an issue in a prior version, and in those cases, the VisualSVN interface and tools (such as the TortoiseSVN tool that VisualSVN relies on) become much less intuitive and less friendly.

I recently had a situation where a client discovered a bug in a version 1.0 production integration after I had already started on making version 2.0 changes and new features to the code.  Version 1.0 had been in production for a few months before the bug was discovered.

It went like this:

  • Develop version 1.0
  • Release version 1.0 to QA environment
  • Test and refine version 1.0
  • Release 1.0 to production environment
  • All is well

  • Develop version 2.0
  • Release version 2.0 to QA environment
  • Test and refine version 2.0

  • Customer finds bug in version 1.0 in production
  • Chaos ensues

So there I was, with my half-baked version 2.0 code released in QA, faced with a bug in version 1.0 that needed to be fixed ASAP.

I had never faced this situation before, so I didn't know how to best handle it.  I knew that I had all of my code and revisions safely checked in VisualSVN, so I knew I could roll back to my 1.0 release code.

But what about my current 2.0 code?  Even though my 2.0 code was checked in, I didn't want to overwrite my current project and roll back to 1.0.  I guess I was afraid that if I pulled down the old 1.0 code and checked in any changes, it would revert my code and mess something up.

My fundamental problem, I later realized, was that short of checking in code, I didn't understand source code control best practices.  Surely there was a way to handle this situation, right?

I posted the question to Experts Exchange and quickly received a response that made total sense in hindsight.  I needed Branching.

I had been developing exclusively against my "trunk" code, in a completely linear manner, without ever branching.  My projects are typically relatively small, easy to manage, and usually don't require branching, but for my current project, the code was moderately complex and had enough features that I really needed to branch with each release, and perhaps with each sub-release.

With that obvious clue in hand, I hit the books.  I downloaded the free SVN Book and read every page.  I needed to understand how to properly branch in SVN / VisualSVN and manage my branches.

The SVN Book is fantastic, providing clear examples in a very easily understood and readable guide.

But I stopped in my tracks when I read this statement:
Once a --reintegrate merge is done from branch to trunk, the branch is no longer usable for further work. It's not able to correctly absorb new trunk changes, nor can it be properly reintegrated to trunk again. For this reason, if you want to keep working on your feature branch, we recommend destroying it and then re-creating it from the trunk.
This refers to the process of merging your "branch" back into the main "trunk" of the code.  Once you perform this merge, the branch is essentially deprecated.  Once the trunk is changed after that point, the branch should no longer be used and should be "destroyed".

What???  So that means I can't persist branches and would have to jump through some hoops if I needed to "back port" some fixes into a prior release.  While the book offers a few workarounds for handling such situations, it appeared that SVN wasn't particularly good at, or really designed for, such "dynamic" branching and back-porting.

The book explained the SVN architecture well, so it was pretty obvious why this limitation existed.  But I was disappointed nonetheless.

I posted another question to Experts Exchange about my concern, asking how to deal with my situation in SVN.  The answer I received wasn't one I was expecting:
You may not like to hear it, but you should switch to Git. 
At first I thought this might be one of those Windows vs. Mac vs. Linux religious opinions, but after a few minutes of reading about Git, the recommendation made a lot of sense.

Git, despite the horrible name, is an amazingly powerful source control system designed to handle the completely crazy development process of the Linux kernel.  If it is good enough Linus Torvalds and Linux kernel development, I have no doubt it would handle my simple needs.

I downloaded the free Pro Git book and started reading that night.  Mind. Blown.

Barney...wait for it...Stinson
Git is source code control and branching and merging on steroids.  Unlike the nice, simple, obvious, and intuitive SVN book, the Git book was harder to follow and digest.  Branch, branch again, branch your branches, then merge, rebranch, merge your merges to your merged merge and then magically just have it all end up in a single cohesive pile of code at the end of the day.

The design and capabilities of Git seemed like some crazy magic.

Despite not fully understanding all of the features that Git provided, it seemed clear that it was more than capable of handling my branching needs.

So, I then needed to figure out how to use it.  I realized that the ubiquity of Git meant that there were quite a few providers of hosted Git servers, so I could outsource my source code control server.  While my VisualSVN server has been virtually zero maintenance, I won't mind having one less VM running.

I looked into GitHub, the well known online code repository.  While it seems to be a great service, there was one significant issue, given my business model.  GitHub charges by "repository", which in Git lingo, is essentially a project.  So if I have 30 clients with an average of 3 projects, I'll have 90 repositories.

Hosted Git services differentiate between a public (open source) and private repository--in my case, all of my client projects will need private repositories, so I would need 90 private repositories.  On GitHub, that would cost me $200 a month.  Gulp.  That would be tough to justify.

Fortunately, there is an alternative service called Bitbucket that has a completely different pricing model that is much better suited to my needs.  Bitbucket charges by user, not by private repository, so I was able to get their free plan with unlimited private repositories and up to 5 users.  Perfect.

(BTW, Atlassian, the provider of Bitbucket, also offers Git server software called Stash that can be installed and hosted on an internal server in case that is appealing)

So now I was interested in using Git and had setup an account on Bitbucket.  How does it work and how to I use it with Visual Studio?

This is one area where I think VisualSVN is a clear winner and Git, well, it's a distant second.  Because Git has a different architecture, a local distributed repository model, more flexibility, and more features, it takes effort to figure out how to use it and how to work with it in Visual Studio.  The local / distributed repository design of Git adds an extra step in the code management process that takes some adjustment when coming from SVN.  But on the flipside, having a local offline repository provides fantastic flexibility for distributed and remote development.

One nice plus is that Visual Studio 2013 has native support for Git, and for online services such as Bitbucket, built right into the Team Explorer window in Visual Studio.

While it is very handy to have the source control built right into Visual Studio, versus a client install and regular updates with VisualSVN, I find the user interface somewhat unintuitive.  I'm slowly learning how to use it, and for now I'm having to regularly refer to my notes every time I have to create a new repository and sync it to Bitbucket.

I'm sure I'll get more comfortable with Git, just as it took me a while to get familiar with VisualSVN, and I hope to take advantage of Git's rich branching and merging functionality.

Whether you consider SVN, Git, or some other solution, one general thing I learned about this project is that source code control is an entire discipline--like networking, system administration, or even software development.  It's one of those things where you really should invest time to learn and understand the discipline in addition to the specific technology that you choose to use.

If I read the Git book a few more times, or a dozen, I hope I'll get more comfortable with the Git features and how to use them.

Now go Git coding!

Steve Endow is a Microsoft MVP for Dynamics GP and a Dynamics GP Certified IT Professional in Los Angeles.  He is the owner of Precipio Services, which provides Dynamics GP integrations, customizations, and automation solutions.

You can also find him on Google+ and Twitter

No comments: