SVN: equivalente externo no Git?

177

Eu tenho dois projetos SVN em uso de outro repositório SVN usando svn: externals .

Como posso ter a mesma estrutura de layout de repositório no Git?

dsimard
fonte
Você deve examinar os submódulos do Git . Deve permitir quase exatamente o que você está procurando.
foxxtrot
7
Alguém tem uma nova resposta para isso nos últimos 4 anos, ou o mundo do git é o mesmo hoje?
DougW
4
@ DougW Sim, tenho uma nova resposta abaixo : git submoduleagora pode emular svn:external(desde março de 2013).
VonC 6/08/13
Para a versão mais recente do Git, sugiro ler sobre os submódulos do Git na documentação oficial do Git.
Bulki S Maslom

Respostas:

134

O Git tem duas abordagens semelhantes, mas não exatamente equivalentes ao svn: externals:

  • Mesclagens de subárvores inserem o código do projeto externo em um subdiretório separado dentro do seu repositório. Isso tem um processo detalhado de configuração e é muito fácil para outros usuários, porque é incluído automaticamente quando o repositório é retirado ou clonado. Essa pode ser uma maneira conveniente de incluir uma dependência no seu projeto.
    É fácil extrair alterações do outro projeto, mas complicado enviar as alterações de volta. E se o outro projeto precisar se mesclar do seu código, os históricos do projeto serão mesclados e os dois projetos se tornarão efetivamente um.

  • Os sub-módulos Git ( manual ) vinculam-se a um commit específico no repositório de outro projeto, como svn: externals com um-rargumento. É fácil configurar os submódulos, mas todos os usuários precisam gerenciar os submódulos, que não são incluídos automaticamente nos checkouts (ou clones).
    Embora seja fácil enviar as alterações de volta para o outro projeto, isso pode causar problemas se o repositório for alterado. Portanto, geralmente não é apropriado enviar as alterações de volta para um projeto em desenvolvimento ativo.

Paulo
fonte
17
FYI, agora é possível especificar as revisões específicas com svn: externals agora (? Desde 1.5 ou 1.6 acredito)
Nate Parsons
9
Para sua informação, os submódulos git podem ser gerenciados e confirmados automaticamente. O git cria um arquivo .gitmodules que pode / deve ser confirmado da mesma forma que o arquivo .gitignore. Veja [ git-scm.com/book/en/Git-Tools-Submodules] para mais informações.
Mikijov
5
@NateParsons Sempre foi possível especificar números de revisão exatos com svn:externals. Com a revisão 1.5, a sintaxe foi alterada para um formato mais flexível. O que foi adicionado foi o endereço relativo de URL.
David W.
@NateParsons, mas é possível omitir revisões com submódulos git ...> _>
Trejkaz
Eu acho que não é possível git submodule arquivos únicos como com svn: externals
user1911091 27/03
38

Como mencionei em " Atualização da nova versão do submódulo Git ", você pode obter o mesmo recurso externo do SVN com os submódulos Git 1.8.2:

git config -f .gitmodules submodule.<path>.branch <branch>

Isso é suficiente para um submódulo seguir uma ramificação (como no commit MAIS RECENTE de uma ramificação remota de um repositório upstream do submódulo ). Tudo que você precisa fazer é:

git submodule update --remote

Isso atualizará o submódulo.

Mais detalhes estão em " git submodulerastreamento mais recente ".

Para converter um submódulo existente em um rastreamento de uma ramificação : consulte todas as etapas em " Sub-módulos Git: Especifique uma ramificação / marca ".

VonC
fonte
Você pode fazer checkout parcial como com svn:externals?
nowox 2/08
@nowox Sim, você pode ter uma verificação esparsa (git 1.7+ stackoverflow.com/a/2372044/6309 ) associada a submodules ( stackoverflow.com/a/17693008/6309 )
VonC
Infelizmente todos os esparsos relacionados verificação geral respostas não dá qualquer exemplo :( Eu vou tentar escrever um exemplo Gist para isso ...
nowox
Ainda há um problema com isso. Você ainda precisa obter todo o histórico de um repositório em que precisa apenas de uma pequena parte. No meu caso, é 100kB acima de 2GB. É claro que posso usar, --depthmas isso realmente não resolve o problema.
nowox 3/08
@nowox É melhor fazer uma nova pergunta explicando exatamente qual é o seu caso de uso: não faço ideia se o seu repositório de 2 GB é um submódulo ou um repositório principal com o submódulo e o que exatamente você precisa extrair dele.
VonC 3/17/17
3

Eu sou o autor da ferramenta gil (git links)

Tenho uma solução alternativa para o problema - ferramenta gil (git links)

Ele permite descrever e gerenciar dependências complexas de repositórios git.

Também fornece uma solução para o problema de dependência dos sub-módulos recursivos git .

Considere que você possui as seguintes dependências do projeto: exemplo de gráfico de dependência do repositório git

Em seguida, você pode definir o .gitlinksarquivo com a descrição da relação dos repositórios:

# Projects
CppBenchmark CppBenchmark https://github.com/chronoxor/CppBenchmark.git master
CppCommon CppCommon https://github.com/chronoxor/CppCommon.git master
CppLogging CppLogging https://github.com/chronoxor/CppLogging.git master

# Modules
Catch2 modules/Catch2 https://github.com/catchorg/Catch2.git master
cpp-optparse modules/cpp-optparse https://github.com/weisslj/cpp-optparse.git master
fmt modules/fmt https://github.com/fmtlib/fmt.git master
HdrHistogram modules/HdrHistogram https://github.com/HdrHistogram/HdrHistogram_c.git master
zlib modules/zlib https://github.com/madler/zlib.git master

# Scripts
build scripts/build https://github.com/chronoxor/CppBuildScripts.git master
cmake scripts/cmake https://github.com/chronoxor/CppCMakeScripts.git master

Cada linha descreve o link git no seguinte formato:

  1. Nome exclusivo do repositório
  2. Caminho relativo do repositório (iniciado a partir do caminho do arquivo .gitlinks)
  3. Repositório Git que será usado no comando git clone Ramificação do repositório para checkout
  4. Linha vazia ou a linha iniciada com # não é analisada (tratada como comentário).

Finalmente, você deve atualizar seu repositório de amostras raiz:

# Clone and link all git links dependencies from .gitlinks file
gil clone
gil link

# The same result with a single command
gil update

Como resultado, você clonará todos os projetos necessários e os vinculará de maneira adequada.

Se você deseja confirmar todas as alterações em algum repositório com todas as alterações em repositórios vinculados a filhos, é possível fazê-lo com um único comando:

gil commit -a -m "Some big update"

Os comandos pull, push funcionam de maneira semelhante:

gil pull
gil push

A ferramenta Gil (git links) suporta os seguintes comandos:

usage: gil command arguments
Supported commands:
    help - show this help
    context - command will show the current git link context of the current directory
    clone - clone all repositories that are missed in the current context
    link - link all repositories that are missed in the current context
    update - clone and link in a single operation
    pull - pull all repositories in the current directory
    push - push all repositories in the current directory
    commit - commit all repositories in the current directory

Mais sobre o problema de dependência dos sub-módulos recursivos git .

cronoxor
fonte
1
Você deve colocar um aviso no topo da postagem dizendo que você é o autor gil.
Daniel Kamil Kozar