Como migrar um repositório SVN com histórico para um novo repositório Git?


1509

Eu li o manual do Git, FAQ, curso intensivo do Git - SVN, etc. e todos explicam isso e aquilo, mas em nenhum lugar você pode encontrar uma instrução simples como:

Repositório SVN em: svn://myserver/path/to/svn/repos

Repositório Git em: git://myserver/path/to/git/repos

git-do-the-magic-svn-import-with-history \
svn://myserver/path/to/svn/repos \
git://myserver/path/to/git/repos

Não espero que seja tão simples e não espero que seja um único comando. Mas espero que não tente explicar nada - apenas para dizer que medidas a serem tomadas, dado este exemplo.


6
Está ficando mais fácil, acabei de concluir e documentei minhas descobertas com a ajuda de SO jmoses.co/2014/03/21/moving-from-svn-to-git.html
John Moses

Use a resposta de Casey abaixo, mas antes de executar o comando "svn clone ...", veja como adicionar a linha "Visual SVN Server" extra ao seu arquivo user.txt ... aqui: stackoverflow.com/questions/8971208/ ...
MacGyver

1
Além disso, se você tiver a opção "tornar email privado marcada no seu perfil do GitHub, use-a como seu endereço de email em users.txt para corresponder. Yourgituser@users.noreply.github.com, para que seu endereço de email real não apareça em commits.
MacGyver

Respostas:


529

Magia:

$ git svn clone http://svn/repo/here/trunk

Git e SVN funcionam de maneira muito diferente. Você precisa aprender o Git e, se quiser acompanhar as alterações do SVN upstream, precisa aprender git-svn. A git-svn página principal tem uma seção de bons exemplos :

$ git svn --help

140
A resposta do @Casey responde muito melhor à pergunta original.
Doug Wilson

3
Isso manterá os galhos e tudo? ou apenas clonar o tronco?
Eildosa

7
@Eildosa: Isso apenas clonará o tronco. Veja a resposta de Casey para uma alternativa.
sleske

3
@DougWilson, mas não consigo ver a resposta de nenhum Casey aqui. É a resposta abaixo com 13 autores que começa com "Criar um arquivo de usuários"?
Andrey Regentov 5/08/16

68
Para qualquer um que esteja se perguntando qual é a "resposta de Casey", mencionada em muitos comentários por aqui, é esse (Casey mudou seu apelido para cmcginty).
Stefan Monov

1560

Crie um arquivo de usuários (ou seja users.txt) para mapear usuários SVN para o Git:

user1 = First Last Name <email@address.com>
user2 = First Last Name <email@address.com>
...

Você pode usar essa linha única para criar um modelo a partir do seu repositório SVN existente:

svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > users.txt

O SVN será interrompido se encontrar um usuário SVN ausente no arquivo. Mas depois disso, você pode atualizar o arquivo e pegar de onde parou.

Agora puxe os dados SVN do repositório:

git svn clone --stdlayout --no-metadata --authors-file=users.txt svn://hostname/path dest_dir-tmp

Este comando criará um novo repositório Git dest_dir-tmpe começará a puxar o repositório SVN. Observe que o sinalizador "--stdlayout" implica que você possui o layout comum "trunk /, branches /, tags /" SVN. Se seus difere layout, familiarizar-se com --tags, --branches, --trunkopções (em geral git svn help).

Todos os protocolos comuns são permitidos: svn://, http://, https://. A URL deve ter como alvo o repositório base, algo como http://svn.mycompany.com/myrepo/repository . A cadeia de URLs não deve incluir /trunk, /tagou /branches.

Observe que, depois de executar este comando, muitas vezes parece que a operação está "travada / congelada" e é bastante normal que ela possa ficar parada por um longo tempo após a inicialização do novo repositório. Eventualmente, você verá mensagens de log indicando que está migrando.

Observe também que, se você omitir o --no-metadatasinalizador, o Git anexará informações sobre a revisão SVN correspondente à mensagem de confirmação (ou seja git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID>)

Se um nome de usuário não for encontrado, atualize seu users.txtarquivo:

cd dest_dir-tmp
git svn fetch

Você pode ter que repetir esse último comando várias vezes, se tiver um projeto grande, até que todas as confirmações do Subversion tenham sido buscadas:

git svn fetch

Quando concluído, o Git fará o check-out do SVN trunkem uma nova ramificação. Quaisquer outras ramificações são configuradas como controles remotos. Você pode visualizar os outros ramos do SVN com:

git branch -r

Se você deseja manter outras ramificações remotas em seu repositório, você deseja criar uma ramificação local para cada uma manualmente. (Ignore tronco / mestre.) Se você não fizer isso, os ramos não serão clonados na etapa final.

git checkout -b local_branch remote_branch
# It's OK if local_branch and remote_branch are the same name

Tags são importadas como ramificações. Você precisa criar uma filial local, criar uma marca e excluir a filial para tê-los como marcas no Git. Para fazer isso com a tag "v1":

git checkout -b tag_v1 remotes/tags/v1
git checkout master
git tag v1 tag_v1
git branch -D tag_v1

Clone seu repositório GIT-SVN em um repositório Git limpo:

