git multiple project merging
We will be forking a project into its own codebase, but it will closely follow the project it forked from.
I see it working like this:
Forked project will develop some initial changes to rebrand product. I wouldn’t want to share these changes with the original project, but going forward I want to merge changes.
The way we have it setup is separate repos that have the same history now and just add remotes for Each other.
The workflow I was thinking of was this:
We should try to work on feature branches and only have 1 commit per
feature so we can each to git cherry-pick . Whenever you
work on a feature and make a commit, just do git commit –amend in the
branch for the feature. When it is finalized I can cherry-pick the
I don’t like this because if the feature gets changed after cherry picking the developer needs to remember to NOT am end but create a new commit.
I would love a way to do this with a merge or rebase.
6 Solutions collect form web for “git multiple project merging”
- New branch for each feature
- Developer commits normally to the feature branch
- When merging to the master branch do:
git merge --squash -m 'new feature' branchname
Now, delete the branch!
git branch -D branchname
- If the developer needs to fix something or change the feature, he creates a new branch from the master. Everything else is the same.
The next merge will appear as a different commit on the master branch.
One possible way to structure this is with three repositories where one repository is the ‘white label version’ and the other two repositories are for the two front ends. The two front ends would reference the ‘white label version’ repository as a submodule.
With this structure you:
- have clearly called out the white label version as a shared resource that is ‘controlled’ but others
- yet, still allow for changes to the white label version by the two front ends
- allow the two front ends to develop independently with their repository contents.
If your two front ends are going to be similar, then they can be branches of one repository (but both dependent on the submodule). In this case, if you are merging back and forth between the two front ends, a good approach is to create a branch for each and every feature. Having a branch per feature frees you from the restriction of ‘one commit per branch’.  Depending on the nature of the feature branch you could a) cherry-pick all the commits using
<branch-base>..<branch-head>; or b) rebase everything on the branch into one commit and then cherry-pick that one commit or c) use merge/rebase to get the feature branch onto another branch (See the numerous examples from the
git rebase documentation, particularly the
--onto option.) [/edit]
Also here is a common, well-respected branching model with a discussion on feature branches.
[edit2] You can do this with one repository if you prefer. Keep three primary branches: white-label-dev, prod1-dev, prod2-dev and have the developers on each of the three teams operate only on their branches or their created branches off of their branches. When one team has something that should be shared, the ‘corporate integration lead’ will do the work of moving commits from that one team’s work to the other team’s branches. (Moving the commits as I described above.)
Your teams will need some discipline to avoid mucking with another team’s branches. But, if you’ve got a shared repository you can assign hooks to prevent pushes from the wrong team onto another team’s branches. [/edit2]
I think that you want to follow a similar procedure that Github uses for keeping forked projects updated.
To start off with would be the
whitelabel repo. This is the one that the other projects would fork from. Then the other projects would be a clone of the
whitelabel with the
whitelabel being set as the
upstream repo. Using this you would be able to do
git merge upstream/master or
git rebase upstream/master depending on the workflow.
The advantage is that you aren’t dealing having to keep straight the status of the main project. The other projects become their own forks and can be updated easily. Trying to
cherry-pick changes could get onerous easily especially with many commits. And doing this if one of the other projects wants to make changes to code that came from the original repo, you can manage that change much easier.
See the section about pulling in changes here:
If the fork is supposed to follow the footsteps of the forkee, better keep the fork in a branch in the master repository. Otherwise cherry-picking upstream changes and such will become unnecessarily hard.
Consider the benefits/costs of the forking repositories. Keeping all together just means dragging along the differences (presumably small?).
With gitolite you can control access to the branches if needed.
Assuming your branded code can all reside “cleanly” within the views/ directory
I suggest breaking views out into its own git repo and nesting it within your
main project. See here
You then have the option to either
- Use git branches in a single views repo for your forks, or
- Use separate views repos for each brand.
I’d prefer 1. since I’d anticipate parts of the views might need to be shared by either folding them back into white label, or cherry picking them from white label onto a brand.
Possible Project Working Layout
White Label Project layout;
- app_whitelabel/ <<-- clone of "app" repo on default branch + config/ + controllers/ + errors/ + views/ <<-- nested clone of "views" repo on branch "brand1"
Brand 1 Project layout;
- app_brand1/ <<-- clone of "app" repo on default branch + config/ + controllers/ + errors/ + views/ <<-- nested clone of "views" repo on branch "brand1"
Brand [n] Project layout;
- app_brand2/ <<-- clone of "app" repo on default branch + config/ + controllers/ + errors/ + views/ <<-- nested clone of "views" repo on branch "brand[n]"
- You don’t need to cherry pick to keep the shared code base up to date – just pull.
- Pulls of “app” will not affect “views”.
- Force you to keep to a clean mvc model – not a bad thing 🙂
- You / others need to be aware of a more complex project layout.
- Force you to keep to a clean mvc model – not always an easy thing 🙂
Assuming you have control over both repositories, the solution is simple.
Maintain branches for each feature.
Maintain a feature release branch.
When features are complete, merge the feature branch to the release branch and tag it.
If the feature needs a bug fix, fix it in the feature branch, and then remerge and re-tag it with a new version.
Your feature release branch is where you can cherry-pick updated features or bug fixes collectively. You can easily identify what version of the feature you have by the tag.
You can also easily look at the commit history on the feature release branch to see if there have been any updates.
Aside from these branches, I maintain a version release branch. Anything publicly released is QAd then committed to the version release branch.
Everyone’s local working repositories can have as many commits as they want or need without restriction.
The master repos have clearly deliniated branches with clearly segmented commits that continually get merged into feature release and version release.
Any forks are easy to update by following either the feature release branches or the version release branch. Any time they want, the forked repos can grab what is appropriate.
The yellow branch is the tagged feature release branch and the green is the version release branch. Forks can freely pull from either of those branches and know exactly what they are getting with cherry picks. Working Feature branches are all based on the release branch unless they are inter-dependent. Bug fixes are handled separately from release.
And like I said… all developers have their own working repos and can freely commit to those.