O controlo de versões de um software sempre foi uma questão muito importante e delicada para qualquer programador que se preze. É actualmente impensável desenvolver projectos de software complexos e com requisitos que estão frequentemente a mudar, sem ter um sistema que controle tudo o que acontece ao software: as alterações ao código, a possibilidade de voltar sempre atrás até uma versão estável do software (óptimo quando ocorrem erros e se precisa de regredir no código), ver que alterações foram feitas no código globalmente ou apenas numa porção deste (incluindo as respostas às perguntas: quando? por quem? para que fim? em que ficheiros?), controlar eficazmente a fusão (em Inglês, merge) das alterações em vários módulos separados de software num mesmo produto unificado, e também controlar a própria documentação do software.
Sem dúvida que em qualquer projecto de software (por muito pequeno ou muito grande que seja), o controlo da informação é crucial para o sucesso do mesmo. Por isto mesmo, a tarefa de controlar as versões de um software não é de todo fácil, nem todos os sistemas de controlo de versões, ou VCS (Version Control System), são iguais e com as mesmas funcionalidades.
Neste artigo vamos ver como funciona o Subversion (também conhecido por SVN): um sistema de controlo de versões open source (software livre) de enorme sucesso actual. Vamos ver também como se instala o Subversion (cliente e servidor) para as plataformas Linux (distribuição Ubuntu) e Windows, como se configura o servidor HTTP da Apache (usufruindo logo à partida das vantagens da autenticação e autorização) para usar URLs dos repositórios SVN, como se usa o Subversion no dia-a-dia do trabalho de um programador e por fim, que ferramentas gráficas ou IDEs (Integrated Development Environment) existem à disposição de todos para serem usadas com o Subversion.
No final da leitura deste artigo, espera-se que se fique a conhecer e a saber usar o Subversion como uma ferramenta de trabalho muito útil para qualquer programador (e mesmo não-programador) no que toca à gestão das alterações do software, ou seja, controlando totalmente o percurso do software.
Porquê controlar o que acontece ao Software?
As funcionalidades básicas de qualquer sistema de controlo de versões são o de permitir anotar todas as alterações dos ficheiros ao longo do tempo e de unir as contribuições de vários programadores. Para suportar isto, o VCS tem de manter um histórico de todas as alterações que foram feitas ao longo do tempo por diferentes pessoas. Desta forma, é possível voltar atrás no código até uma revisão mais antiga, e ver que aspecto tinham os ficheiros nessa altura. Para além disso, o VCS tem de garantir sempre a correcta integração das alterações feitas no código.
Mas o que se ganha efectivamente com o controlo das versões de software? Especialmente, para uma equipa pequena que benefícios se podem tirar de um bom VCS que valham a pena perder tempo a aprender como usá-lo no dia-a-dia? Eis algumas das razões para usar sempre um VCS:
- Integridade dos Dados
- Um bom VCS ajuda a proteger a integridade dos dados. Ao manter um histórico das revisões (que são os conjuntos atómicos de alterações) deixa de haver a preocupação de possivelmente se estar a apagar código que mais tarde vamos perder tempo a reproduzir e que afinal era mesmo importante. Com um bom VCS podemos voltar sempre a qualquer snapshot do código, inclusivamente a esse momento anterior a termos apagado código. Esta característica também é útil no backup de dados, porque se os programadores guardarem regularmente as suas alterações no repositório central (no SVN, isto designa-se de commit) que tem todo o código, então é fácil ter um processo automático que arquive todo este código do repositório, e assim resolve-se o problema do código não estar unicamente no computador de um programador (mesmo à espera que aconteça aquela falha inevitável no disco :-).
- Produtividade
- Ao libertar os programadores da tarefa árdua de ter que integrar manualmente todas as alterações que fizeram (e tipicamente em muitos ficheiros ao mesmo tempo), um VCS pode aumentar bastante a produtividade na criação de software. De facto, com um bom VCS os programadores conseguem testar as alterações que fizeram e que outros programadores fizeram, resolver possíveis conflitos de código (que correspondem a mudanças nos mesmos ficheiros e nas mesmas linhas desses ficheiros) mesmo antes de incluir esse código no repositório central, e de uma forma automática. E, com mais tempo para programar, nasce melhor software (se o programador não se distrair das suas programações).
- Gestão de projectos
- Um bom VCS consegue reunir rapidamente um conjunto de informações muito úteis para um gestor de projectos: quem alterou o quê, quando, porquê, quantas modificações fez no mesmo projecto (ou módulo), e se as alterações feitas vão de encontro à finalidade do projecto (por exemplo, se existirem várias modificações que não resolvem os bugs encontrados). Estas informações são importantes para os gestores de projectos e para os programadores que não são apenas programadores mas também líderes de pequenas equipas de software. Apesar de um VCS estar principalmente preocupado com a gestão das versões, as informações que fornece podem ser facilmente usadas por software mais específico da área de gestão de projectos.
- Suporte a projectos de Engenharia de Software
- Tipicamente, bons projectos de software são desenvolvidos com um processo de engenharia de software. Por engenharia de software, quero dizer a aplicação de políticas de desenvolvimento com o intuito de assegurar que o produto final do processo vai de encontro aos objectivos, dentro dos prazos previstos e com os melhores padrões possíveis de qualidade do software. Um bom processo de engenharia de software envolve um conjunto de passos, tais como o desenho bem detalhado do projecto na sua globalidade, a revisão dos componentes do software por parte dos analistas e engenheiros, a anotação de todos os bugs, e testes de qualidade ao software. Nenhum destes passos é explicitamente suportado por qualquer VCS actualmente, mas as características de muitos VCS (como por exemplo, os hook scripts e logs do SVN) são excelentes ajudas ao processo de engenharia de software. Vamos ver mais adiante o que o SVN nos fornece neste campo.
- Ramificação do desenvolvimento
- À medida que os projectos vão aumentando, há necessidade de ramificar o projecto. Isto é, vai surgir naturalmente a necessidade de um programador (ou conjunto de programadores) desenvolver features que não podem de maneira nenhuma minar o trabalho que já existe guardado num repositório de código central. Por exemplo, basta pensar num novo módulo que vai demorar tempo a ser desenvolvido e que vai ter repercussões nos restantes módulos. Neste caso, o ideal é o programador trabalhar num ramo privado, em que este ramo não é mais do que uma cópia de todo o código que já existia e no qual vai poder alterar à vontade, sem o problema de estar a interferir com o código de outros programadores. No final, quando todas as alterações estiverem feitas, o programador funde todo o seu código com o que existe no repositório central (podendo ter que resolver conflitos), e o ramo pode deixar de existir. Outro caso em que os ramos são importantes é no suporte a versões antigas do software. Cada uma das versões antigas poderá ser um ramo do código a dada altura (por exemplo, na altura em que sai uma nova versão), e a equipa de programadores pode testar a resolução dos bugs nesses ramos de código antigo e posteriormente entregar ao cliente uma versão corrigida desse software para aquela versão anterior. Nem todos os VCS possuem esta funcionalidade nem tão pouco fornecem uma alternativa. No entanto, o VCS analisado neste artigo fornece esta a outras funcionalidades importantes para o controlo do software.
- Anotação dos logs
- Para além de saber quem alterou o quê, é também importante saber o porquê. A cada alteração deverá ficar sempre associada uma mensagem que traduza a alteração que se fez e que pode posteriormente ser usada para construir um CHANGELOG ou ainda ser injectada num sistema de tracking, tal como o Trac de que falaremos mais abaixo.
- Distribuição do trabalho
- Actualmente, com a era da globalização e do alcance fácil de uma ligação à Internet, o trabalho à distância é uma realidade presente em cada vez mais empresas, seja o programador que está a aceder ao código do outro lado da cidade ou seja uma empresa sub-contratada do outro lado do planeta; um VCS deverá conseguir equilibrar esta distribuição de trabalho ao gerir todas estas alterações ao código pelos diferentes programadores e também unificar este mesmo código automaticamente. Combinando estas características com uma comunicação (que é fundamental) através de e-mail ou um cliente de IM (como o GTalk, MSN Messenger, Skype ou ICQ), é praticamente tão fácil de trabalhar remotamente como localmente ao lado dos restantes elementos da equipa.
- Desenvolvimento rápido
- As mais recentes metodologias de desenvolvimento de software apontam para uma forma de programar mais rápida, e flexível usando metodologias de Extreme Programming (XP) e de Desenvolvimento Ágil de software. Estas metodologias de desenvolver software, esperam por iterações mais rápidas e sucessivas relativamente a metodologias mais “planeadas”. Esta forma de programar é facilitada por um VCS que consiga manter e indicar todas as alterações por que passou o software nas sucessivas iterações. Para além disso, um repositório central de software pode ajudar na automatização dos builds frequentes que são precisos por um processo de desenvolvimento ágil.
O que é o Subversion?
O Subversion é um VCS open source que tem tido enorme sucesso mundial e sido escolhido não só para a gestão de pequenos projectos open source, como também para projectos comerciais de grandes empresas de software. É um VCS livre, a custo zero e que se pode alterar a gosto (licença), e tem-se revelado como a melhor alternativa actual a VCS comerciais, como é o caso do Rational ClearCase da IBM, o Microsoft SourceSafe (já de si bastante decrépito; uma melhor alternativa actual é o Microsoft Team Foundation Server) ou ainda o Borland StarTeam.
É um sistema de controlo de versões que faz a gestão de ficheiros e directórios ao longo do tempo. Surgiu em 2000 pelas mãos da CollabNet com o objectivo principal de substituir o CVS (Concurrent Versions System), que até então era bastante usado, mas que tinha limitações claras na usabilidade.
A ideia principal do SVN é a de ter uma árvore de ficheiros colocados num repositório central. O repositório é como um servidor de ficheiros, com a excepção de que se lembra de todas as mudanças feitas nos ficheiros e directórios. Isto permite que versões antigas de software sejam recuperadas, ou apenas que se possa examinar o histórico das alterações feitas nos dados.
O Subversion pode também aceder a repositórios remotos, o que permite que possa ser utilizado por pessoas em diferentes máquinas, permitindo assim que haja uma maior colaboração no desenvolvimento de software. Este desenvolvimento pode, portanto, ser mais rápido, e uma vez que há versões no código desenvolvido, não há receio de que se perca qualidade no software uma vez que se houver uma mudança incorrecta no software, basta apenas retroceder nessa alteração. Simples e rápido.
O Subversion fornece:
- Versionamento de directórios
- O CVS mostra apenas o histórico de ficheiros individuais, mas o Subversion implementa um sistema “virtual” de versões que pode tomar nota das alterações a árvores inteiras de directórios ao longo do tempo. Desta maneira, ficheiros e directorias têm versões.
- Histórico de versões
- Uma vez que o CVS é limitado nas versões dos ficheiros, operações como copiar ou renomear ficheiros não são suportadas. O CVS também não consegue substituir um ficheiro com uma determinada versão por outro ficheiro com o mesmo nome, sem que antes esse novo ficheiro tenha herdado todo o histórico do ficheiro antigo, e pode acontecer que este novo ficheiro não tenha nenhuma relação com o antigo do mesmo nome. Com o Subversion pode-se adicionar, apagar, copiar, e renomear tanto ficheiros como directorias. E cada novo ficheiro adicionado começa com um histórico limpo apenas para aquele ficheiro.
- Commit’s atómicos
- Um conjunto de modificações (designado de commit) vai para o repositório de uma só vez como um conjunto global, ou não vai de todo (precisamente como um commit em SQL, isto é, se o commit falhar durante a operação, nada é passado para o servidor). Isto permite que os programadores possam construir e aplicar as modificações ao software como conjuntos lógicos de modificações de software, prevenindo que possam ocorrer problemas quando apenas uma parte do conjunto de alterações é enviado com sucesso para o repositório.
- Versionamento de meta-dados
- Cada ficheiro e directoria tem um conjunto de propriedades – chaves e os valores das chaves – associadas. Pode-se criar e guardar qualquer par arbitrário chave/valor, que se deseje. As propriedades têm também versões ao longo do tempo, como para os conteúdos dos ficheiros; As propriedades fornecem um maior controlo e customização do código-fonte no repositório.
- Escolha de redes de acesso
- O Subversion tem uma noção abstracta de acesso a um repositório, tornando mais fácil a criação de novos mecanismos de rede. O Subversion pode ligar-se ao servidor de HTTP da Apache como um módulo de extensão. Isto dá ao Subversion uma grande vantagem na estabilidade e interoperabilidade, e acesso instantâneo às funcionalidades existentes fornecidas por este servidor HTTP – autenticação, autorização, etc. Uma versão mais leve, sem se ligar ao servidor HTTP do Apache, do servidor de Subversion está também disponível (designada por svnserve). Este servidor comunica através de um protocolo que pode ser facilmente usado num túnel SSH.
- Tratamento consistente de dados
- O Subversion percebe as diferenças nos ficheiros através de um algoritmo que diferencia os binários de texto, e que funciona tão bem para ficheiros de texto como para ficheiros binários. Ambos os tipos de ficheiros são comprimidos no repositório, e as diferenças são transmitidas em ambas as direcções através da rede de computadores.
- Ramificação (branching) e Etiquetagem (tagging) eficientes
- O custo de ramificar e etiquetar não são proporcionais ao tamanho do projecto. O Subversion cria ramos e etiquetas ao copiar o projecto usando um mecanismo semelhante a um link em Linux. Por isso, estas operações levam um período de tempo bastante curto e constante. O que é excelente.
- Usabilidade
- O Subversion é implementado numa colecção de bibliotecas C partilhadas com APIs bem definidas. Isto torna o Subversion extremamente fácil de manter e modificar por outras aplicações e linguagens de programação. Existe também actualmente uma biblioteca Java, SVNKit, que implementa o Subversion e que pode ser usada por qualquer aplicação Java.
Arquitectura do SVN
Na figura seguinte mostra-se a arquitectura do Subversion numa visão de alto-nível. Como se pode ver, o Subversion segue uma filosofia de implementação do tipo cliente-servidor. Numa extremidade está o repositório do Subversion que tem o projecto com as diferentes versões. Na outra extremidade está o cliente de Subversion, que gere as porções locais do projecto em determinada versão (chamadas cópias de trabalho – working copies). Entre estas extremidades há vários caminhos possíveis através das várias camadas de acesso ao repositório (RA – Repository Access). Alguns destes caminhos (ou percursos), atravessam redes de computadores e terminam em servidores que acedem ao repositório.
Outros caminhos não passam por redes de computadores e levam a um acesso directo ao repositório.
Existem dois tipos de filesystem para os repositórios SVN: FSFS (o mais recente e recomendado) e o Berkeley DB da Oracle. Com as versões mais recentes do SVN (desde a versão 1.4.6), o filesystem criado por omissão é FSFS.