How I've decided to coordinate multiple git repos for a single project
I'm increasingly using git for my own projects (partly because I
keep putting them on Github),
and this has brought up a problem. On the one hand, I like linear
VCS histories (even if they're lies); I don't plan on having branches
be visible in the history of my own repos unless it's clearly
necessary. On the other hand, I routinely have multiple copies of
my repos spread across multiple machines. In theory I always keep
all repos synchronized with each other before I start working in
one and make commits. In practice, well, not necessarily, and the
moment I screw that up a straightforward
git pull/push workflow
to propagate changes around creates merges.
My current solution goes like this. First, I elect one repo as the
primary repo; this is the repo which I use to push changes to Github,
for example. To avoid merge commits ever appearing in it, I set it
to only allow fast-forward merges when I do '
git pull', with:
git config pull.ff only
This insures that if the primary repo and a secondary repo wind up with different changes, a pull from the secondary into the primary will fail instead of throwing me into creating a merge commit that I don't want. To avoid creating merge commits when I pull the primary into secondaries, all other repos are set to rebase on pulls following my standard recipe. This is exactly what I want; if I pull new changes from the primary into a secondary, any changes in the secondary are rebased on top of the primary's stuff and linear history is preserved. I can then turn around and pull the secondary's additional changes back into the primary as a fast-forward.
If I use '
git push' to move commits from one repo to another I'm
already safe by default, because
git push normally refuses to do
anything except fast-forward updates of the remote. If it complains,
the secondary repo involved needs a rebase. I can either do the
rebase with '
git pull' in the secondary repo, or in the primary
repo I can push to the remote tracking branch in the secondary with
git push <machine>:<directory> master:origin/master' and then
do a '
git rebase' on the secondary.
(Using a push from the primary usually means that my ssh activity flows the right way. And if I'm pushing frequently I should configure a remote for the secondary or something. I'm not quite hep on git repo remotes and remote tracking branches just yet, though, so that's going to take a bit of fumbling around when I get to it.)