Reputation: 21
I am now faced with a challenge of organising two projects' code in Git. There are two software A and B, one could say that B is the same as A, only that it has some additional modules (more features). So the problem now is, I have two projects, but I cannot simply separate them into two repositories since they share 4/5 of the same files. A and B are compiled to be two separate software releases, so how can I organise them such that it makes sense?
I have thought about having 2 repositories, but how can I make it work so that when I change something in A, B is also updated? How does this work in Git (sorry I have not used Git at a more advanced level yet)? And if it will be possible for me to compile B (make a release) without compiling A at the same time? Any help would be appreciated, and if I didn't describe something properly please let me know. Thank you so much in advance.
Upvotes: 1
Views: 488
Reputation: 164769
You have a few options, and they should be used in combination.
Configuration can mean turning features on and off with configuration flags. It can also mean having separate templates for A and B. A and B become saved configurations. This is probably best for changes which are mostly cosmetic, or if the features are fairly integral to the process like database and API credentials.
Other bits will make sense to extract into modules. Subclasses allowing connections to new databases or APIs for example.
Initially you can manage this all as a single repository. A and B could be as simple as separate directories within your repository. It might look like this.
base/
modules/
feature1/
feature2/
releases/
A/
config
templates/
B/
config
templates/
Everything in one repo is simple and convenient. It will serve you initially and it might be all you need. But it encourages wielding everything tightly together. Why write a well thought out API when you can just change everything at once?
If you find you need more modularity, you'd extract the base, each of the modules, and each of the releases into their own repositories. This brings up dependency management.
Initially, A and B could pull in their dependent base and module repositories as Git Submodules. This will work in the short run, but it's a poor way to manage dependencies and, again, encourages binding things tightly together.
Finally you'd manage each repository separately as their own project. Make releases as you would for any project using your language's normal system for distributing modules (Ruby gems, Javascript npm, Python packages, etc...), probably using a private module repository. A and B then become installations using your language's dependency system to choose which extra features to install.
This takes some practice to get right, and for many internal projects full releases and dependency management is overkill. Start by reorganizing everything into subdirectories in one repository, this will likely be challenge enough, and see if you need more.
Upvotes: 0
Reputation: 4140
Short answer:
Tribulation, trial and eventual brain damage
Long answer:
It depends. Depending on your language, frameworks, etc, you should aim to isolate the "additional modules (more features)" into a separate software package and manage them in their own repository. This way you can merely change configuration (npm package.json, python Pipfile, ruby gemfile, etc) to add the additional features and enable them using environment variables. Each "project" gets its own configuration files that would enable a subset or superset of features.
Generally speaking, this is time consuming (every release cycle becomes more resource consuming to ensure both projects are functioning properly). Figure out a way to have one repository that only contains reused code for both projects, and isolate additional modules a one or more separately maintained packages.
It still depends on specific requirements, software languages, tools, etc.
Upvotes: 1