git clone dest_dir-tmp dest_dir
rm -rf dest_dir-tmp
cd dest_dir

As ramificações locais que você criou anteriormente a partir de ramificações remotas serão copiadas apenas como ramificações remotas no novo repositório clonado. (Ignore tronco / mestre.) Para cada ramo que você deseja manter:

git checkout -b local_branch origin/remote_branch

Por fim, remova o controle remoto do seu repositório Git limpo que aponta para o repositório temporário agora excluído:

git remote rm origin

36
Esta postagem no blog da Eelke é uma excelente referência cruzada para a resposta acima. blokspeed.net/blog/2010/09/converting-from-subversion-to-git
kgriffs

4
Isso é 99% impressionante, seguindo estas etapas, eu tenho tudo em ordem, exceto ramos: após a etapa final, eles eram apenas remotos (e, como tal, desapareceram quando eu fiz o comando: git remote rm origin)
Dirty Henry

4
O GitHub tem um passo-a-passo muito conveniente: github.com/nirvdrum/svn2git#readme
Dan Nissenbaum

8
Para aqueles no Windows, eu criei um script do PowerShell com base neste método: gist.github.com/Gimly/90df046dc38181bb18de
Gimly

5
Aviso para grandes repositórios com muita história, isso é lento e tedioso . Desisti de tentar migrar todos os ramos antigos e simplesmente migrei o tronco.
Jess

195

Migrar corretamente o repositório do Subversion para um repositório Git . Primeiro você precisa criar um arquivo que mapeie os nomes dos autores de confirmação do Subversion para os confirmadores do Git, digamos ~/authors.txt:

jmaddox = Jon Maddox <jon@gmail.com>
bigpappa = Brian Biggs <bigpappa@gmail.com>

Então você pode baixar os dados do Subversion em um repositório Git:

mkdir repo && cd repo
git svn init http://subversion/repo --no-metadata
git config svn.authorsfile ~/authors.txt
git svn fetch

Se você estiver em um Mac, poderá obter o git-svnMacPorts instalando git-core +svn.

Se o seu repositório subversion estiver na mesma máquina que o repositório git desejado, você poderá usar esta sintaxe para a etapa init, caso contrário, será a mesma:

git svn init file:///home/user/repoName --no-metadata

1
Quando comentei a outra resposta, tive que remover os espaços =, users.txtporque a importação estava abortando e eu estava recebendo um repositório vazio.
Sebastián Grignoli 31/01

8
Ah! Explicação simples e eficaz. No meu caso, file:///recusou-se a trabalhar, apenas usei svnserve.exe --daemone depois usei svn://localhost/home/user/repo.
Daniel Reis

No meu Mac executando o Mountain Lion, o git svn não funcionaria até eu entrar no Xcode e instalar as Ferramentas de Linha de Comando encontradas na guia Downloads do painel Preferências. Como alternativa, eu poderia ter instalado apenas as ferramentas de linha de comando do OS X Mountain Lion encontradas no site de desenvolvedor da Apple.
Tirou

3
Para o meu caso, tive que converter o arquivo authors.txtem utf-8 without BOM.
quer

Isso funcionou muito bem para mim! Depois de ter o repositório local, usei a postagem de cmcginty começando em "Clone seu repositório GIT-SVN em um repositório Git limpo:" Acho que o principal motivo pelo qual gostei da resposta do @zoul foi o uso git svn init, git svn confige finalmente, git svn fetchcomo ficou mais fácil para fazer dessa maneira, tive que buscar várias vezes para acertar. A linha única de cmcginty git svn clone, que faz todos os três, estava muito confusa para mim.
mike

70

Eu usei o script svn2git e funciona como um encanto.


4
P: isso corrige espaços nos nomes de tags e ramificações (permitido no svn e não permitido no git)?
Spazm



É preferível explicar respostas, caso contrário, produzimos scripts para crianças.
Josh Habdas

E se seus ramos estiverem todos na raiz do SVN e você não tiver tronco ou tags?
Kal

58

Sugiro que você se sinta confortável com o Git antes de tentar usar o git-svn constantemente, ou seja, mantendo o SVN como repositório centralizado e usando o Git localmente.

No entanto, para uma migração simples com todo o histórico, aqui estão algumas etapas simples:

Inicialize o repositório local:

mkdir project
cd project
git svn init http://svn.url

Marque até que ponto você deseja começar a importar revisões:

git svn fetch -r42

(ou apenas "git svn fetch" para todas as rotações)

Na verdade, busque tudo desde então:

git svn rebase

Você pode verificar o resultado da importação com o Gitk. Não sei se isso funciona no Windows, mas no OSX e Linux:

gitk

Quando seu repositório SVN for clonado localmente, convém enviá-lo para um repositório Git centralizado para facilitar a colaboração.

Primeiro, crie seu repositório remoto vazio (talvez no GitHub ?):

git remote add origin git@github.com:user/project-name.git

Em seguida, sincronize opcionalmente sua ramificação principal para que a operação pull mescle automaticamente o mestre remoto com o mestre local, quando ambos contiverem novos itens:

git config branch.master.remote origin
git config branch.master.merge refs/heads/master

Depois disso, você pode estar interessado em experimentar minha própria git_remote_branchferramenta, que ajuda a lidar com ramificações remotas:

