I don't want to put them in the same repo as subfolders because each have its own dependencies and configuration files, and also I don't want to have their commits mixed up.
Ok, you don't want their commits mixed up.
I don't want to leave them as separate repos since I have issues on the parent repo that might require work to be done on ,say, both the back end and mobile repos,and i would like the have the issue solved on the same branch...
...except when you DO want their commits mixed up. ;)
Where do I have it wrong?
If you have to habitually change multiple repositories simultaneously, you may want to consider whether they're actually a single repository. There's two good ways to handle this, subrepositories are not one of them.
One repo
One is to make them a single repository. If they're all pieces of the same project, and they have changes which depend on each other, they're a single repository. It's ok for them to be subfolders with their own configuration and dependencies, this is fairly common for large projects that need to be developed together, but split for distribution.
The downside is developers are likely to take advantage of this and tightly bind the client code to the backend. Without clear separations between the projects the backend API is likely to get sloppy. The clients are more likely to take advantage of undocumented backend features making the whole system brittle and resistant to change. Adding a new client, like maybe tharwa-api
, will become more difficult.
If you have 3rd parties writing their own clients for the tharwa-backend
, they're at a disadvantage. client
and web
are in a privileged position, they can be in lock-step with backend
. 3rd party developers aren't so lucky, and your project will be harder to contribute to.
And once you wield your projects together, you're not likely to ever pull them apart again.
Many repos, strict dependencies.
The other is to more strictly enforce your encapsulation between the pieces by each repo treating the other as normal dependencies. In your login
example...
- Implement, test, and commit the change on
backend
.
- Release
backend
, even if only for internal distribution.
- Test
web
and mobile
against the new backend
to ensure backwards compatibility is maintained.
- Some dependency mechanisms allow drawing dependencies directly from a Git repo.
- Have
web
and mobile
update their backend
dependency and use the new feature.
Now it harder for developers to cheat. The extra step of a release (which shouldn't take more than a minute or two) provides an "air gap". backend
has to develop its own unit, integration, and acceptance tests; it can't rely on the clients to do it for them. The clients have to be more robust and adhere more strictly to the backend API. With the backend and client decoupled, it will be easier to make radical changes to the internals of each.
Developers can still make lockstep changes, but they're now explicit. Making them explicit discourages their use, it prevents devs from getting lazy.
But it does add some more overhead. backend
changes must be fully thought through, developed, and documented. The backend
API must be more fully developed and robust. The clients must adhere more closely to the API. All this is good software engineering and will speed things up in the mid and long-term.
Why not submodules?
Submodules provide most of the upsides of a single repo, but adding a confusing feature. It also provides all of the downsides of a single repo, plus one more: a lack of coordination.
With a single repo, one commit is one commit. One branch is one branch. With submodules is it's difficult to know by looking at a single repository which commits must be coordinated between all repositories. These coordinated commits can happen at any time, without warning, and it's difficult to know.
You'll want some procedures and mechanisms to track and coordinate these commits. You could build this all yourself through trial and error, maybe something with tags or special commit messages.
Or you could use an existing release dependency system.
Which you choose depends on your project. However I'd recommend you try the full decoupling and see how it goes. It encourages good software engineering practices. And you can always put them back together later, it's difficult to go the other way around.