Venho fazendo todo o meu trabalho no Git e pressionando para o GitHub. Fiquei muito feliz com o software e o site, e não quero mudar minhas práticas de trabalho neste momento.
Meu orientador de doutorado está pedindo a todos os alunos que mantenham seu trabalho em um repositório SVN hospedado na universidade. Eu encontrei toneladas de documentação e tutoriais sobre como baixar um repositório SVN existente no Git, mas nada sobre enviar um repositório Git para um repositório SVN novo. Espero que haja alguma maneira de fazer isso com uma combinação de git-svn e um novo ramo, rebasing e todos esses termos maravilhosos, mas sou um novato no Git e não me sinto confiante com nenhum deles.
Desejo então executar apenas alguns comandos para enviar confirmações ao repositório SVN quando eu escolher. Desejo continuar usando o Git e ter apenas o espelho do repositório SVN que está no Git.
Serei a única pessoa que se comprometerá com o SVN, se isso fizer alguma diferença.
Nota: você provavelmente perderá seus carimbos de data originais ao fazer isso. As novas datas serão baseadas na hora da importação para o Subversion.
Para aqueles que procuram informações mais atuais alguns podem encontrar o útil seguinte pós durante a sua pesquisa para automação: deliciousbrains.com/deploying-wordpress-plugins-travis
Eu também precisava disso, e com a ajuda da resposta de Bombe + algumas brincadeiras, consegui que funcionasse. Aqui está a receita:
Importar Git -> Subversion
Após o nº 3, você receberá uma mensagem enigmática como esta:
Usando um nível mais alto de URL: protocol:///path/to/repo/PROJECT => protocol:///path/to/repo
Apenas ignore isso.
Quando você executa o número 5, pode ter conflitos. Resolva-os adicionando arquivos com o estado "não imerso" e retomando a rebase. Eventualmente, você estará pronto; sincronize novamente com o repositório SVN, usandodcommit . Isso é tudo.
Mantendo repositórios sincronizados
Agora você pode sincronizar do SVN para o Git, usando os seguintes comandos:
E para sincronizar do Git para o SVN, use:
Você pode tentar isso em uma cópia local, antes de aplicar em um repositório ativo. Você pode fazer uma cópia do seu repositório Git para um local temporário; basta usar cp -r, pois todos os dados estão no próprio repositório. Em seguida, você pode configurar um repositório de teste baseado em arquivo usando:
E verifique uma cópia de trabalho usando:
Isso permitirá que você brinque com as coisas antes de fazer alterações duradouras.
Adendo: Se você errar git svn init
Se você executar acidentalmente git svn initcom o URL errado e não for inteligente o suficiente para fazer um backup do seu trabalho (não pergunte ...), não poderá simplesmente executar o mesmo comando novamente. No entanto, você pode desfazer as alterações emitindo:
E remova a seção de [svn-remote "svn"]seção.
Você pode executar git svn initnovamente.
Boa resposta. Isso também atrapalha as datas de confirmação?
Boas perguntas - Infelizmente, também não sei a resposta. Este é mais um guia prático do que achei funcionar. Eu não entendo completamente todos os detalhes. Em relação às datas de confirmação, acho que você poderia fazer um teste e descobrir. Lembre-se de que você pode iniciar um repositório svn local (baseado em fs), para testar as coisas.
Eu segui essas mesmas etapas usando "git rebase --onto trunk --root" no lugar da etapa 5 e tive muito mais sucesso. Apenas um punhado de conflitos de mesclagem a serem resolvidos, em vez de toneladas.
No meu caso, essa sequência não funcionou. Sempre uma mensagem "Não é possível determinar as informações de SVN upstream do histórico HEAD" era exibida. Portanto, não é possível comprometer.
Deixa pra lá, tentei ser inteligente e omiti o -s, pois não queria seguir a configuração padrão do SVN (trunk / branches / tags /). Não foi possível fazê-lo funcionar sem isso.
— 22612 James McMahon
Veja como o fizemos funcionar:
Clone seu repositório Git em algum lugar da sua máquina.
Abra .git / config e adicione o seguinte (em Mantendo um espelho SVN somente leitura de um repositório Git ):
Agora, em uma janela do console, digite:
Agora, se ele quebrar aqui por qualquer motivo, digite estas três linhas:
E, finalmente, você pode se comprometer com o SVN:
Nota: Eu sempre rasco essa pasta depois.
— Alex Rouillard
+1 isso realmente funcionou para mim (não têm tronco / base qualquer que seja), em contraste com outras respostas que continuou dandoUnable to determine upstream SVN information from HEAD history.
Outro bom resumo: codeography.com/2010/03/17/howto-mirror-git-to-subversion.html
Eu tentei essa técnica, mas ela não importou o histórico. Btw, "git merge master" é agora "git merge - mestre de histórias não-relacionadas-anteriores"
Se você deseja absolutamente substituir o conteúdo do SVN pelo git, use git merge -s recursive -Xtheirs --allow-unrelated-histories master.
— user1475814
Usar git rebasediretamente perderá o primeiro commit. O Git trata diferente e não pode refazê-lo.
Existe um procedimento que preservará o histórico completo: http://kerneltrap.org/mailarchive/git/2008/10/26/3815034
Vou transcrever a solução aqui, mas os créditos são para Björn.
Inicialize o git-svn:
O --prefix fornece ramificações de rastreamento remoto como "svn / trunk", o que é legal porque você não recebe nomes ambíguos se chamar a ramificação local apenas como "trunk". E-s é um atalho para o layout padrão de troncos / tags / ramos.
Busque o material inicial do SVN:
Agora, procure o hash do seu commit raiz (deve mostrar um único commit):
Em seguida, obtenha o hash do tronco vazio commit:
Crie o enxerto:
Agora, o "gitk" deve aparecer svn/trunkcomo o primeiro commit no qual sua ramificação principal se baseia.
Tornar o enxerto permanente:
Solte o enxerto:
O gitk ainda deve aparecer svn/trunkna ancestralidade do mestre.
Linearize seu histórico sobre o tronco:
E agora "git svn dcommit -n" deve lhe dizer que ele irá se comprometer com o tronco.
Você pode explicar como essa técnica é diferente da acima, de forma mais clara.
Quando tento "git rev-parse svn / trunk", ele relata uma revisão desconhecida ou o caminho que não está na árvore de trabalho.
— 23612 Adam Ness
Esta é a única resposta que funcionou para mim, exceto as etapas que o git filter-branch e o drop graft não eram necessários: fiz uma reformulação após criar o enxerto e git svn dcommit.
— Fc7
Crie um novo diretório no repositório Subversion para o seu projeto.
Mude para o seu projeto gerenciado pelo Git e inicialize o git-svn.
Isso criará uma única confirmação porque o diretório do projeto SVN ainda está vazio. Agora, refaça tudo o que foi confirmado git svn dcommite você deverá concluir. Isso vai atrapalhar seriamente suas datas de confirmação.
Eu usei esta resposta com as instruções em hassox.blogspot.com/2007/12/using-git-with-svn.html Eu segui esses comandos e, em seguida, "#git branch -a" para ver o nome do tronco. Então: # git checkout -b local-svn trunk # git merge master # git svn dcommit Lembre-se de .gitignore no diretório .svn!
— 22909 cflewis
Como acabei de fazer a mesma operação, queria deixar explícito que já há algum tempo (janeiro '09), o git pode executar uma operação de rebase na confirmação raiz. Isso torna o processo muito mais simples do que um monte de artigos antigos indicam, ver comentários sobre its.arubything.com/2009/1/4/...
O que a opção git svn init "-s" faz? Não vejo isso nas páginas de manual do git svn.
— 18711 Nathan
Leia a página de manual novamente, talvez pesquise "-s" porque está lá. É um alias para "--stdlayout".
Git -> SVN com histórico completo de consolidação
Eu tinha um projeto Git e tive que movê-lo para o SVN. Foi assim que eu fiz, mantendo todo o histórico de confirmação. A única coisa que se perde é o tempo de confirmação original, já que o libSVN definirá o horário local quando o fizermos git svn dcommit.
Tenha um repositório SVN para o qual queremos importar nossas coisas e cloná-lo com git-svn:
Vá ali:
Adicione o controle remoto do repositório Git (neste exemplo, estou usando C: /Projects/repo.git ). Você deseja enviar para o SVN e dar o nome old-git:
Busque as informações da ramificação principal do repositório git antigo para o repositório atual:
Faça o checkout da ramificação principal do controle remoto antigo-git em uma nova ramificação chamada antiga no repositório atual:
Rebase para colocar o HEAD em cima do old-git / master. Isso manterá todos os seus commits. O que isso faz basicamente é pegar todo o seu trabalho realizado no Git e colocá-lo em cima do trabalho que você está acessando no SVN.
Agora volte ao seu ramo principal:
E você pode ver que possui um histórico de consolidação limpo. É isso que você deseja enviar para o SVN.
Envie seu trabalho para o SVN:
Isso é tudo. É muito limpo, sem hackers, e tudo funciona perfeitamente fora da caixa. Aproveitar.
Processo semelhante também detalhado em chani.wordpress.com/2012/01/25/…
— TWiStErRob 2/17/17
Parece. No entanto, acho o caminho dela bastante confuso e o meu é muito mais curto (8 passos que 19/23). Talvez eu não esteja entendendo corretamente, mas acho que ela mistura os comandos svn e git em sua segunda bala.
Ah, sim, a diferença é que seu processo importa o git para a raiz do repositório SVN, o seu importa para uma subpasta, é por isso que as poucas git svnpreparações são necessárias.
— TWIStErRob 4/17/17
Na etapa 7, não deveria haver uma fusão de git antiga? Para mim, parece que você está fazendo um compromisso de mestre que não mudou ?!
@Alexander usando o 'git rebase master', produzimos uma mesclagem de avanço rápido, que é uma mesclagem linear sem que um commit de mesclagem tenha dois pais. Queremos ter uma história linear aqui.
Eu proporia uma instrução muito curta em 4 comandos usando SubGit . Veja este post para detalhes.
— Dmitry Pavlenko
Eu precisava comprometer meu repositório Git existente em um repositório SVN vazio.
Foi assim que consegui fazer isso:
Funcionou sem problemas. Espero que isso ajude alguém.
Como tive que me autorizar com um nome de usuário diferente para o repositório SVN (meu originuso de autenticação de chave pública / privada), tive que usar a --usernamepropriedade
— Jay Linski
pode ser necessário instalar git-svnantes isso é possível, ver stackoverflow.com/questions/527037/git-svn-not-a-git-command
— flexponsive
Se você quiser continuar trabalhando com o Git como seu repositório principal e apenas precisar "exportar" as revisões para o SVN de tempos em tempos, poderá usar o Tailor para manter o repositório SVN sincronizado. Ele pode copiar revisões entre diferentes sistemas de controle de origem e atualiza o SVN com as alterações feitas no Git.
Eu não tentei uma conversão de Git para SVN, mas para um exemplo de SVN -> SVN, veja esta resposta .
Mais uma sequência que funcionou (com alguns comentários em cada etapa):
Instalar git-svne subversionkits de ferramentas:
Mudar dentro do PROJECT_FOLDER
Crie o caminho do projeto no servidor Subversion (infelizmente o git-svnplugin atual tem um defeito em comparação com o TortoiseSVN). Não é possível armazenar o código-fonte diretamente no PROJECT_FOLDER. Em vez disso, por padrão, ele fará o upload de todo o código PROJECT_FOLDER/trunk.
svn mkdir --parents protocol: /// caminho / para / repo / PROJECT_FOLDER / trunk -m "criando espaço reservado para o repositório git"
Este é o local onde trunkno final do caminho é obrigatório
Inicialize o git-svncontexto do plug - in dentro da .gitpasta
Este é o lugar onde trunkno final do caminho é desnecessário
Buscar uma Subversioninformação de repositório vazia
Esta etapa está ajudando a sincronizar o servidor Subversion com o git-svnplug - in. É o momento em que o git-svnplug-in estabelece o remotes/origincaminho e o associa à trunksubpasta no lado do servidor.
O rebase de confirmações antigas do Git aconteceu antes do git-svnenvolvimento do plug-in no processo (esta etapa é opcional )
Adicione arquivos novos / modificados para confirmar (esta etapa é regular para atividades do Git e é opcional )
Confirme arquivos adicionados recentemente no repositório Git local (esta etapa é opcional e só é aplicável se a etapa 7 tiver sido usada):
Enviando todo o histórico de alterações do projeto para o servidor Subversion:
— Oleg Kokorin
Você pode criar um novo repositório SVN. Exporte seu projeto Git (detalhando os arquivos .git). Adicione-o ao repositório SVN (inicializando o repositório com o que você tinha até agora no Git). Em seguida, use as instruções para importar repositórios SVN em um novo projeto Git.
Mas isso perderá seu histórico anterior do Git.
Se você não precisar usar nenhum SVN específico e estiver usando o GitHub, poderá usar o conector SVN.
Mais informações estão aqui: Colaborando no GitHub com Subversion
— elmariofredo
SVN o que? In ( "... qualquer SVN específico e ..." ). Versão SVN? Cliente SVN? Ou alguma outra coisa?
Gostaria de compartilhar uma ótima ferramenta que está sendo usada na comunidade WordPress chamada Scatter
Plugins do Git WordPress e um pouco de dispersão da sanidade
Isso permite que os usuários possam enviar seu repositório Git para o wordpress.org SVN automaticamente. Em teoria, esse código pode ser aplicado a qualquer repositório SVN.
— r109
O link parece estar efetivamente quebrado ( "O servidor no evansolomon.me está demorando muito para responder." ).
Recentemente, tive que migrar vários repositórios Git para o SVN e, depois de tentar todas as soluções que pude encontrar, o que finalmente funcionou para mim foi o Mercurial (sim, usando um terceiro VCS). Usando este guia , criei o seguinte processo (no Linux, mas a idéia básica também deve funcionar no Windows).
Os pacotes necessários:
O Mercurial precisa ser configurado adicionando o seguinte a ~/.hgrc:
Crie alguns diretórios de trabalho temporários (eu tinha vários repositórios para migrar, então criei diretórios para as versões SVN e Git, para mantê-los separados):
Faça um repositório SVN local vazio:
Clone o repositório Git existente:
Deixe o Mercurial fazer a sua coisa:
Agora, o repositório SVN deve conter o histórico completo de consolidação, mas não com registros de data e hora originais. Se isso não for um problema, pule a próxima parte para a etapa 11.
Com um pouco de trabalho, a data e hora de cada confirmação podem ser alteradas . Como meus repositórios são pequenos, era possível fazê-lo manualmente. Primeiro, crie um pre-revprop-changegancho no repositório SVN com o seguinte conteúdo, para permitir que a propriedade necessária seja modificada:
Este script deve ser tornado executável:
O Mercurial criou uma cópia de trabalho do repositório SVN, chamada projeto -wc, portanto, alterne para ele e edite os tempos de confirmação:
Digite a data e a hora corretas (preste atenção aos fusos horários!) E salve. Você deve receber uma mensagem dizendo "Definir novo valor para a propriedade svn: date na revisão 1".
Agora, enxágue e repita para todas as outras revisões.
Opcionalmente, verifique o histórico de confirmação para garantir que tudo esteja correto:
Volte um nível acima:
Despejar o repositório:
E carregue o dump no seu servidor Subversion. Feito!
Esse processo provavelmente também funcionaria diretamente entre repositórios remotos, mas achei mais fácil trabalhar com repositórios locais. Corrigir os tempos de consolidação foi muito trabalhoso, mas no geral o processo foi muito mais direto do que qualquer outro método que encontrei.
rebase: como as outras respostas
commit id: encontre svn primeiro commit id e git primeiro commit id, faça eco em .git / info / grafts: echo "git_id svn_id}" > .git/info/graftsthengit svn dcommit
confira cada commit do git, copie os arquivos para svn_repo, svn commit
demonstração do bash: demonstração do github
v1.x: use rebase e confirme o ID
v2.x: use arquivos de cópia e, em seguida, svn commit
— 张耀文
No meu caso, tive que iniciar um projeto limpo do SVN
adicione todas as fontes do seu projeto ...
— dangt85
Eu só quero compartilhar um pouco da minha experiência com a resposta aceita. Eu fiz todas as etapas e tudo estava bem antes de executar a última etapa:
Uso do valor não inicializado $ u na substituição (s ///) na /usr/lib/perl5/vendor_perl/5.22/Git/SVN.pm linha 101.
Uso do valor não inicializado $ u na concatenação (.) Ou string no /usr/lib/perl5/vendor_perl/5.22/Git/SVN.pm linha 101. refs / remotes / origin / HEAD: ' https://192.168.2.101/ svn / PROJECT_NAME 'não encontrado em' '
Encontrei o thread https://github.com/nirvdrum/svn2git/issues/50 e, finalmente, a solução que apliquei no arquivo a seguir na linha 101 /usr/lib/perl5/vendor_perl/5.22/Git/SVN.pm
— Pavel Slepiankou
E se você não quiser comprometer todos os commit que fizer no Git, no repositório SVN? E se você apenas quiser enviar seletivamente confirmações pelo canal? Bem, eu tenho uma solução melhor.
Eu mantenho um repositório Git local onde tudo o que faço é buscar e mesclar no SVN. Dessa forma, posso garantir que estou incluindo todas as mesmas alterações que o SVN, mas mantenho meu histórico de consolidação separado do SVN por completo.
Em seguida, mantenho uma cópia local de trabalho SVN separada, que está em uma pasta separada. É o que eu faço confirmado no SVN e simplesmente uso o utilitário de linha de comando do SVN para isso.
Quando estou pronto para confirmar o estado do meu repositório Git local no SVN, simplesmente copio toda a bagunça de arquivos na cópia de trabalho local do SVN e o confirmo a partir daí usando o SVN em vez do Git.