Primeiro post explicativo: " Git branches remotos "

Acompanhamento da versão mais recente: " Hora de começar a colaborar com git_remote_branch "


Extremamente útil, isso funcionou perfeitamente. Eu acrescentaria que há uma etapa final a ser tomada se você estiver sincronizando com um repositório remoto. Após as etapas git config, eu precisavagit push origin master
mag382

31

Existe uma nova solução para migração suave do Subversion para o Git (ou para usar os dois simultaneamente): SubGit .

Eu mesmo estou trabalhando nesse projeto. Usamos o SubGit em nossos repositórios - alguns dos meus colegas de equipe usam o Git e o Subversion e, até agora, funciona muito bem.

Para migrar do Subversion para o Git com o SubGit, você precisa executar:

$ subgit install svn_repos
...
TRANSLATION SUCCESSFUL 

Depois disso, você obterá o repositório Git em svn_repos / .git e poderá cloná-lo, ou apenas continuar usando o Subversion e este novo repositório Git juntos: O SubGit garantirá que ambos estejam sempre sincronizados.

Caso seu repositório Subversion contenha vários projetos, vários repositórios Git serão criados no diretório svn_repos / git. Para personalizar a tradução antes de executá-la, faça o seguinte:

$ subgit configure svn_repos
$ edit svn_repos/conf/subgit.conf (change mapping, add authors mapping, etc)
$ subgit install svn_repos

Com o SubGit, você pode migrar para o Git puro (não git-svn) e começar a usá-lo enquanto mantém o Subversion pelo tempo que for necessário (para as ferramentas de construção já configuradas, por exemplo).

Espero que isto ajude!


4
Observe que uma importação única (usando o subgit importcomando) nem parece exigir uma licença. A tradução exata da svn:ignorepropriedade para .gitignorearquivos também está incluída.
precisa saber é o seguinte

1
O SubGit não reconheceria minha chave privada, nem nenhum sinalizador que eu definir na linha de comando. A documentação é muito ruim. Esta não é uma alternativa viável para git svn.
pfnuesel

1
erro: 'svn_repos' não é um local configurado válido; O arquivo de configuração do SubGit está ausente.
Jon Davis

19

Veja o funcionário de manual git-svn . Em particular, consulte "Exemplos básicos":

Rastreando e contribuindo para todo um projeto gerenciado pelo Subversion (completo com um tronco, tags e ramificações):

# Clone a repo (like git clone):
    git svn clone http://svn.foo.org/project -T trunk -b branches -t tags

Seu comando clone funcionou, aqueles acima não me deram nada além de repositórios vazios de git. A única diferença parece ser o explícito '-T trunk'.
User1984717


14

SubGit (vs Tela Azul da Morte)

subgit import --svn-url url://svn.serv/Bla/Bla  directory/path/Local.git.Repo

É tudo.

+ Para atualizar do SVN, um repositório Git criado pelo primeiro comando.

subgit import  directory/path/Local.git.Repo

Eu usei uma maneira de migrar para o Git instantaneamente para um repositório enorme.
Claro que você precisa de alguma preparação.
Mas você pode não parar o processo de desenvolvimento.

Aqui está o meu caminho.

Minha solução se parece com:

  • Migrar SVN para um repositório Git
  • Atualize o repositório Git imediatamente antes da equipe mudar para .

A migração leva muito tempo para um grande repositório SVN.
Mas a atualização da migração concluída é apenas alguns segundos.

Claro que estou usando SubGit , mamãe. git-svn me faz tela azul da morte . Apenas constantemente. E o git-svn está me entediando com o erro fatal " nome do arquivo muito longo " do Git .

PASSOS

1. Baixe o SubGit

2. Prepare os comandos de migração e atualização.

Digamos que façamos isso no Windows (é fácil portar para o Linux).
No diretório bin de instalação do SubGit (subgit-2.XX \ bin), crie dois arquivos .bat.

Conteúdo de um arquivo / comando para a migração:

start    subgit import --svn-url url://svn.serv/Bla/Bla  directory/path/Local.git.Repo

O comando "start" é opcional aqui (Windows). Ele permitirá ver erros no início e deixou um shell aberto após a conclusão do SubGit.

Você pode adicionar aqui parâmetros adicionais semelhantes ao git-svn . Estou usando apenas --default-domain myCompanyDomain.com para corrigir o domínio do endereço de email dos autores SVN.
Eu tenho a estrutura do repositório SVN padrão (trunk / branches / tags) e não tivemos problemas com o "mapeamento de autores". Então, não estou mais fazendo nada.

(Se você quiser migrar tags como branches ou seu SVN tiver várias pastas de branches / tags, considere usar a abordagem mais detalhada do SubGit )

Dica 1 : use --minimal-revisão YourSvnRevNumber para ver rapidamente como as coisas acontecem (algum tipo de depuração). Especialmente útil é ver nomes ou e-mails de autores resolvidos.
Ou para limitar a profundidade do histórico de migração.

Dica 2 : A migração pode ser interrompida ( Ctrl+ C) e restaurada executando o próximo comando / arquivo de atualização.
Eu não aconselho fazer isso para grandes repositórios. Recebi "Exceção de Java + Windows com falta de memória".

