Como eu trabalho com um repository git dentro de outro repository?

Eu tenho um repository de mídia Git onde eu estou mantendo todos os meus arquivos mestres e scripts JavaScript e CSS que eu vou usar em vários projetos.

Se eu criar um novo projeto que esteja em seu próprio repository Git, como faço para usar arquivos JavaScript do meu repository de mídia em meu novo projeto de uma maneira que faça com que não seja necessário atualizar as duas cópias do script quando fizer alterações ?

A chave é submodules git .

Comece a ler o capítulo Submódulos do Git Community Book ou do Manual do Usuário.

Digamos que você tenha o repository 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 repo …

Agora, o legal é que, sempre que você fizer alterações no MEDIA, poderá fazer isso:

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

Isso apenas registrou o fato de que o submódulo do MEDIA WITHIN PROJECT2 está agora na versão XYZ.

Ele oferece 100% de controle sobre qual versão do MEDIA cada projeto usa. git submodules são ótimos, mas você precisa experimentar e aprender sobre eles.

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

Considere o uso de subtree em vez de submódulos, isso facilitará muito a vida útil do seu repo. Você pode encontrar um guia mais detalhado no livro Pro Git .

Se eu entendi bem o seu problema, você quer o seguinte:

  1. Tenha seus arquivos de mídia armazenados em um único repository git, que é 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 enviar + push + pull o tempo todo)

Infelizmente não há uma solução definitiva para o que você quer, mas há algumas coisas pelas quais você pode facilitar sua vida.

Primeiro você deve decidir uma coisa importante: você quer armazenar para cada versão em seu repository de projetos uma referência à versão dos arquivos de mídia? Então, por exemplo, se você tem um projeto chamado example.com, você precisa saber qual style.css usou 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 repository para os arquivos de mídia e um para cada projeto
  2. crie um link simbólico em seus projetos que aponte para o repository de mídia clonado localmente. Você pode criar um link simbólico relativo (por exemplo, ../media) e assumir que todos farão o checkout do projeto para que o diretório de mídia esteja no mesmo lugar, ou escreva o nome do link simbólico em .gitignore, e todos possam decidir onde ele / ela coloca os arquivos de mídia.

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

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

  2. Use submódulos (conforme explicado na resposta 1). Dessa forma, você armazenará os arquivos de mídia em um repository e os projetos conterão apenas uma referência a uma versão de repository de mídia específica. Mas desta forma você normalmente terá muitas cópias locais do repository 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 terceira solução (links simbólicos ou submódulos). 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 você estiver pronto para commitar, você pode remover o symlink e remover o submódulo de volta, e então confirmar.

  2. Você pode adicionar uma das suas cópias do repository de mídia como um repository remoto para todos os seus projetos.

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

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

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

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

Você está livre para remover esses commits posteriormente (com git reset) porque você não os compartilhou com outros usuários.

Eu tive problemas com subtrees e submódulos que as outras respostas sugerem … principalmente porque estou usando o SourceTree e parece bastante bugs.

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

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 vincular os dois caminhos em um prompt de comando elevado. Certifique-se de usar o prefixo de link físico / J. Algo ao longo destas linhas: mklink / JC: \ projetos \ MainProject \ plugins C: \ projects \ SomePlugin

Você também pode usar caminhos de pastas relativos e colocá-los em um morcego para serem executados por cada pessoa quando eles fizerem o check-out do seu projeto.

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

Uma vez que a pasta foi ligada, você pode precisar ignorar a pasta dentro do seu repository principal que está fazendo referência a ela. Caso contrário, você é bom para ir.

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