Git pull with rebase causing excessive conflicts. How can I fix our workflow?
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 bein开发者_运维技巧g 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.
Let me get this straight on your repos:
- the main project is separate, called
base
- each client project is cloned from
base
, only pulling updates - the devs work from the public
client_foo
repo, andpush
/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:
Continue doing what your doing, but when the dev pushes the rebased
client_foo
branch (with the newbase
commits) back to the publicclient_foo
repo, everyone else has to do areset --hard
onorigin/master
. If they keep all their unpushed changes in a private topic branch then, they have torebase
those back onto the newclient_foo/master
.Have your dev
merge
changes frombase
toclient_foo
. This will give you a merge commit onclient_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.Have your dev
cherrypick
the changes frombase
ontoclient_foo
. This keeps your history linear, but git will no longer track that thecherrypick
'd commits came frombase
. 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.
精彩评论