Workflow for using Git SVN and a Remote Git Repository with multiple users

Summary of the question:

I came to realise as I wrote this out that there is a lot of detail, so here’s the headline:

  • What is a good workflow for a team of many users that use SVN and Git SVN within a work environment, but then also want to use a remote Git Repo (BitBucket) to access the same code from outside of the work environment, share changes to this code between each other while out of the office, and then safely rebasing back to SVN when back in the office? While others are continuing to use Git SVN locally within the office too?

In writing this, I’ve also come to realise that what I’m asking to do is really quite complex and may simply not be possible…

The Detail:

I work with a team of people using an SVN Repository. A number of us have started using Git SVN and are now reaping the benefits of using Git locally, branching at whim, merging into our local Masters as necessary and then dcommitting back to SVN. This works well (although I realise we are not reaping all the benefits of a pure Git solution).

I have recently started using a private BitBucket Git Repository as a remote for the Master, so I can easily transfer code to and from other places. The workflow is this:

  • At work, Rebase from SVN Trunk => Local Work Master.
  • Push from Local Work Master => BitBucket Master.
  • At home, pull from BitBucket Master => Local Home Master.
  • Do coding at home, branching, merging, enjoying git.
  • Merge from local home branches => Local Home Master.
  • Push from Local Home Master => BitBucket Master.
  • At work, pull from BitBucket Master to Local Work Master.
  • Rebase against SVN Trunk.
  • Dcommit to SVN.

Okay, there are a few steps but it works well for me. But, a number of my colleagues want to start doing the same sort of thing. What is more, we want to be able to use our BitBucket Git repo without the encumbrance SVN.

Some examples of the sorts of things we are considering:

  • If one of us is out of the office, they want to be able to get the latest code. At work, I can rebase from SVN and then push to BitBucket, making the latest code available to my colleague.
  • If two of us want to share some changes (assuming either one or both of us are out of the office), we can create a feature branch for this on BitBucket and each push and pull it as necessary.
  • When we’re happy with it one of us can merge it into our Local Home Master and then push to BitBucket Master, ready for pulling when we’re back at work.
  • Once back at work one of us can pull Master from BitBucket to our Local Work Master, then then rebase against SVN and dcommit as usual.

But, assuming one of us has done this, what then happens for the rest of the team? If they pull from BitBucket Master, they’ll get the changes.
But, if they rebase from SVN, they’ll get the changes too.

What happens if they do both? And this is just one possible snag. I can think of other sets of steps were this could all get into a real mess.

Unfortunately our Continuous Integration workflow is tied to SVN, as is the rest of the business. Therefore we don’t really have the option of moving to Git in it’s entirety. We also can’t access our SVN repository from outside the company.

  • My project uses over 100 git submodules, which submodule alternative can handle a lot of repositories gracefully
  • Git and nightly builds - how to do it efficiently?
  • Create a subdomain for every Git branch created
  • Bitbucket workflow query
  • How to work on a drop-in library?
  • How can I use Git repositories for web development (and deployment)?
  • Is installing WordPress as a Git submodule a good idea?
  • Git automatic checkout in subprojects
  • 2 Solutions collect form web for “Workflow for using Git SVN and a Remote Git Repository with multiple users”

    Have a look at SubGit project designed for those who wants to use Git and SVN repositories at the same time. If you have access to your SVN server, you just run

    $ subgit install path/to/svn/repository
    

    After that a Git interface for the repository is created. Every push to the Git repository is translated to SVN and vice versa. You just setup access to that newly created Git repository.

    Some git-svn-based scripts for SVN<->Git mirror propose similar functionality but they have disadvantages compared to SubGit:

    • concurrency problems: if someone pushes to SVN and Git at the same time, the repositories histories become diverged (SubGit cares about concurrency);
    • git-svn repository allows only SVN-like concepts (for instance, it doesn’t allow to have a Git submodules — “git svn dcommit” removes locally added submodules)
    • git-svn doesn’t translate svn:ignore to .gitignore
    • git-svn doesn’t handle line endings correctly (i.e. doesn’t respect svn:eol-style)
    • git-svn doesn’t translate anonymous Git branches, commits in those branches never get into SVN
    • git-svn not always translates Git merge commits to SVN svn:mergeinfo change correctly
    • git-svn dcommit doesn’t preserve dates in Git commits while Git->SVN translation

    The advantage of git-svn is to have a possibility to keep Git mirror in another machine; but it pays for that with concurrency-safety (being on the same machine is a condition of locking both SVN and Git repositories for a translation period for short time).

    Synchronizing a git server with a svn repository is no easy business. If you want to use two servers, one with git and one with subversion, you are going to run into problems:

    • Subversion does not understand branches the same way that git does. If you do a couple of merges in git between branches, this can be passed to svn too. But for subversion, everything happened in one branch, so the reverse is not possible without losing information.
    • When you dcommit, your changes are rebased. That means that the commits get a new sha. If you merge changes back from subversion to git, git gets confused.

    I tried at work to get the same sync going (we were tied to svn for the build process too), and after some experimenting, what I’ve found that reliably works is using a git server, used by everybody, and synchronizing the changes to subversion, so that jenkins or the integration server that you use can get the latest changes too. The easiest way to achieve this is by synchronizing only in one direction, git -> svn. This means that nobody commits to svn (except the git sync process).

    If this solution works for you, I documented how I did it, and built a couple of scripts to do it automatically. You can find it in this post.

    Git Baby is a git and github fan, let's start git clone.