Dica 3 : é melhor criar uma cópia do seu repositório bare de resultados.

Conteúdo de um arquivo / comando para atualização:

start    subgit import  directory/path/Local.git.Repo

Você pode executá-lo quantas vezes quiser, para obter as confirmações da última equipe no seu repositório Git.

Atenção! Não toque no seu repositório vazio (criação de ramificações, por exemplo).
Você receberá o próximo erro fatal:

Erro irrecuperável: está fora de sincronia e não pode ser sincronizado ... A tradução de revisões do Subversion para o Git confirma ...

3. Execute o primeiro comando / arquivo. Levará muito tempo para um grande repositório. 30 horas para o meu humilde repositório.

É tudo.
Você pode atualizar seu repositório Git a partir do SVN a qualquer momento, executando o segundo arquivo / comando. E antes de mudar sua equipe de desenvolvimento para o Git.
Vai demorar apenas alguns segundos.



Há mais uma tarefa útil.

Envie seu repositório Git local para um repositório Git remoto

É o seu caso? Vamos continuar.

  1. Configure seus controles remotos

Corre:

$ git remote add origin url://your/repo.git
  1. Prepare-se para o envio inicial do seu enorme repositório Git local para um repositório remoto

Por padrão, seu Git não pode enviar grandes pedaços. fatal: A extremidade remota desligou inesperadamente

Vamos correr para isso:

git config --global http.postBuffer 1073741824

524288000 - 500 MB 1073741824 - 1 GB etc.

Corrija seus problemas de certificado local . Se o seu servidor git usa um certificado quebrado.

Eu desativei certificados .

Além disso, seu servidor Git pode ter limitações na quantidade de solicitações que precisam ser corrigidas .

  1. Envie toda a migração para o repositório Git remoto da equipe.

Execute com um Git local:

git push origin --mirror

( origem do push do git '*: *' para versões antigas do Git)

Se você obtiver o seguinte: error: Impossível gerar o git: Esse arquivo ou diretório não existe ... Para mim, a recreação completa do meu repositório resolve esse erro (30 horas). Você pode tentar os próximos comandos

git push origin --all
git push origin --tags

Ou tente reinstalar o Git ( inútil para mim ). Ou você pode criar ramificações de todas as tags e enviá-las. Ou, ou, ou ...


10

reposurgeon

Para casos complicados, o reposurgeon de Eric S. Raymond é a ferramenta de escolha. Além do SVN, ele suporta muitos outros sistemas de controle de versão por meio do fast-exportformato e também do CVS . O autor relata conversões bem-sucedidas de repositórios antigos, como Emacs e FreeBSD .

Aparentemente, a ferramenta visa uma conversão quase perfeita (como converter as svn:ignorepropriedades do SVN em.gitignore arquivos), mesmo para layouts de repositórios difíceis com um longo histórico. Para muitos casos, outras ferramentas podem ser mais fáceis de usar.

Antes de investigar a documentação da reposurgeonlinha de comando, leia o excelente guia de migração do DVCS, que detalha o processo de conversão passo a passo.



8

Você precisa instalar

git
git-svn

Copiado deste link http://john.albin.net/git/convert-subversion-to-git .

1. Recupere uma lista de todos os commits do Subversion

O Subversion simplesmente lista o nome de usuário para cada confirmação. Os commits do Git têm dados muito mais ricos, mas, na sua forma mais simples, o autor do commit precisa ter um nome e um email listados. Por padrão, a ferramenta git-svn lista apenas o nome de usuário do SVN nos campos de autor e email. Mas, com um pouco de trabalho, você pode criar uma lista de todos os usuários do SVN e qual o nome e email correspondentes do Git. Esta lista pode ser usada pelo git-svn para transformar nomes de usuário simples do svn em committers apropriados do Git.

Na raiz do seu checkout local do Subversion, execute este comando:

svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors-transform.txt

Isso irá capturar todas as mensagens de log, extrair os nomes de usuário, eliminar nomes de usuário duplicados, classificar os nomes de usuário e colocá-los em um arquivo "autores-transform.txt". Agora edite cada linha no arquivo. Por exemplo, converta:

jwilkins = jwilkins <jwilkins>

nisso:

jwilkins = John Albin Wilkins <johnalbin@example.com>

2. Clone o repositório Subversion usando git-svn

git svn clone [SVN repo URL] --no-metadata -A authors-transform.txt --stdlayout ~/temp

Isso fará a transformação padrão do git-svn (usando o arquivo autores-transform.txt criado na etapa 1) e coloque o repositório git na pasta "~ / temp" dentro do diretório inicial.

3. Converta propriedades svn: ignore em .gitignore

Se o seu repositório svn estava usando as propriedades svn: ignore, você pode facilmente convertê-lo em um arquivo .gitignore usando:

cd ~/temp
git svn show-ignore > .gitignore
git add .gitignore
git commit -m 'Convert svn:ignore properties to .gitignore.'

4. Envie o repositório para um repositório git simples

Primeiro, crie um repositório vazio e faça com que sua ramificação padrão corresponda ao nome da ramificação “trunk” do svn.

