views:

103

answers:

1

We have a base system that is customized for each client. The base lives in its own repository, and each client lives in its own repository (originally cloned from base).

The goal is to have the ability to add bug fixes/features to base, which can be propagated to clients, on demand.

So far the workflow has been as follows:

  • Make commits/topic branches for the base fixes/features: (on base, master) git commit -m "Fix admin typo"
  • Merge those changes into the client: (on client, master) git merge base/master. Obviously, this includes fixing any conflicts between base and the client's customizations.
  • Push the merge to client's origin: (on client, master) git push origin master
  • Our convention has been to pull with rebase (to keep history readable). So, then a different developer working on the client project would (on client, master) git pull --rebase origin master

It is at this point that we reach significant problems with that pull/rebase. Developers get conflicts in the pull/rebase done after a merge from the base into client. And its not just a few conflicts, it's many (for many of the commits being replayed?), and often code that particular developer never even touched. I think this is unreasonable and unsustainable.

What's the best solution here?

My only thought is to stop using rebase when pulling and deal with sloppy and hard-to-read logs, but I'd rather not have to do this. These client projects can live on for years, and I'd like to be able to still make some sense out of base system merges in the future.

+1  A: 

Let me get this straight on your repos:

  1. the main project is separate, called base
  2. each client project is cloned from base, only pulling updates
  3. the devs work from the public client_foo repo, and push/pull to/from that

The workflow is failing because one dev is rebasing client_foo branch onto the new commits from the base repo and pushing back to client_foo. This will end up breaking all the other devs using client_foo when they try to do their next pull. So you can't do that, and expect git to automatically handle it.

If it was just one dev per client repo, then maybe that would work. I'm assume that is not the case.

Options:

  1. Continue doing what your doing, but when the dev pushes the rebased client_foo branch (with the new base commits) back to the public client_foo repo, everyone else has to do a reset --hard on origin/master. If they keep all their unpushed changes in a private topic branch then, they have to rebase those back onto the new client_foo/master.

  2. Have your dev merge changes from base to client_foo. This will give you a merge commit on client_foo which you said you are trying to avoid, but it will give you the most accurate history. When your devs do a 'pull --rebase', you should no longer get the long list of conflicts you have now.

  3. Have your dev cherrypick the changes from base onto client_foo. This keeps your history linear, but git will no longer track that the cherrypick'd commits came from base. You'll have to come up with another way to track it.

I would say stick with #2 since that is the way git is supposed to work. However, someone else may think of a better non-obvious solution.

Casey