As I can read from the whole description it seems that during development time (and in production also I suppose) all 3 projects are really tight coupled. So I'll use the first scenario for convenience of work. I'll also build all the projects together, tagged them together and keep same versioning pattern - in general even if it's separated this is a single project.
The first scenario can be carried on till no 3rd party (external) application/library/team uses any of the projects (I suppose it could only be C project). Then backward compatibility issues/pull requests and other may happen and the mentioned projects should be separated. If there's no chance that such situation takes place You shouldn't bother too much. But remember about good (semantic) versioning, and tagging the repository to be always sure which version is deployed to which environment.
UPDATE
After question update.
If You've dependency paths like A->B->C
and D->B->C
I'll reorganize the project structure. B
should become a subproject of both A
and D
or maybe not a subproject but an external library that is added to these projects. B
and C
should be a separate project with B
dependent on C
.
All three projects (A
,D
, B with C
) should be separately versioned (especially B with C
) because this is a common part for clients (A
and D
).
Now, for a convenient development You can add to A
and D
snapshot libs that will be built often on CI server and then update to artifactory. This will allow You to introduce changes to B
and have them visible fast in the projects A
and D
. But stable release of B
(and hence C
) should be maintained totally separately.
I hope I understood the problem well and helped You a bit.
P.S. Please consider also using gitflow
- a branching model. Then You can used SNAPSHOT versions in dev branch and a stable version of B
in release.