Subversion: Controlo total sobre o Software

Subversion em acção

Nesta secção vai-­se passar da ideia à acção, exemplificando na prática o uso do Subversion.

Cópias de trabalho

Como foi explicado acima, uma cópia de trabalho para o Subversion é apenas uma directoria no sistema local de trabalho de cada utilizador, que contém uma colecção de ficheiros. Cada utilizador pode editar os ficheiros como quiser, e se forem ficheiros de código-­fonte de uma qualquer linguagem de programação, o utilizador pode compilar o programa da maneira habitual com os editores ou IDEs que preferir. A cópia de trabalho é uma área de trabalho privada: o Subversion nunca vai incorporar nesta área de trabalho as alterações das outras pessoas, ou colocar as alterações feitas nessa área de trabalho visíveis aos outros utilizadores, até que se diga ao explicitamente ao Subversion para o fazer. É possível ainda ter várias cópias de trabalho do mesmo projecto.

Após terem sido feitas alterações aos ficheiros na cópia de trabalho pessoal de cada utilizador e de se verificar que estas funcionam correctamente, o Subversion fornece os comandos para se publicar as alterações para os outros utilizadores que trabalham no mesmo projecto (ao escrever para o repositório). Se outras pessoas publicarem as suas próprias alterações, o Subversion fornece comandos para unificar essas alterações na cópia de trabalho de cada um (ao ler do repositório).

Uma cópia de trabalho contém também alguns ficheiros extra, criados e mantidos pelo Subversion, para ajudar na execução dos comandos do Subversion. Em particular, cada directoria na cópia de trabalho contém uma subdirectoria chamada .svn, que é também conhecida por directoria administrativa da cópia de trabalho. Os ficheiros na directoria administrativa ajudam o Subversion a reconhecer que ficheiros contêm alterações por publicar, e que ficheiros estão fora-­do-­prazo (antigos) em relação ao trabalho feito pelos outros utilizadores.

Um repositório típico de Subversion contém frequentemente ficheiros (ou código-­fonte) de vários projectos; normalmente, cada projecto é uma sub-directoria na árvore do sistema de ficheiros do repositório. Por isso, a cópia de trabalho de um utilizador corresponde geralmente a uma sub-árvore particular do repositório global.

Por exemplo, suponhamos que temos um repositório Subversion que contém dois projectos de software, ProjX e ProjY. Cada projecto existe na sua própria sub-­directoria. Para ter uma cópia de trabalho, um utilizador tem de fazer check out a uma sub-­árvore do repositório (o termo check out pode parecer que se está a fazer algum bloqueio ou a reservar recursos, mas na verdade não; simplesmente cria uma cópia privada do projecto na máquina local do utilizador). Por exemplo, se o utilizador fizer check out ao ProjX/, fica com uma cópia local deste projecto:

$ svn checkout http://svn.exemplo.com/repositorio/ProjX
A   ProjX/Makefile
A   ProjX/classe.c
A   ProjX/LEIAME.txt
...
Checked out revision 29.
$ ls ­-A ProjX
Makefile   classe.c   LEIAME.txt ... .svn/

A lista que começa com A significa que o Subversion está a adicionar esses ficheiros à cópia de trabalho pessoal do utilizador. O utilizador possui agora uma cópia pessoal da directoria ProjX/ do repositório, com uma entrada adicional – .svn – que contém informação extra necessária ao Subversion, como mencionado acima.

Não apagar as pastas .svn; estas pastas ocultas são a porta de entrada da comunicação entre o cliente e o servidor de SVN.

Supondo que um utilizador fazia alterações no ficheiro classe.c, a directoria .svn/ lembra-­se da data original de modificação deste ficheiro e do conteúdo que tinha nessa data, e o Subversion pode assim indicar que o ficheiro foi alterado. No entanto, o Subversion não torna as alterações do utilizador públicas de imediato até que o utilizador indique explicitamente para tal. Publicar as alterações introduzidas em determinado ficheiro para ficarem visíveis aos outros utilizadores é feito através do comando commit ao repositório:

$ svn commit classe.c
Sending   classe.c
Transmiting file data .
Committed revision 30.

Agora que as alterações à classe.c foram colocadas no repositório, qualquer utilizador que faça check out à cópia de trabalho do ProjX/ vai poder ver as alterações introduzidas na última versão do ficheiro classe.c. Suponhamos agora que a Alexandra fez check out à sua cópia de trabalho do ProjX/ ao mesmo tempo que o Hugo. Quando o Hugo faz commit às alterações do ficheiro classe.c, a cópia de trabalho da Alexandra fica inalterada; o Subversion apenas modifica uma cópia de trabalho a pedido do utilizador. Para colocar o seu projecto actualizado, a Alexandra faz um pedido ao Subversion para fazer update à sua cópia de trabalho, usando para isso o comando update. Isto vai incorporar as alterações do Hugo no ficheiro classe.c, bem como outras alterações feitas pelos outros utilizadores do projecto desde que a Alexandra fez check out ao repositório de Subversion.

$ pwd
/repositorio/ProjX/
$ ls ­-A
.svn/ Makefile classe.c LEIAME.txt ...
$ svn update
U   classe.c
Updated to revision 30.

