Controle de versões com SVN localmente

Eu sempre precisei de um sistema para controle de versões e nunca soube que era isso que eu precisava para ser feliz. Talvez você passe pela mesma situação que eu então ai vai uma dica muito útil.

Vamos a teoria (muito breve) e depois a prática (mais longa e interessante).

O que é?

Um sistema de controle de versão é um sistema de armazenamento que permite guardar os seus arquivos, mantendo um controle de cada alteração feita nele

De forma bem direta, entenda-o como um backup incremental, onde você coloca um arquivo lá e a partir daí  poderá adicionar as alterações de forma que a qualquer momento seja possível recuperar as versões anteriores.

Pra que serve isso?

Imagine que você tenha um conjunto de arquivos que serão modificados com muita freqüência. Como o código fonte daquele seu projeto WEB, a sua aplicação standalone feita em MS Visual Studio para controle de estoque, ou ainda os arquivos Tex da sua dissertação/tese etc. Emfim, qualquer arquivo que seja muito modificado.

Você pode armazenar estes arquivos em repositório SVN e toda a vez que você precisar alterá-los você faz uma cópia deles, altera o que desejar e depois volta com as alterações para o repositório. Desta forma vamos supor que as alterações de ontem causaram problemas inesperados e você não faz a menor idéia de quais arquivos você alterou, ou sabe que arquivo foi alterado, mas não sabe quais linhas. Se você tiver o controle de versões poderá voltar todos os arquivos do dia anterior ao problema.

Por esta explicação parece que essa coisa de controle de versões é realmente um backup, mas na realidade é muito mais do que isso, pois o controle de versões é dinâmico e pode ser disparado a partir de diversas ferramentas de desenvolvimento como Eclipse, Anjuta, E-macs etc.

Só existe o SVN para este serviço?

Não! O SVN é só mais um deles, mas existem outros como o vovô CVS, e o expertíssimo GIT, filho mais novo do nosso conhecido Linus Torvald, e que inclusive é usado para controlar versões do Kernel Linux.

O SVN foi minha escolha porque eu o achei bem simples de trabalhar, além de ter sido a minha primeira experiência com versionamento.

Como usar isso?

Basicamente, existe duas formas para se usar o SVN. A forma local que é ideal para apenas um usuário – recomendável para projetos seus e que esteja exclusivamente em sua máquina, a forma remota que inicia um serviço em segundo plano e que fica permanentemente escutando a porta tcp/3690.

Para simplificar daqui a diante você terá a exemplificação de como usar o SVN de forma local. A forma remota vai ficar pra outro dia 😉

Mas antes de mais nada instale o pacote “Subversion” em sua estação pois ele tem tudo o que precisamos.

Considerando que você esteja usando uma distribuição baseada no Debian como Ubuntu, Kurumin etc o comando será esse:

$ sudo aptitude search subversion

Ou use o gerenciador de pacotes da sua distribuição preferida.

SVN Local

Uma vez que o Subversion esteja instalado você deverá escolher um lugar onde os seus repositórios serão guardados.

