Ramificando um subdiretório enquanto mantém commits de outros diretórios

5

Atualmente, tenho um único repositório do Git preexistente para uma solução cliente / servidor que contém três subdiretórios para três subprojetos:

/client  - An Angular2 SPA application (client-side TypeScript)
/dtos    - Language-agnostic web-service DTO (data contract) definitions written in T4
    /client - T4-generated TypeScript typings *.d.ts files
    /server - T4-generated C# DTO classes
/server  - The web-service

Até agora, tudo isso está em uma única ramificação master , com ramificações dev/ temporárias apropriadas que são mescladas quando o trabalho é concluído:

o--o--o--o - master
 \   /
  o-o      - dev/foo

Precisamos fazer alguns testes A / B (ou melhor, A / B / C / D) em opções UX radicalmente diferentes no projeto Angular2 - gostaria de ramificar para cada opção UX, para gerar construções diferentes podemos testar, depois que nossa pesquisa sobre UX estiver concluída, mesclaremos essa ramificação específica de volta em master para o restante do projeto:

o             - master
 \
  o--o--o---o - ux/red-background
   \
    o--o----o - ux/new-sidebar
        \
         o--o - ux/new-sidebar-and-banner

No entanto, só quero desmembrar o diretório /Client - portanto, os diretórios /DTOs e /Server sempre contêm o código mais recente.

No SVN e no TFS isto é facilmente realizável porque as ramificações podem ser feitas a partir de subdiretórios, não apenas de todo o repositório (como estão com o git), então se fosse um projeto SVN eu faria algo assim:

cd trunk  # this is the solution root with the client, dtos and server directories
svn copy ^/trunk/client ^/branches/red-background
svn copy ^/branches/red-background ^/branches/new-sidebar
# then after some commits to 'new-sidebar'...
svn copy ^/branches/new-sidebar ^/branches/new-sidebar-and-banner

Em seguida, para criar a solução com cada ramificação diferente de /client , modificamos o link simbólico:

cd trunk
# to 'checkout' the red-background version prior to building:
ln -s branches/red-background client
# or the new-sidebar version:
ln -s branches/new-sidebar client

A principal vantagem dessa abordagem é que os commits podem continuar sendo feitos nos diretórios /dtos e /server sem afetar client - independentemente de qual ramificação de client esteja sendo trabalhada. / p>

Considerando que, com o git, uma ramificação é uma linha de tempo separada inteiramente, então esse cenário se torna impossível.

Entendo que, para obter o resultado desejado, ainda precisarei criar ramificações diferentes para cada versão a ser testada ou criada, mas as alterações em /dtos ou /server ainda precisariam acontecer em master (apenas como em trunk no SVN), mas após cada commit todo mundo trabalhando nas diferentes ramificações client precisaria rebase ou merge de master , e isso tem o potencial de ficar realmente feio (especialmente se pessoas individuais rebase de vários commits para /server escolhendo seus próprios pontos de rebase - eles podem acabar com codebases idênticas, mas diferentes hashes de commit).

Qual é a solução?

(Outra solução é mover client para seu próprio repositório git - depois mesclá-lo novamente no repositório da solução quando tudo estiver pronto - não sou contra isso, mas vamos fingir que atingimos nossa contagem máxima de recompras na nossa conta organizacional do GitHub)

    
por Dai 26.05.2017 / 01:43
fonte

1 resposta

0

A maneira ideal é mover o cliente para o seu próprio repositório e torná-lo um submódulo do superprojeto. Mas se você não quiser criar um novo repositório, você pode tentar uma dessas soluções.

Vários diretórios em um ramo

Se você é capaz de configurar seu projeto para usar diretório / client_A em vez de / client, então você pode clonar o diretório / cliente para vários diretórios

  • / client_A
  • / client_B
  • / client_C

e separar o desenvolvimento em cada um desses diretórios. Até este ponto, basta usar apenas o branch master.
Mais tarde, quando você decidir "mesclar" o diretório / client_A no diretório / cliente, crie uma ramificação chamada, por exemplo, branch_A. Neste ramo, substitua o conteúdo do diretório / cliente pelo conteúdo do diretório / client_A, exclua o diretório / client_A e confirme esse estado. Em seguida, mescle branch_A para dominar e resolver conflitos, se houver.
Faça o mesmo com os diretórios / client_B e / client_C se você quiser "mesclá-los" com o diretório / cliente. Você pode escolher horários diferentes para "mesclar" diretórios / client_A, / client_B e / client_C no diretório / cliente.

Vários ramos sem diretórios de clonagem

Escolha um horário de início adequado e faça quantas ramificações do mestre quiser

  • branch_A
  • branch_B
  • branch_C

A partir desta hora de início, use estritamente

  • mestre para mudanças em diretórios diferentes de / client (/ dtos e / server)
  • branch_A, branch_B, branch_C para alterações no diretório / client

Use branch_A, branch_B, branch_C para criar diferentes versões do seu projeto. Mesclar ramo mestre nesses ramos antes de construir. Evite mesclar essas ramificações no ramo mestre (na direção oposta). Mais tarde você pode mesclar branch_A em master. Mas depois de fazer isso, você não pode mesclar o mestre em branch_B ou branch_C. Isso significa que você precisa escolher a hora de término adequada e mesclar todas as ramificações branch_A, branch_B, branch_C no master neste momento.

    
por 31.05.2017 / 00:20
fonte

Tags