Oddzielny!
W rzeczywistości prawdopodobnie miałbym trzy repozytoria, jedno dla klienta i odpowiednie biblioteki tylko dla klienta, jedno dla serwera (i odpowiednich bibliotek) i jedno dla bibliotek współdzielonych (zawierających interfejsy API, które ujawniają funkcjonalność między tymi dwoma oraz wszelkie inne wspólne kody). Myślę, że to naprawdę klucz, wspólny kod powinien przejść do osobnego repozytorium. W ten sposób możesz mieć pewność, że interoperacyjność między twoim klientem a serwerem jest zawsze w tej samej wersji ORAZ jest odizolowana od projektu każdego z jej konsumentów.
Oczywiście nie zawsze jest to możliwe, w zależności od konkretnej struktury komunikacyjnej, której używasz, ale prawdopodobnie zostanie udostępniony kod, który dyktuje format obiektów przesyłania danych lub kroki uzgadniania w niestandardowym protokole (lub w innym przykładzie) .
Zakładając, że masz dość przyzwoitą konfigurację ciągłej integracji i kontroli jakości (dość duże założenie, z mojego doświadczenia, ale i tak zamierzam to zrobić. Jeśli nie masz działu kontroli jakości, powinieneś przynajmniej zdobyć trochę CI), nie powinieneś nie musisz używać wzorca pojedynczej operacji repo jako obrony przed możliwymi błędnymi dopasowaniami kodu, albo twój serwer CI oznaczy interoperacyjność bibliotek, albo twój zespół kontroli jakości wyłapie błędy w czasie wykonywania (lub, co lepiej, testy jednostkowe).
Zalety podzielonych repozytoriów polegają na możliwości osobnej wersji oddzielnych części systemu. Chcesz wziąć kopię serwera z zeszłego tygodnia i uruchomić go z klientem w tym tygodniu, aby spróbować zablokować źródło problemu z wydajnością? Bez obaw.