Particularmente eu costumo usar uma pasta dentro de /home, convenientemente chamada “subversion” e com permissão de escrita para o meu usuário padrão (lembrando que estamos falando de repositório local para um só usuário. Então vamos lá:

1 – Criando um diretório

Crie um diretório onde você possa dar permissões para quem você quiser acessá-lo com permissões de leitura e escrita (este diretório, não será o repositório ainda, mas um local onde estarão todos os seus repositórios)

$ sudo mkdir /home/subversion

2 – Ajustando as permissões

Dê permissões para o seu usuário poder atualizar os repositórios.

$ sudo chown wbraga. /home/subversion

3 – Criando o seu repositório

Entre neste diretório e crie um novo repositório

$ cd /home/subversion
$ svnadmin create intranet

ou apenas

$ svnadmin create /home/subversion/intranet

Uma palavra sobre repositórios locais, usuários e permissões

Este tipo de repositório (local) não é a melhor forma de versionamento a ser lidada por diversos usuários. Isso é muito funcional e prático para apenas UM usuário, mais que isso você deveria pensar em levantar o serviço svnserver e que poderá gerenciar tais questões, ou ainda através do Apache com modulo WebDAV (que estão fora do escopo deste artigo).

Na realidade é possível usar repositórios locais com vários usuários sim, mas você terá que dar permissões de escrita e setar os grupos com freqüência no(s) diretório(s) e arquivo(s) do seu repositório:

$ chmod -R g+w /home/subversion/bin
$ chgrp -R subversion /home/subversion/bin

Para simplificar isso poder-se-ia usar scripts de hook (script executados antes/após certos eventos – vide documentação oficial), mas isso pode ser trabalho desnecessário de se realizar também. Não reinvente a roda, esta forma é meramente um brinquedo para nerd e não deve ser usada assim para um grande projeto onde várias pessoas estarão trabalhando, ou você vai amargar o stresse por excesso de trabalho desnecessário.

4 – Importando o seu projeto

Agora é que tudo efetivamente começa. Importe os arquivos que você deseja gerenciar para o seu novo repositório:

$ svn import /var/www/intranet file:///home/subversion/intranet

Esteja atento as 3 (três) barras após o “file:”. Ao confirmar esse comando (teclando ENTER) será aberto o editor de textos padrão da sua distro (nano, pico, vi etc) onde você deverá descrever o que está sendo feito. Por exemplo, a frase “Importação inicial da Intranet para o SVN”. Após escrever, saia deste editor salvando as alterações e aguarde a importação terminar.

Isso deverá gerar algumas linhas como estas:

Adicionando /home/arquivos/Projetos/duplicatas/teste.py


Adicionando /home/arquivos/Projetos/duplicatas/arquivo.py
Adic. (bin) /home/arquivos/Projetos/duplicatas/teste.pyc

Commit da revisão 1.

E no final todo o diretório /var/www/intranet estará copiado para o seu repositório local “intranet”, onde as versões serão gerenciadas.

A cópia de trabalho

O repositório está criado, seu projeto está importado e agora você precisa trabalhar com ele. Se você olhar o conteúdo do diretório /home/subversion/intranet você certamente não encontrará seus arquivos lá dentro. O subversion usa um banco de dados simples, porém robusto, para guardar o seu controle de versões então para lidar com os seus arquivos você precisará usar uma cópia a qual é conhecida por “Workcopy” será aqui onde você vai trabalhar e no final fará um “commit” das alterações.

Para criar a cópia de trabalho use o comando abaixo:

$ svn checkout file:///home/subversion/intranet /tmp/minhacopia

Ao confirmar você verá as mensagens, como a seguir:

A /tmp/minhacopia/teste.py

A /tmp/minhacopia/arquivo.py
A /tmp/minhacopia/teste.pyc
Gerado cópia de trabalho para revisão 1.

Indicando que sua cópia de trabalho está pronta para uso e agora você poderá alterar a vontade os seus arquivos que estão na cópia de trabalho. É importante avisar que o comando “svn” que será usado daqui em diante deverá ser executado SEMPRE de dentro do seu diretório com a cópia de trabalho. Portanto use “cd /tmp/minhacopia” antes de começar o trabalho.

Considerações: Eu poderia usar os arquivos originais em minha máquina “/var/www/intranet” como cópia de trabalho?
Sim e não!

Sim, poderia. Já que tudo não passa de arquivos e diretórios e bastaria ajustar as permissões pronto.

Não, não poderia. Porque se fizer isso você teria que importar todos os arquivos novamente ao terminar o trabalho, ao invés de fazer um “commit” o que quebraria o recurso de versionamento, afinal o “import” é para ser feito uma só vez e as demais alterações são transferidas com “commit”.

Ainda há a possibilidade de você dar um “checkout” para /var/www/intranet, ao invés de um outro diretório temporário, mas lembre-se da assombração chamada “permissões”. Os arquivos que forem para o repositório terão sempre o usuário que o colocou lá como dono, logo, se a sua intranet (como nesse exemplo) tiver uma estrutura de permissões complexas (cada pasta com um grupo, dono etc) você poderá ter problemas com isso.

Salvando as alterações no repositório

Terminando as suas edições agora você precisa devolver o(s) arquivo(s) modificados para o repositório, para que num próximo sincronismo por outro usuário, ou você mesmo, receba-se a última edição do arquivo. Para isso use o comando:

$ svn commit

Como não foi especificada nenhuma mensagem para registrar no log, um editor de textos será aberto para este propósito (assim como ocorreu na importação). Isso poderia ser evitado (caso quisesse) usando o parâmetro -m “mensagem” ou -F arquivo_de_mensagem.txt no final do comando acima.

Ao confirmar o comando você verá a seguinte mensagem:

Enviando teste.py
Transmitindo dados do arquivo .
Commit da revisão 2.

Onde teste.py foi o arquivo modificado. Uma lista bem maior seria exibida se eu alterasse vários arquivos.

Mantendo-se em dia com as novidades

Eventualmente você precisa sincronizar sua cópia local com o repositório.
Quando você usa o commit você está apenas enviando suas modificações, mas quando outras pessoas manipulam o mesmo projeto elas farão as atualizações delas e você precisa recebê-las. Para isso atualize sua cópia local com certa freqüência usando o comando:

$ svn update

Em projetos muito “badalados” não é muito bom que você fique mais do que um dia sem dar um update pois poderá estar realizando alterações em arquivos já obsoletos. Ao confirmar o comando acima você terá uma mensagem parecida com:

M artigos.xml
Atualizado para revisão 10.

Isso indica que o repositório já foi atualizado 10 vezes e desde o seu último update até agora apenas o “artigos.xml” foi modificado. Após o update estes arquivos serão atualizados na sua cópia de trabalho.

Divertindo-se pra valer com o SVN

Vamos acelerar a explicação de alguns pontos importantes e que você precisa saber.

Incluindo novos arquivos

Caso você inclua novos arquivos em sua cópia local do projeto e que precisem ser encaminhadas para o repositório você deverá fazer isso com o comando ADD que registra um novo arquivo a ser adicionado no repositório:

$ svn add lancamento.html
A lancamento.html

No próximo commit este arquivo será enviado:

$ svn commit
Adicionando lancamento.html
Transmitindo dados do arquivo .
Commit da revisão 14.

Note que o arquivo só será transferido realmente para o repositório no seu proximo COMMIT.

Removendo arquivos desnecessários

Se determinado(s) arquivo(s) não servem mais no projeto você deverá removê-lo da seguinte forma:

$ svn rm resumo2004.html
D resumo2004.html

Lembrando que a reoção no repositório, efetivamente ocorrerá ro próximo commit

$ svn commit
Apagando resumo2004.html
Commit da revisão 16.

Voltando no tempo

Apagou um arquivo por engano, alterou tanta coisa que nem lembra mais o que foi e derrepente tudo parou de funcionar? Relaxe, é só voltar no tempo e reverter a sua cópia local para uma revisão estável.

Supondo que o problema todo foi causado pela exclusão do arquivo resumo2004.html que ocorreu na revisão 16, então volte para revisão 15

$ svn update -r 15
A resumo2004.html
Atualizado para revisão 15.

Observe que o que estamos fazendo é apenas um update em que foi especificado para qual revisão desejamos. Desta forma ao invés recebermos a última versão receberemos e versão especificada.

Diga-me tudo, não esconda nada

Se você não sabe para qual revisão voltar use o log para ver o que foi feito em cada revisão. Se você foi um bom menino e registrou suas alterações antes de executar cada commit, então você saberá exatamente para qual revisão reverter o trabalho.

$ svn log -r 14:16
————————————————————————
r14 | wbraga | 2007-06-07 15:20:26 -0300 (Qui, 07 Jun 2007) | 2 lines

Incluindo o arquivo lancamento.html

————————————————————————
r15 | wbraga | 2007-06-07 16:30:00 -0300 (Qui, 07 Jun 2007) | 2 lines

Lançamento da campanha contra desperdício de energia em lancamento.html

————————————————————————
r16 | wbraga | 2007-06-07 17:27:44 -0300 (Qui, 07 Jun 2007) | 3 lines

Removendo o lancamento.html novamente. por onde do chefe a campanha não
sairá

————————————————————————

Veja neste exemplo que estamos visualizando o log das revisões 14,15 e 16. Se quiséssemos ver todo o log bastava não limitar o número da revisão.

Só isso!?

É isso ai. Não vou detalhar mais o assunto pois como eu disse este é um meio muito rudimentar de lidar com versionamento e convenhamos, atualmente é muito mais comodo trabalhar no modo gráfico então use um cliente gráfico como um destes:

  • Para linha de comandos use o svn e svnadmin
  • Para gnome use o RapidSVN
  • Para Windows use o TortoiseSVN

Veja mais ferramentas gráficas para administrar o seu repositório no site oficial do Subversion.

Faltou mostrar aqui como criar um diretório, por exemplo (vide o comando svn mkdir) que é útil porém simples, e mais simples ainda via interface gráfica. E até acredito que apesar de ter usado uma intranet como exemplo de projeto o prezado leitor tenha percebido que esta forma de uso do SVN é mais útil para projetos locais, como uma aplicação standalone, ou algo que não precise ser enviada para um servidor para ser testada, a não ser é claro que você mantenha um servidor Web rodando localmente e sua workcopy esteja na raiz deste servidor.

Num próximo artigo eu vou mostrar como colocar um repositório remoto e multi-usuário no ar.

6 comentários em “Controle de versões com SVN localmente”

  1. Prezado Welington Braga,

    Gostei muito do seu trabalho sobre SVN e gostaria de saber onde eu posso encontrar orientações de como migrar arquivos em CVS para SVN.

    Antecipamente agradecido,

    Adilson Vasconcelos.

  2. Valeu Adilson,

    Espero que o artigo tenha sido realmente útil. Quanto ao CVS, existe um pacote chamado cvs2svn (pelo menos no meu Ubuntu tem), conforme a descrição abaixo. Não sei como funciona mas acredito que não tenha mistérios não.

    $ aptitude show cvs2svn
    Pacote: cvs2svn
    Estado: não instalado
    Versão: 1.5.0-1
    Prioridade: opcional
    Seção: universe/devel
    Mantenedor: Ubuntu MOTU Developers
    Tamanho Descompactado: 672k
    Depende de: python-support (>= 0.2), subversion (>= 1.0.1), rcs
    Recomenda: mime-support
    Sugere: cvs
    Descrição: Convert a cvs repository to a subversion repository
    Converts a CVS repository (including its branches and tags) to a Subversion
    repository. It is designed for one-time conversions, not for repeated
    synchronizations between CVS and Subversion.

  3. Viva,

    Algo que deve ser ressaltado para quem esta iniciando no controle de versões, mas que é pouco comentado nos tutoriais e artigos:

    Depois que seu projecto está sobre um controle de versões, nunca, mas nunca mais utilize comandos do sistema operacional (Ex: cp, mv, rm…) para manipular directorios! Sempre utilize os comandos equivalentes do seu sistema de controle de versões! Como por exemplo svn cp, svn mv etc…

  4. Isso ai @Steven .

    Estou para publicar esta semana ou na próxima uma texto sobre clientes subversion integrados ao gerenciador de arquivos. Isso definitivamente “mata” este problema.

    Para modo texto, existe a possibilidade de usar alias de comandos no bash, mas confesso que comecei a fazer umas rotinas para este fim e acabei parando por falta de tempo, mas estava ficando legal. Se algum dia elas estiverem funcionais eu as publico para que seja uteis para mais alguém.

    Abç.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.