Este artigo é dedicado a todos aqueles que já enviaram um commit equivocado para o SVN e quebraram ou estragaram alguma coisa no sistema onde trabalham. Quem nunca fez isso antes, que atire a primeira pedra!!
Bom, mas vamos lá.... A reposta para a pergunta acima é bem simples: não há como. Meu Deus, então agora estou perdido?? Calma, não se preocupe!! Existe uma técnica que lhe permite reverter o seu repositório para um estado anterior, se for realmente preciso. Acompanhe nosso artigo.
Se desejar, você pode ir imediatamente para a solução do problema, lá embaixo. Entretanto, eu resolvi incluir esta seção aqui para lhe ajudar a pensar mais sobre como funciona o SVN e quais as suas premissas, aumentando seu conhecimento sobre o mesmo.
O SVN armazena seus dados em um banco de dados interno (ou em BDB - Berkeley Data Base, ou em FSFS). Evidentemente, seria possível fazer operações comuns a bancos de dados, como delete ou roll back. Contudo, o Subversion não permite qualquer tipo de remoção de entradas (inserts) de dados que foram efetivadas, sob risco de comprometer a segurança do repositório. Observe o risco a que os desenvolvedores estariam sujeitos e a falta de confiança que se geraria sobre os repositórios se isso fosse possível, considerando cenários como:
Por motivos como estes, a remoção direta de commits não é possível. No entanto, existe a solução paliativa, um pouco mais agressiva, porém que funciona e é razoavelmente fácil e segura. Acompanhe-a na próxima seção!!
Se é realmente necessário remover um ou mais commits do SVN, e espero que tenham sido os últimos, então a única solução é fazem um dump do repositório filtrado pelo número de revisão, eliminá-lo, recriá-lo e restaurar o dump com um load, de forma a carregar no repositório recém-criado todas as revisões até a última antes das indesejadas. Todas estas ações devem ser feitas como root!! Vamos fazer isso passo a passo...
1. Fazendo o dump:
Considere que seu repositórios se chame "repo" e você está no diretório onde ele se encontra. Primeiramente, pare todos os acessos ao repositório, para congelá-lo (ou seja, pare o Apache, se você usa o WebDAV, ou impeça o login via SSH de usuários comuns, se você usa o protocolo svn+ssh://). Descubra o número da última revisão boa (desejada), a partir da qual todas serão eliminadas (suponhamos: revisão 200), para que façamos o dump de tudo até ela. Agora, considerando esta revisão, faça o dump:
É criado o arquivo repo.dump, que contém todas as revisões deste o tenro início de seu repositório até a revisão informada, de número 200.
2. Remova o repositório e crie outro idêntico:
Se você quiser, por segurança, pode mover o repositório para outro nome ao invés de apagá-lo, de forma a manter uma cópia de segurança do mesmo, caso alguma operação falhe. Você pode também fazer um backup do diretório completo do repositório ou armazená-lo em um arquivo .tar.gz, para economizar espaço, caso o repositório seja muito grande.
Isto recria o repositório com mesmo nome, só que agora completamente vazio.
3. Agora sim, subindo tudo!!
Rode o comando, considerando o arquivo de dump gerado e o repositório novo recém-criado. Observe que, evidentemente, convém utilizar o mesmo nome do repositório antigo, para que outras configurações de seu sistema permaneçam válidas:
Se tudo deu certo até aqui, você terá seu repositório recuperado até a revisão que você informou no dump, de forma que as posteriores foram ignoradas e serão perdidas.
4. Para finalizar, não esqueça deste procedimento!! Atribua as mesmas permissões de arquivos, dono e grupo originais às pastas do repositório, especialmente ao diretório "db" e seus arquivos. Se você usa o WebDAV, por exemplo, terá de tornar os arquivos pertencentes ao usuário "www-data" (ou o nome que tem seu usuário do Apache), e não "root", como é inicialmente criado. Não esqueça de verificar se os diretórios estão marcados como executáveis, se for o caso, para permitir a criação de novos arquivos de log no diretório "db".
5. Teste tudo bem detidamente, para evitar surpresas. Em tudo funcionando, finalmente, faça a faxina: elimine ou faça backup do repositório antigo e dos arquivos de dump que ainda estão no disco.
Bom, pessoal, testei realmente todos estes comandos, embora eu mesmo já tenha me visto em situações de utilizar este mecanismo para eliminar commits errados. Torço que tudo dê certo com vocês!!
Mais detalhes sobre administração de repositórios, consultem o manual do SVN (SVN Red Book), Capítulo 5. Veja também nosso artigo completo sobre Como Fazer Backup de Repositórios SVN. E, claro, COMENTEM!!!
Bom, mas vamos lá.... A reposta para a pergunta acima é bem simples: não há como. Meu Deus, então agora estou perdido?? Calma, não se preocupe!! Existe uma técnica que lhe permite reverter o seu repositório para um estado anterior, se for realmente preciso. Acompanhe nosso artigo.
- Por Que não há uma Forma Direta de Desfazer Commits??
Se desejar, você pode ir imediatamente para a solução do problema, lá embaixo. Entretanto, eu resolvi incluir esta seção aqui para lhe ajudar a pensar mais sobre como funciona o SVN e quais as suas premissas, aumentando seu conhecimento sobre o mesmo.
O SVN armazena seus dados em um banco de dados interno (ou em BDB - Berkeley Data Base, ou em FSFS). Evidentemente, seria possível fazer operações comuns a bancos de dados, como delete ou roll back. Contudo, o Subversion não permite qualquer tipo de remoção de entradas (inserts) de dados que foram efetivadas, sob risco de comprometer a segurança do repositório. Observe o risco a que os desenvolvedores estariam sujeitos e a falta de confiança que se geraria sobre os repositórios se isso fosse possível, considerando cenários como:
- Um desenvolvedor ou administrador de sistemas é demitido. Num acesso de raiva e considerando-se injustiçado, ele remove grande parte dos commits dos repositórios da empresa, deixando-os em estados muito primitivos e perdendo grande parte dos códigos gerados durante anos.
- Um desenvolvedor mal intencionado pratica sabotagem industrial: elimina ou deturpa parte do código do sistema antes do mesmo ser compilado e o envia para produção. Após a implantação do sistema danificado, o desenvolvedor remove o trecho defeituoso que criou, eliminando a única prova concreta de sua ação.
- Imagine que ninguém será demitido e não há qualquer pessoa mal intencionada. Ao contrário: todos trabalham felizes e freneticamente. Contudo, a equipe tem o hábito de, vez por outra, remover um commit mal feito. A uma certa altura, descobre-se um erro grave no sistema que está há mais de 1 mês em produção. A correção parece simples e poderia ser feita em cerca de um dia. Contudo, a quantidade de commits removidos impede que se consiga restaurar o código exato da versão que está em produção. Resultado: o erro vai persistir lá até que a versão seguinte seja totalmente finalizada e implantada...
Por motivos como estes, a remoção direta de commits não é possível. No entanto, existe a solução paliativa, um pouco mais agressiva, porém que funciona e é razoavelmente fácil e segura. Acompanhe-a na próxima seção!!
- Removendo um Commit Indesejado
Se é realmente necessário remover um ou mais commits do SVN, e espero que tenham sido os últimos, então a única solução é fazem um dump do repositório filtrado pelo número de revisão, eliminá-lo, recriá-lo e restaurar o dump com um load, de forma a carregar no repositório recém-criado todas as revisões até a última antes das indesejadas. Todas estas ações devem ser feitas como root!! Vamos fazer isso passo a passo...
1. Fazendo o dump:
Considere que seu repositórios se chame "repo" e você está no diretório onde ele se encontra. Primeiramente, pare todos os acessos ao repositório, para congelá-lo (ou seja, pare o Apache, se você usa o WebDAV, ou impeça o login via SSH de usuários comuns, se você usa o protocolo svn+ssh://). Descubra o número da última revisão boa (desejada), a partir da qual todas serão eliminadas (suponhamos: revisão 200), para que façamos o dump de tudo até ela. Agora, considerando esta revisão, faça o dump:
svnadmin dump repo --revision 0:200 > repo.dump
É criado o arquivo repo.dump, que contém todas as revisões deste o tenro início de seu repositório até a revisão informada, de número 200.
2. Remova o repositório e crie outro idêntico:
Se você quiser, por segurança, pode mover o repositório para outro nome ao invés de apagá-lo, de forma a manter uma cópia de segurança do mesmo, caso alguma operação falhe. Você pode também fazer um backup do diretório completo do repositório ou armazená-lo em um arquivo .tar.gz, para economizar espaço, caso o repositório seja muito grande.
rm -rf repo
svnadmin create --fs-type bdb repo
Isto recria o repositório com mesmo nome, só que agora completamente vazio.
3. Agora sim, subindo tudo!!
Rode o comando, considerando o arquivo de dump gerado e o repositório novo recém-criado. Observe que, evidentemente, convém utilizar o mesmo nome do repositório antigo, para que outras configurações de seu sistema permaneçam válidas:
svnadmin load repo < repo.dump
Se tudo deu certo até aqui, você terá seu repositório recuperado até a revisão que você informou no dump, de forma que as posteriores foram ignoradas e serão perdidas.
4. Para finalizar, não esqueça deste procedimento!! Atribua as mesmas permissões de arquivos, dono e grupo originais às pastas do repositório, especialmente ao diretório "db" e seus arquivos. Se você usa o WebDAV, por exemplo, terá de tornar os arquivos pertencentes ao usuário "www-data" (ou o nome que tem seu usuário do Apache), e não "root", como é inicialmente criado. Não esqueça de verificar se os diretórios estão marcados como executáveis, se for o caso, para permitir a criação de novos arquivos de log no diretório "db".
5. Teste tudo bem detidamente, para evitar surpresas. Em tudo funcionando, finalmente, faça a faxina: elimine ou faça backup do repositório antigo e dos arquivos de dump que ainda estão no disco.
Bom, pessoal, testei realmente todos estes comandos, embora eu mesmo já tenha me visto em situações de utilizar este mecanismo para eliminar commits errados. Torço que tudo dê certo com vocês!!
Mais detalhes sobre administração de repositórios, consultem o manual do SVN (SVN Red Book), Capítulo 5. Veja também nosso artigo completo sobre Como Fazer Backup de Repositórios SVN. E, claro, COMENTEM!!!