A saída do comando svn update indica que o Subversion fez uma actualização aos conteúdos do ficheiro classe.c. Note-­se que a Alexandra não precisou de especificar a que ficheiros fazer o update; o Subversion usa a informação da directoria .svn, e outras informações contidas no repositório, para decidir que ficheiros precisam de ser actualizados na cópia de trabalho da Alexandra.

Começar a usar o Subversion

De seguida apresenta-­se um exemplo de utilização do Subversion para que se consiga ter uma percepção mais abrangente das vantagens de utilização deste software de controlo de versões. O seguinte exemplo assume que já esteja instalado o svn – o cliente de linha de comandos do Subversion – e o svnadmin – a ferramenta administrativa – e que estejam prontos a usar. Assume também que se esteja a usar o Subversion 1.4 ou mais recente (executar svn --version para verificar a versão).

O Subversion guarda todas versões do software num repositório central. Para começar, criar um novo repositório:

$ svnadmin   create   /usr/local/share/repositorio/  
$ ls /usr/local/share/repositorio/
conf/   dav/   db/   format  hooks/   locks/  README.txt

Podemos também criar um repositório através do TortoiseSVN, começando por criar uma pasta e seleccionando a opção Create Repository here… com o botão direito do rato em cima da pasta para o repositório.

Este comando cria uma nova directoria (no exemplo acima, em /usr/local/share/repositorio) que contém um repositório de Subversion. Esta directoria contém para além de outros ficheiros, uma colecção de ficheiros de base de dados. Porém, não se acede aos ficheiros do software e às diferentes versões se explorarmos o repositório de Subversion acabado de criar. O Subversion não tem o conceito de “projecto”. O repositório é apenas um sistema de ficheiros virtual com versões, uma árvore de ficheiros que pode conter qualquer tipo de ficheiro que se queira. Alguns programadores preferem guardar apenas um só projecto num repositório, enquanto que outros guardam vários projectos no repositório guardando cada um deles em directorias separadas. De qualquer forma, o repositório apenas guarda ficheiros e directorias, cabe aos programadores saber que directorias e ficheiros pertencem a determinado projecto. Assim, tudo o que realmente se está a falar quando se fala de repositórios de Subversion é de uma colecção de directorias e de ficheiros à qual o Subversion não conhece a que projecto pertence cada ficheiro ou directoria.

Supondo que o software a partir do qual se quer começar a depender do Subversion está numa pasta designada /usr/local/share/softwareXPTO/, começa-­se por criar três directorias com os nomes branches, tags e trunk. A pasta trunk deverá conter todo o código de software e ficheiros dependentes, enquanto que as pastas branches e tags deverão estar vazias:

/usr/local/share/softwareXPTO/branches/
/usr/local/share/softwareXPTO/tags/
/usr/local/share/softwareXPTO/trunk/
                       ficheiroA.c
                       ficheiroB.h
                       ficheiroC.html
                       Makefile
                       configure
                       ...

Uma vez criadas estas sub­directorias, importa-­se a pasta do software para o repositório criado com o comando svn import:

$ svn import /usr/local/share/softwareXPTO/ 
 file:///usr/local/share/repositorio/softwareXPTO  
­-m “import inicial para o repositório”
Adding   /usr/local/share/softwareXPTO/branches
Adding   /usr/local/share/softwareXPTO/tags
Adding   /usr/local/share/softwareXPTO/trunk
Adding   /usr/local/share/softwareXPTO/trunk/ficheiroA.c
Adding   /usr/local/share/softwareXPTO/trunk/ficheiroB.h
Adding   /usr/local/share/softwareXPTO/trunk/ficheiroC.html
Adding   /usr/local/share/softwareXPTO/trunk/Makefile
Adding   /usr/local/share/softwareXPTO/trunk/configure
…
Committed revision1.

Com o TortoiseSVN a operação é semelhante: depois de criar o repositório SVN, é só escolher a opção Import… a partir da directoria do software e escolher o repositório criado.

O repositório contém nesta altura a árvore de ficheiros pretendida. Como foi mencionado acima, não se acedem aos ficheiros do projecto de software olhando directamente para o conteúdo do repositório; o código fica armazenado numa base de dados dentro do repositório.

Para começar a manipular os dados no repositório, é necessário criar uma cópia de trabalho (working copy) dos dados, como se fosse uma área de trabalho privada. Para tal, pede-­se ao Subversion para fazer um check­out da cópia de trabalho da directoria /usr/local/share/repositorio/softwareXPTO/trunk no repositório:

$ svn checkout file:///usr/local/share/repositorio/softwareXPTO/trunk softwareXPTO
A   softwareXPTO/ficheiroA.c
A   softwareXPTO/ficheiroB.h
A   softwareXPTO/ficheiroC.html
A   softwareXPTO/Makefile
A   softwareXPTO/configure
...
Checked out revision 1.

Após esta operação, temos uma cópia pessoal de parte do repositório numa directoria chamada softwareXPTO. Pode-­se editar os ficheiros na cópia de trabalho e depois fazer commit a essas alterações de novo para o repositório.

  • Dentro da pasta da cópia de trabalho editar e alterar o conteúdo de um ficheiro;
  • Fazer svn diff para ver uma saída das diferenças unificadas das alterações feitas;
  • Fazer svn commit para introduzir a nova versão dos ficheiros no repositório;
  • Fazer svn update para colocar na cópia de trabalho a versão mais actual do repositório.

A partir deste ponto pode tornar-se o repositório acessível a outros utilizadores e/ou programadores numa rede de computadores.