views:

352

answers:

2

I've just inherited a project which was maintained using Git. At one point, the code was deployed onto 3 separate systems and each system maintained their own decentralised Git respository.

Each of the 3 systems extended the original base system in 3 different directions. None of the 3 systems have been synchronised against each other. Some changes are on master branch, others are on new branches.

How can I bring the 3 different sources together so that I can:

  1. find a common base to work with;
  2. find out which changes are bug fixes which should be applied across all 3 systems; and
  3. maintain the 3 systems in a sane way so that there is only one common branch and separate out the customisations required for the 3 different systems?
+10  A: 

I would probably start by pushing all the repositories to separate branches in a central repository, from which I can rebase, merge etc between branches easily.

A good visualization tool such as git-age, gitnub, gitx, giggle can work wonders, but your task will probably be rather tedious unless you can find the branching points. If there are similar patches applied to all branches you can use (interactive) rebase to reorder your commits such that they are in the same order. Then you can start 'zipping up' your branches, moving the branch-point upwards by putting commits into master. A nice description on how to reorder commits using rebase can be found here.

Chances are the actions you need to take are described in the links provided by the Git Howto Index. A good cheat sheet is always nice to have within reach. Also, I suspect the followup to Eric Sinks post "DVCS and DAGs, Part 1" will contain something useful (It didn't, but was an interesting read nontheless).

Additional good-to-have links are: Git Magic, Git Ready and SourceMage Git Guide

I hope all the repos had good commit messages that tell you the purpose of each patch, it's that or code review :)

As for how to maintain customizations we've had luck with the following:

We started by separating (or keeping separate) the customized code from the generic code. Then we've tried two approaches; both which worked fine:

  1. All deployments got their own repositories where the customization was kept.
  2. All deployments got their own branch in a 'customization'-repository.

After the first deployment and seeing that the second was a fact we spent some time trying to foresee future customization/cutting points to reduce duplication across the customized repos (alt. 1, which is the approach we currently use) and in the base/core repo.

And yes, we do try to refactor mercilessly whenever we notice the core/customization split slipping :)

Henrik Gustafsson
Thanks for your help. I'm new to git, so probably a bit more challenging for me than others who are used to it.
Charles Darke
Hey, I had an excuse to dump some links :) Although you'll probably get more and better answers if your questions are more specific in the future
Henrik Gustafsson
Oh, and it's kind of good manners to accept an answer if you find it helpful (no hurry, wait a bit...). You can always change your mind about it later if a better answer comes around.
Henrik Gustafsson
Thanks. How do you actually push into different branches without it merging automatically?
Charles Darke
Worked it out. Created new branches in each of the separate systems then git fetched from new central location.
Charles Darke
+1  A: 

OK. After a big of a slog, I've managed to do it. For anybody else embarking on a similar task, it will involve a lot of:

git rebase

commands and when things got screwed up:

git reflog

followed by

git reset --hard HEAD@{ref}
Charles Darke