git init --bare ~/new-bare.git
cd ~/new-bare.git
git symbolic-ref HEAD refs/heads/trunk

Em seguida, envie o repositório temporário para o novo repositório vazio.

cd ~/temp
git remote add bare ~/new-bare.git
git config remote.bare.push 'refs/remotes/*:refs/heads/*'
git push bare

Agora você pode excluir com segurança o repositório ~ / temp.

5. Renomeie o ramo "tronco" para "mestre"

Seu ramo de desenvolvimento principal será chamado de "tronco", que corresponde ao nome que estava no Subversion. Você vai querer renomeá-lo para o ramo "master" padrão do Git usando:

cd ~/new-bare.git
git branch -m trunk master

6. Limpe ramos e etiquetas

O git-svn transforma todas as tags do Subversions em ramificações muito curtas no Git, no formato "tags / nome". Você desejará converter todos esses ramos em tags Git reais usando:

cd ~/new-bare.git
git for-each-ref --format='%(refname)' refs/heads/tags |
cut -d / -f 4 |
while read ref
do
  git tag "$ref" "refs/heads/tags/$ref";
  git branch -D "tags/$ref";
done

Esta etapa levará um pouco de digitação. :-) Mas não se preocupe; seu shell unix fornecerá um prompt secundário para o comando extra-longo que começa com git para cada ref.


7

Agora o GitHub tem um recurso para importar de um repositório SVN . Eu nunca tentei, no entanto.


3
A recomendação atual do GitHub é usar o svn2gitprograma sugerido em outra resposta .
Ntc2

Importou dois projetos bastante grandes agora sem falhas. Todas as ramificações SVN foram importadas (lembre-se de NÃO usar a parte \ trunk no caminho do repositório). Uma coisa que ainda não sei é se o Github rastreará novos commits.
Fr0sT

7

Uma resposta um tanto extensa usando apenas git, SVN e bash. Inclui etapas para repositórios SVN que não usam o layout convencional com um layout de diretório trunk / branches / tags (o SVN não faz absolutamente nada para impor esse tipo de layout).

Primeiro, use esse script bash para verificar seu repositório SVN para as diferentes pessoas que contribuíram e gerar um modelo para um arquivo de mapeamento:

#!/usr/bin/env bash
authors=$(svn log -q | grep -e '^r' | awk 'BEGIN { FS = "|" } ; { print $2 }' | sort | uniq)
for author in ${authors}; do
  echo "${author} = NAME <USER@DOMAIN>";
done

Use isso para criar um authorsarquivo no qual você mapeia nomes de usuário svn para nomes de usuário e email, conforme definido por seus desenvolvedores usandogit config propriedades user.namee user.email(observe que, para um serviço como o GitHub, basta ter um email correspondente).

Então tem git svn clone o repositório svn em um repositório git, informando sobre o mapeamento:

git svn clone --authors-file=authors --stdlayout svn://example.org/Folder/projectroot

Isso pode levar um tempo incrivelmente longo, já que o git svn verifica individualmente todas as revisões de cada tag ou ramo que existe. (observe que as tags no SVN são apenas verdadeiras ramificações, então elas acabam como tal no Git). Você pode acelerar isso removendo tags e ramificações antigas no SVN de que não precisa.

Executar isso em um servidor na mesma rede ou no mesmo servidor também pode realmente acelerar isso. Além disso, se por algum motivo esse processo for interrompido, você poderá continuar usando

git svn rebase --continue

Em muitos casos, você terminou aqui. Mas se o seu repositório SVN tiver um layout não convencional, onde você simplesmente tem um diretório no SVN que deseja colocar em uma ramificação git, poderá executar algumas etapas extras.

O mais simples é criar um novo repositório SVN no servidor que siga a convenção e use svn copy para colocar seu diretório em tronco ou filial. Essa pode ser a única maneira, se o diretório estiver na raiz do repositório, quando eu tentei isso pela última vezgit svn simplesmente se recusou a fazer um checkout.

Você também pode fazer isso usando o git. Paragit svn clone simplesmente usar o diretório que você deseja colocar em um ramo git.

Depois de correr

git branch --set-upstream master git-svn
git svn rebase

Observe que isso exigia o Git 1.7 ou superior.


Eu proporia combinar essas informações com este link: sailmaker.co.uk/blog/2013/05/05/…
Joan PS

7

Publiquei um guia passo a passo ( aqui ) para converter svn para git, incluindo a conversão de tags svn para tags git e ramos svn para ramos git.

Versão curta:

1) clone svn de um número de revisão específico. (o número da revisão deve ser o mais antigo que você deseja migrar)

git svn clone --username=yourSvnUsername -T trunk_subdir -t tags_subdir -b branches_subdir -r aRevisionNumber svn_url gitreponame

2) buscar dados svn. Esta etapa é a que leva mais tempo.

cd gitreponame
git svn fetch

repita git svn fetch até terminar sem erro

3) atualize o ramo mestre

git svn rebase

4) Crie ramificações locais a partir das ramificações svn, copiando referências

