Como trabalho com um repositório git em outro repositório?

283

Eu tenho um repositório de mídia Git em que mantenho todos os meus arquivos e scripts mestres JavaScript e CSS que vou usar em vários projetos.

Se eu criar um novo projeto que esteja em seu próprio repositório Git, como uso os arquivos JavaScript do meu repositório de mídia no meu novo projeto de uma maneira que permita que eu não precise atualizar as duas cópias do script ao fazer alterações ?

Brent O'Connor
fonte
Consulte a resposta da subárvore abaixo em @ ruslan-kabalin. Nota: ganchos de pré-confirmação (ou supercomissão ) são uma maneira de lidar com a objeção levantada por Robert Dundon
Hedgehog

Respostas:

347

A chave é submódulos git .

Comece a ler o capítulo Submodules do Git Community Book ou do Manual do Usuário

Digamos que você tenha o repositório PROJECT1, PROJECT2 e MEDIA ...

cd /path/to/PROJECT1
git submodule add ssh://path.to.repo/MEDIA
git commit -m "Added Media submodule"

Repita no outro repositório ...

Agora, o mais interessante é que, sempre que você confirmar alterações no MEDIA, poderá fazer o seguinte:

cd /path/to/PROJECT2/MEDIA
git pull
cd ..
git add MEDIA
git commit -m "Upgraded media to version XYZ"

Isso acabou de registrar o fato de que o submódulo MEDIA WITHIN PROJECT2 está agora na versão XYZ.

Dá a você 100% de controle sobre qual versão do MEDIA cada projeto usa. Os sub-módulos git são ótimos, mas você precisa experimentar e aprender sobre eles.

Com grande poder, vem a grande chance de ser mordido na garupa.

gahooa
fonte
Esse fluxo de trabalho me faz lembrar de usar um módulo de NPM privada stackoverflow.com/questions/7575627/...
cyrf
Se você preferir que o padrão seja a versão mais recente, poderá adicionar um script para propagar o commit MEDIA para todos os projetos dependentes.
precisa saber é o seguinte
3
Como isso se integra ao github?
theonlygusti
26

Considere usar subárvore em vez de submódulos, isso facilitará muito a vida dos usuários de repositório. Você pode encontrar um guia mais detalhado no livro Pro Git .

Ruslan Kabalin
fonte
6
Aqui está outro artigo informativo sobre subárvore vs. submódulo: blogs.atlassian.com/2013/05/…
Benny Neugebauer
3
De acordo com esse artigo, uma das desvantagens é:> A responsabilidade de não misturar códigos de super e subprojetos está em você. Ninguém tem tempo para isso (IMO)
Robert Dundon
20

Se entendi bem o seu problema, você deseja o seguinte:

  1. Tenha seus arquivos de mídia armazenados em um único repositório git, usado por muitos projetos
  2. Se você modificar um arquivo de mídia em qualquer um dos projetos em sua máquina local, ele deverá aparecer imediatamente em todos os outros projetos (para que você não queira confirmar + empurrar + puxar o tempo todo)

Infelizmente, não existe uma solução definitiva para o que você deseja, mas existem algumas coisas pelas quais você pode facilitar sua vida.

Primeiro, você deve decidir uma coisa importante: deseja armazenar para cada versão no repositório do projeto uma referência à versão dos arquivos de mídia? Por exemplo, se você tem um projeto chamado example.com, precisa saber qual style.css foi usado há 2 semanas ou o mais recente é sempre (ou principalmente) o melhor?

Se você não precisa saber disso, a solução é fácil:

  1. crie um repositório para os arquivos de mídia e um para cada projeto
  2. crie um link simbólico em seus projetos que aponte para o repositório de mídia clonado localmente. Você pode criar um link simbólico relativo (por exemplo, ../media) e assumir que todos farão o check-out do projeto para que o diretório de mídia esteja no mesmo local ou escrever o nome do link simbólico em .gitignore, e todos poderão decidir onde ele coloca os arquivos de mídia.

Na maioria dos casos, no entanto, você deseja conhecer essas informações de versão. Nesse caso, você tem duas opções:

  1. Armazene todos os projetos em um grande repositório. A vantagem desta solução é que você terá apenas 1 cópia do repositório de mídia. A grande desvantagem é que é muito mais difícil alternar entre versões do projeto (se você fizer o checkout para uma versão diferente, sempre modificará TODOS os projetos)

  2. Use submódulos (como explicado na resposta 1). Dessa forma, você armazenará os arquivos de mídia em um repositório e os projetos conterão apenas uma referência a uma versão específica de repositório de mídia. Porém, dessa forma, você normalmente terá muitas cópias locais do repositório de mídia e não poderá modificar facilmente um arquivo de mídia em todos os projetos.

Se eu fosse você, provavelmente escolheria a primeira ou a terceira solução (links ou submódulos simbólicos). Se você optar por usar submódulos, ainda poderá fazer muitas coisas para facilitar sua vida:

  1. Antes de confirmar, você pode renomear o diretório do submódulo e colocar um link simbólico em um diretório de mídia comum. Quando estiver pronto para confirmar, você pode remover o link simbólico e remover o submódulo novamente e confirmar.

  2. Você pode adicionar uma de sua cópia do repositório de mídia como um repositório remoto a todos os seus projetos.

Você pode adicionar diretórios locais como um controle remoto desta maneira:

cd /my/project2/media
git remote add project1 /my/project1/media

Se você modificar um arquivo em / my / project1 / media, poderá confirmá-lo e retirá-lo de / my / project2 / media sem enviá-lo para um servidor remoto:

cd /my/project1/media
git commit -a -m "message"
cd /my/project2/media
git pull project1 master

Você pode remover esses commits mais tarde (com redefinição do git) porque não os compartilhou com outros usuários.

Gyim
fonte
1
para projetos relacionados à Web em que você trabalha na wwwpasta do Apache , você deve colocar um .htaccessarquivo na raiz da wwwpasta ou do seu projeto, Options +FollowSymLinksnela, ou melhor ainda <IfModule mod_rewrite.c>{new line}Options +FollowSymLinks{new line}RewriteEngine on{new line}</IfModule> (substituir {new line}pela nova linha real)
3

Eu tive problemas com subárvores e submódulos que as outras respostas sugerem ... principalmente porque estou usando o SourceTree e parece bastante incorreto.

Em vez disso, acabei usando o SymLinks e isso parece funcionar bem, por isso estou postando aqui como uma possível alternativa.

Há um guia completo aqui: http://www.howtogeek.com/howto/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/

Mas basicamente você só precisa mklink os dois caminhos em um prompt de comando elevado. Certifique-se de usar o prefixo do link físico / J. Algo nesse sentido: mklink / JC: \ projects \ MainProject \ plugins C: \ projects \ SomePlugin

Você também pode usar caminhos de pasta relativos e colocá-lo em um bastão para ser executado por cada pessoa quando eles verificarem seu projeto pela primeira vez.

Exemplo: mklink / J. \ Assets \ TaqtileTools .. \ TaqtileHoloTools

Depois que a pasta estiver vinculada, talvez seja necessário ignorá-la no repositório principal que a está referenciando. Caso contrário, você está pronto para ir.

Observe que eu excluí minha resposta duplicada de outra postagem, pois ela foi marcada como uma pergunta duplicada para esta.

ickydime
fonte