Separado!
Na verdade, eu provavelmente teria três repositórios, um para o cliente e as bibliotecas somente para clientes correspondentes, um para o servidor (e as bibliotecas correspondentes) e um para as bibliotecas compartilhadas (incorporando as interfaces API que expõem a funcionalidade entre os dois , além de qualquer outro código compartilhado). Eu acho que essa é realmente a chave, o código compartilhado deve entrar em um repositório separado. Dessa forma, você pode garantir que a interoperabilidade entre seu cliente e servidor esteja sempre na mesma versão E seja isolada do design de cada um de seus consumidores.
Obviamente, isso nem sempre é possível, dependendo da estrutura de comunicação específica que você está usando, mas é provável que haja um código compartilhado que dite o formato dos objetos de transferência de dados ou as etapas do handshake no seu protocolo personalizado (ou outro exemplo) .
Supondo que você tenha uma configuração de Integração Contínua e controle de qualidade razoavelmente decente (uma suposição bastante grande, na minha experiência, mas ainda vou fazer. Se você não tem um departamento de controle de qualidade, pelo menos deve obter um IC), deve não é necessário usar o padrão de repositório único como uma defesa contra possíveis correspondências incorretas de código; o servidor de IC sinalizará a interoperabilidade da biblioteca ou a equipe de controle de qualidade detectará erros de tempo de execução (ou, melhor ainda, os testes de unidade).
Os benefícios dos repositórios divididos estão na capacidade de versão separada de partes separadas de um sistema. Deseja tirar uma cópia do servidor da semana passada e executá-la com o cliente desta semana, para tentar bloquear a raiz de um problema de desempenho? Não se preocupe.