cp .git/refs/remotes/origin/* .git/refs/heads/

5) converter tags svn em tags git

git for-each-ref refs/remotes/origin/tags | sed 's#^.*\([[:xdigit:]]\{40\}\).*refs/remotes/origin/tags/\(.*\)$#\2 \1#g' | while read p; do git tag -m "tag from svn" $p; done

6) Coloque um repositório em um lugar melhor como o github

git remotes add newrepo git@github.com:aUser/aProjectName.git
git push newrepo refs/heads/*
git push --tags newrepo

Se você quiser mais detalhes, leia meu post ou me pergunte.


6

Podemos usar git svn clonecomandos como abaixo.

  • svn log -q <SVN_URL> | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors.txt

O comando acima criará o arquivo de autores a partir de confirmações do SVN.

  • svn log --stop-on-copy <SVN_URL>

O comando acima fornecerá o primeiro número de revisão quando seu projeto SVN foi criado.

  • git svn clone -r<SVN_REV_NO>:HEAD --no-minimize-url --stdlayout --no-metadata --authors-file authors.txt <SVN_URL>

O comando acima criará o repositório Git no local.

O problema é que ele não converterá ramificações e tags para envio. Você terá que fazê-los manualmente. Por exemplo abaixo para ramificações:

$ git remote add origin https://github.com/pankaj0323/JDProjects.git
$ git branch -a
* master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$$ git checkout -b MyDevBranch origin/MyDevBranch
Branch MyDevBranch set up to track remote branch MyDevBranch from origin.
Switched to a new branch 'MyDevBranch'
$ git branch -a
* MyDevBranch
  master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$

Para tags:

$git checkout origin/tags/MyDevBranch-1.0
Note: checking out 'origin/tags/MyDevBranch-1.0'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 3041d81... Creating a tag
$ git branch -a
* (detached from origin/tags/MyDevBranch-1.0)
  MyDevBranch
  master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$ git tag -a MyDevBranch-1.0 -m "creating tag"
$git tag
MyDevBranch-1.0
$

Agora envie master, branches e tags para o repositório git remoto.

$ git push origin master MyDevBranch MyDevBranch-1.0
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (14/14), 2.28 KiB | 0 bytes/s, done.
Total 14 (delta 3), reused 0 (delta 0)
To https://github.com/pankaj0323/JDProjects.git
 * [new branch]      master -> master
 * [new branch]      MyDevBranch -> MyDevBranch
 * [new tag]         MyDevBranch-1.0 -> MyDevBranch-1.0
$

utilitário svn2git

O utilitário svn2git remove os esforços manuais com ramificações e tags.

Instale-o usando o comando sudo gem install svn2git. Depois disso, execute o comando abaixo.

  • $ svn2git <SVN_URL> --authors authors.txt --revision <SVN_REV_NO>

Agora você pode listar os ramos, tags e enviá-los facilmente.

$ git remote add origin https://github.com/pankaj0323/JDProjects.git
$ git branch -a
  MyDevBranch
* master
  remotes/svn/MyDevBranch
  remotes/svn/trunk
$ git tag
  MyDevBranch-1.0
$ git push origin master MyDevBranch MyDevBranch-1.0

Imagine que você tem 20 ramificações e tags, obviamente o svn2git economizará muito tempo e é por isso que eu gosto mais que os comandos nativos. É um bom invólucro em torno do git svn clonecomando nativo .

Para um exemplo completo, consulte minha entrada de blog .




3

Se você estiver usando o SourceTree, poderá fazer isso diretamente do aplicativo. Vá para Arquivo -> Novo / Clone e faça o seguinte:

  1. Digite o URL remoto do SVN como o "Caminho / URL de origem".
  2. Digite suas credenciais quando solicitado.
  3. Digite o local da pasta local como o "Caminho de destino".
  4. Dê um nome a ele.
  5. Nas opções avançadas, selecione "Git" no menu suspenso "Criar repositório local do tipo".
  6. Opcionalmente, você pode especificar uma revisão da qual clonar.
  7. Clique em Clone.

Abra o repositório no SourceTree e você verá que suas mensagens de confirmação também foram migradas.

Agora vá para Repositório -> Configurações do Repositório e adicione os novos detalhes do repositório remoto. Exclua o controle remoto SVN, se desejar (fiz isso através da opção "Editar arquivo de configuração").

Envie o código para o novo repositório remoto quando estiver pronto e codifique livremente.


Obrigado, super fácil e rápido!
Rikard

Obrigado. Isso funcionou para mim. Estou usando o SourceTree e o Stash.
VK_217 20/10/2015

3

Para o GitLab usuários do eu como eu migrei do SVN aqui:

https://gist.github.com/leftclickben/322b7a3042cbe97ed2af

Etapas para migrar do SVN para o GitLab

Configuração

  • SVN está hospedado em svn.domain.com.au.
  • O SVN é acessível via http(outros protocolos devem funcionar).
  • O GitLab está hospedado em git.domain.com.aue:
    • Um grupo é criado com o espaço para nome dev-team.
    • Pelo menos uma conta de usuário é criada, adicionada ao grupo e possui uma chave SSH para a conta que está sendo usada para a migração (teste usando ssh git@git.domain.com.au ).
    • O projeto favourite-projecté criado no dev-teamespaço para nome.
  • O arquivo users.txtcontém os detalhes relevantes do usuário, um usuário por linha, do formulário username = First Last <address@domain.com.au>, onde usernameé o nome de usuário fornecido nos logs SVN. (Veja o primeiro link na seção Referências para obter detalhes, em particular a resposta do usuário Casey).

Versões

  • subversion versão 1.6.17 (r1128011)
  • git versão 1.9.1
  • GitLab versão 7.2.1 ff1633f
  • Servidor Ubuntu 14.04

Comandos

bash
git svn clone --stdlayout --no-metadata -A users.txt 
http://svn.domain.com.au/svn/repository/favourite-project
cd favourite-project
git remote add gitlab git@git.domain.com.au:dev-team/favourite-project.git
git push --set-upstream gitlab master

É isso aí! Recarregue a página do projeto na interface da web do GitLab e você verá todos os commits e arquivos listados agora.

Notas

  • Se houver usuários desconhecidos, o git svn clonecomando irá parar, caso em que, atualização users.txt, cd favourite-projecte git svn fetchvai continuar de onde parou.
  • O padrão trunk- tags- brancheslayout para repositório SVN é necessária.
  • O URL SVN fornecido ao git svn clone comando pára no nível imediatamente superior trunk/, tags/ebranches/ .
  • O git svn clonecomando produz muita saída, incluindo alguns avisos na parte superior; Eu ignorei os avisos.

Embora esse link possa responder à pergunta, é melhor incluir aqui as partes essenciais da resposta e fornecer o link para referência. As respostas somente para links podem se tornar inválidas se a página vinculada for alterada.
Blackhole

1
Discordo. O conteúdo vinculado pode mudar, e o conteúdo duplicado aqui não será atualizado e, portanto, pode estar desatualizado (e, de fato, acredito que tenha sido alterado desde que originalmente publiquei esta resposta). As diretrizes dizem apenas para incluir algum contexto relevante para um link, o que eu fiz - a pergunta real foi respondida por atacado pelo link. A cópia de todo o recurso vinculado aqui não é necessária ou necessária. Eu fui votado para isso ?!
leftclickben

2

Como outro aparte, o comando git-stash é uma dádiva de Deus ao tentar git com o git-svn dcommits.

Um processo típico:

  1. configurar repositório git
  2. faça algum trabalho em arquivos diferentes
  3. decida verificar parte do trabalho, usando git
  4. decidir svn-dcommit
  5. obtenha o temido erro "não é possível confirmar com um índice sujo".

A solução (requer git 1.5.3+):

git stash; git svn dcommit ; git stash apply

2

Aqui está um script de shell simples, sem dependências que converterá um ou mais repositórios SVN em git e os enviará para o GitHub.

https://gist.github.com/NathanSweet/7327535

Em cerca de 30 linhas de script, ele: clona usando o git SVN, cria um arquivo .gitignore a partir das propriedades SVN :: ignore, entra em um repositório vazio, renomeia o tronco do SVN para mestre, converte tags SVN em tags git e o envia para o GitHub preservando as tags.

Eu me esforcei ao mover uma dúzia de repositórios SVN do Google Code para o GitHub. Não ajudou que eu usei o Windows. Ruby estava com todos os tipos de problemas na minha antiga caixa Debian e fazê-lo funcionar no Windows era uma piada. Outras soluções falharam ao trabalhar com os caminhos do Cygwin. Mesmo depois que algo funcionou, eu não conseguia descobrir como fazer as tags aparecerem no GitHub (o segredo é --follow-tags).

No final, juntei dois scripts curtos e simples, vinculados acima, e funciona muito bem. A solução não precisa ser mais complicada do que isso!


2
Eu usei esse script. Depois de um pouco de trilha e erro, funcionou para mim. Esteja ciente de que você precisa do Git 1.8.3+ para isso, pois --follow-tags só é suportado posteriormente.
Nvrey

2

Estou em uma máquina Windows e fiz um pequeno Lote para transferir um repositório SVN com histórico (mas sem ramificações) para um repositório GIT apenas chamando

transfer.bat http://svn.my.address/svn/myrepo/trunk https://git.my.address/orga/myrepo

Talvez alguém possa usá-lo. Ele cria uma pasta TMP, verifica o repositório SVN lá com o git e adiciona a nova origem e a empurra ... e exclui a pasta novamente.

@echo off 
SET FROM=%1 
SET TO=%2 
SET TMP=tmp_%random%

echo from:  %FROM% 
echo to:    %TO% 
echo tmp:   %TMP%

pause

git svn clone  --no-metadata --authors-file=users.txt %FROM% %TMP%  
cd %TMP% 
git remote add origin %TO% 
git push --set-upstream origin master


cd .. 
echo delete %TMP% ... 
pause

rmdir /s /q %TMP%

Você ainda precisa do users.txt com seus mapeamentos de usuário, como

User1 = User One <u.1@xxx.com>

Esta resposta me ajudou a mover todos os meus repositórios para o BitBucket sem problemas.
Gonzalingui 28/05

Fico feliz em ouvir. Eu só tinha experiência com Gitea ... mas transferi 40 repositórios dessa maneira.
Cljk

Muito agradável! Thnx
b3wii

Atenção; Tive problemas com charset ruim. Eu reconheci isso muito tarde, mas levei várias horas para consertar. Verifique se o seu repo resultante contém as fontes exata esperados (!)
cljk

1

Eu só queria adicionar minha contribuição à comunidade Git. Eu escrevi um script simples do bash que automatiza a importação completa. Diferente de outras ferramentas de migração, essa ferramenta depende do git nativo em vez do jGit. Essa ferramenta também suporta repositórios com um grande histórico de revisões e ou grandes blobs. Está disponível no github:

https://github.com/onepremise/SGMS

Este script converterá projetos armazenados no SVN com o seguinte formato:

/trunk
  /Project1
  /Project2
/branches
     /Project1
     /Project2
/tags
 /Project1
 /Project2

Este esquema também é popular e suportado também:

/Project1
     /trunk
     /branches
     /tags
/Project2
     /trunk
     /branches
     /tags

Cada projeto será sincronizado pelo nome do projeto:

Ex: ./migration https://svnurl.com/basepath project1

Se você deseja converter o repositório completo, use a seguinte sintaxe:

Ex: ./migration https://svnurl.com/basepath .

0

Usar efetivamente o Git com o Subversion é uma introdução suave ao git-svn. Para repositórios SVN existentes, o git-svn torna isso super fácil. Se você estiver iniciando um novo repositório, é muito mais fácil criar primeiro um repositório SVN vazio e depois importar usando o git-svn do que na direção oposta. Criar um novo repositório Git e depois importar para o SVN pode ser feito, mas é um pouco doloroso, especialmente se você é novo no Git e espera preservar o histórico de consolidação.


0

Faça o download do instalador do Ruby para Windows e instale a versão mais recente. Adicione executáveis ​​Ruby ao seu caminho.

  • Instale o svn2git
  • Menu Iniciar -> Todos os programas -> Ruby -> Inicie um prompt de comando com Ruby
  • Então digite “gem install svn2git” e digite

    Migrar repositório do Subversion

  • Abra um prompt de comando Ruby e vá para o diretório em que os arquivos serão migrados

    Então svn2git http: // [ nome do domínio ] / svn / [raiz do repositório]

  • A migração do projeto para o Git pode demorar algumas horas, dependendo do tamanho do código do projeto.

  • Esta etapa principal ajuda na criação da estrutura do repositório Git, conforme mencionado abaixo.

    Tronco SVN (/ Project_components) -> Git master SVN (/ Project_components) branches -> Git branches SVN (/ Project_components) tags -> tags Git

Crie o repositório remoto e faça as alterações.


0

O GitHub tem um importador. Depois de criar o repositório, você pode importar de um repositório existente, via URL. Ele solicitará suas credenciais, se aplicável, e partirá daí.

Enquanto estiver em execução, ele encontrará autores e você pode simplesmente mapeá-los para os usuários no GitHub.

Eu o usei para alguns repositórios agora, e é bem preciso e muito mais rápido também! Foram necessários 10 minutos para um repositório com ~ 4000 confirmações e depois de quatro dias para meu amigo!



0

Existem diferentes métodos para atingir esse objetivo. Eu tentei alguns deles e achei realmente funcionando um com apenas git e svn instalado no sistema operacional Windows.

Pré-requisitos:

  1. git no windows (eu usei este) https://git-scm.com/
  2. svn com as ferramentas do console instaladas (usei o tortoise svn)
  3. Arquivo de despejo do seu repositório SVN. svnadmin dump /path/to/repository > repo_name.svn_dump

Etapas para atingir o objetivo final (mova todo o repositório com histórico para um git, primeiro git local e depois remoto)

  1. Crie um repositório vazio (usando ferramentas do console ou tortoiseSVN) no diretório REPO_NAME_FOLDER cd REPO_NAME_PARENT_FOLDER, coloque dumpfile.dump em REPO_NAME_PARENT_FOLDER

  2. svnadmin load REPO_NAME_FOLDER < dumpfile.dump Aguarde esta operação, pode demorar

  3. Este comando é silencioso, então abra a segunda janela do cmd: svnserve -d -R --root REPO_NAME_FOLDER Por que não usar apenas file: /// ......? Causa O próximo comando falhará Unable to open ... to URL:, graças à resposta https://stackoverflow.com/a/6300968/4953065

  4. Crie uma nova pasta SOURCE_GIT_FOLDER

  5. cd SOURCE_GIT_FOLDER
  6. git svn clone svn: // localhost / Aguarde esta operação.

Finalmente, o que temos?

Vamos verificar nosso repositório local:

git log

Veja seus commits anteriores? Se sim - tudo bem

Então agora você tem um repositório git local totalmente funcional com suas fontes e histórico antigo do svn. Agora, se você deseja movê-lo para algum servidor, use os seguintes comandos:

git remote add origin https://fullurlpathtoyourrepo/reponame.git
git push -u origin --all # pushes up the repo and its refs for the first time
git push -u origin --tags # pushes up any tags

No meu caso, eu não preciso do comando tags porque meu repositório não possui tags.

Boa sorte!


0

Convertendo o sub-módulo / pasta svn 'MyModule' em git com histórico sem tags nem ramificações.

Para manter a lista de ignorar svn, use os comentários acima após a etapa 1

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.