terça-feira, 24 de dezembro de 2013

Tortoise SVN - Parte 2

Conceitos básicos do Controle de Versão

Este capítulo é uma versão levemente modificada do mesmo capítulo do livro do Subversion. Há uma versão disponível do livro do Subversion aqui: http://svnbook.red-bean.com/.
Este capítulo é uma pequena, simplória introdução ao Subversion. Se você é novato em controle de versões, este capítulo com certeza é para você. Nós começamos com uma abordagem geral dos conceitos do controle de versão, seguindo nossas idéias sobre o Subversion, e mostrando alguns exemplos simples de uso do Subversion.
Embora os exemplos desse capítulo mostre pessoas compartilhando uma porção de código de fonte, tenha em mente que Subversion pode controlar qualquer conjunto de arquivos - não está limitado a ajudar programadores.

O Repositório

Subversion é um sistema centralizador de compartilhamento de informação. A essência é um repositório, que é um arquivo central de dados. O repositório grava informação no formato de diretório de arquivo de sistemas - uma típica hierarquia de arquivos e diretórios. Quantos clientes quiser se conectam no repositório, e então leem e escrevem nesses arquivos. Escrevendo dados, um usuário torna a informação disponível para outros; lendo os dados, um usuário recebe a informação de outros.

Então porque isto é interessante? Até agora, isso se parece com a definição de um típico servidor de arquivos. E de verdade, o repositório é um tipo de servidor de arquivos, mas não é sua função normal. O que o repositório do Subversion faz de especial é que ele guarda cada modificação feita: cada modificação para cada arquivo e mesmo as modificações na prória estrutura de diretórios, como adição, exclusão e reorganização de arquivos e diretórios.
When um cliente lê uma informação do repositório, normalmente vê apenas a última versão da estrutura de arquivos. Mas o usuário também pode ver estruturas mais antigas. Por exemplo, um usuário pode fazer perguntas como, o que este diretório continha na últma quarta-feira?, ou quem foi a última pessoa a modificar este arquivo, e que modificações foram feitas? Estas são os tipos de perguntas principais em qualquer sistema de controle de versão: sistemas que são projetados para gravar e armazenar modificações dos dados ao longo do tempo.

Modelo de controles

Todo sistema de controle de versão precisa resolver algumas problemas fundamentais: como o sistema vai permitir aos usuários compartilhar a informação, mas prevenindo que um não atrapalhe o outro? É muito fácil para os usuários acidentalmente sobreescrever as modificações de outros no repositório.

O problema do compartilhamento de arquivo

Considere o cenário: suponha que nós temos dois usuários, Harry e Sally. Cada um deles decide editar o mesmo arquivo no mesmo repositório ao mesmo tempo. Se Harry salvar suas alterações no repositório primeiro, é possível que (alguns tempo depois) Sally poderia acidentalmente sobreescrever as alterações com sua versão do arquivo. Enquanto a versão do arquivo do Harry se perderia para sempre (porque o sistema guarda cada modificação), qualquer alteração que Harry fez não estariam presentes na nova versão do arquivo de Sally, porque ela nunca viu as modificações do Harry. O trabalho do Harry foi perdido - ou no mínimo estaria na versão mais recente - e provavelmente por acidente. Esta é definitivamente um situação que nós queremos evitar!


A solução Alocar-Modificar-Desalocar

Muitos sistemas de controle de versão usam o modelo alocar-modificar-desalocar para resolver este problema, o qual é uma solução simples. Em cada sistema, o repositório permite somente uma pessoa por vez modificar o arquivo. Primeiro Harry deve alocar o arquivo antes que possa fazer as alterações. Alocar um arquivo é como um controle de biblioteca/ se Harry alocou o arquivo, então Sally não pode fazer qualquer alteração nele. Se ela tentar alocar o arquivo, o repositório vai negar essa solicitação. Tudo que ela pode fazer é ler o arquivo, e esperar até que Harry acabe as suas alterações e libere o arquivo. Depois que Harry desalocar o arquivo, sua vez acaba, e então é a vez de Sally alocar o arquivo e fazer suas alterações.


O problema com o modelo alocar-modificar-desalocar é que é muito restritivo, e muitas vezes é um empecilho para os usuários:
  • Alocação pode causar problemas administrativos. Algumas vezes Harry vai alocar o arquivo e então esquecer dele. Entretanto, porque Sally continua esperando para para editar o arquivo, suas mãos estão atadas. E então Harry sai de férias. Agora Sally precisa pedir a um administrador para liberar o arquivo alocado por Harry. A situação acaba causando atrasos e uma porção de tempo perdido desnecessário.
  • Alocação pode causa uma serialização desnecessária. O que fazer se Harry estava editando o início de um arquivo texto, e Sally quer editar apenas o fim do arquivo? Estas alterações não se sobrepoem. Eles poderiam facilmente editar o arquivo ao mesmo tempo, e nenhum grande problema ocorreria, assumindo que as modificações seriam corretamente unificadas. Não é necessário travar o arquivo neste caso.
  • Alocar pode criar uma falta noção de segurança. Suponhamos que Harry aloque e altere o arquivo A, enquanto ao mesmo tempo Sally aloca e edita o arquivo B. Supondo que A e B dependem um do outro, e que as modificações feitas em cada um são semanticamente incompatíveis. Imprevisivelmente A e B não funcionam mais juntos. O sistema de alocação não tem como prever este problema - ainda que esse sistema passe uma falta sensação de segurança. É fácil para Harry e Sally imaginar que alocando arquivos, cada um está seguro, numa tarefa isola, e deste modo evitando discussões precosss sobre as modificações.

A solução Copiar-Modificar-Unificar

Subversion, CVS e outros sistemas de controle de versão usam o modelo copiar-modificar-unificar como alternativa para a alocação. Neste modelo, cada usuário lê o repositório e cria uma cópia de trabalho pessoal dos arquivos do projeto. Eles então trabalham de forma paralela, modificando suas próprias cópias. No final, as cópias locais são unificadas com uma nova versão, uma versão final. O sistema de controle de versão oferece ajuda com a unificação, mas no final uma intervenção humana é que decide como a unificação será feita.
Aqui vai um exemplo. Digamos que Harry e Sally criam cada um uma cópia de trabalho de um mesmo projeto, copiado do repositório. Eles trabalham ao mesmo tempo, e fazem modificações em um mesmo arquivo A em suas cópias. Sally salva suas alterações no repositório primeiro. Quando Harry tenta salvar suas modificações após Sally, o repositório informa a ele que o arquivo A está desatualizado. Em outras palavras, o arquivo A do repositório tem alguma alteração desde a última vez que ele foi copiado. Então Harry é questionado sobre a unificação das modificações no repositório serem inseridas em sua cópia do arquivo A. Oportunamente as modicações de Sally não foram sobreescritas pelas dele; uma vez que ele unificou ambas as alterações, ele salva a sua cópia no repositório.




Mas o que acontece se as alterações de Sally se sobrepoem sobre as alterações de Harry? O que então deve ser feito? Esta situação é chamada de conflito, e em geral isto não é um problema. Quando Harry for questionado sobre a unificação das últimas alterações no repositório em sua cópia de trabalho, sua cópia do arquivo A de qualquer maneira é marcada como conflitante: ele verá todas as modificações em conflito, e manualmente resolverá. Entenda que o software não pode resolver automaticamente os conflitos; somente humanos são capazes de entender quais são as escolhas lógicas a serem tomadas. Uma vez que Harry manualmente resolveu o que estava se sobreponde (talvez precise discutir o conflito com Sally!), ele pode seguramente salvar o arquivo unificado de volta no repositório.
O modelo copiar-modificar-unificar pode parecer bagunçado, mas na prática, isto funciona grandemente. Usuários podem trabalhar paralelamente, sem esperar por outros. Quando eles trabalham num mesmo arquivo, a maioria das alterações não se sobrepoem; conflitos são pouco frequentes. E na maioria das vezes o tempo que leva para resolver os conflitos é muito menor que o tempo perdido em um sistema de alocação.
No final das contas, tudo isso acaba em um ponto crítico: comunicação entre os usuários. Quando os usuários não se comunicam direito, aumenta-se os conflitos sintáticos e semênticos. Nenhum sistema pode forçar uma perfeita comunicação, nenhum sistema pode detectar conflitos de semântica. Então não há porque se entusiasmar com falsas promessas de que um sistema de alocação evitará conflitos; na prática, alocações parecem restringir a produtividade mais que qualquer outra cosa.
Existe uma situação em comum onde o modelo alocar-modificar-desalocar se torna melhor, e é com arquivos que não são unificáveis. Por exemplo, se seu repositório contém alguns arquivos de imagens, e duas pessoas mudam a imagem ao mesmo tempo, não há nenhuma maneira de combinar as alterações. Ou Harry ou Sally perderá sua alteração.

O que o Subversion faz?

Subversion usa a solução copiar-modificar-unificar como padrão, e na maioria dos casos é o suficiente. Contudo, a partir da versão 1.2, Subversion também permite alocar um arquivo, e se existem arquivos que não são unificáveis, você pode adotar uma política de alocação, que o Subversion está preparado para o que você precisa.

Subversion em Ação

Cópias de Trabalho

Você está pronto para ler sobre cópias de trabalho; agora vamos demonstrar como o aplicativo do Subversion cria e usa as cópias.
Uma cópia de trabalho do Subversion é uma estrutura de diretórios como outra qualquer em seu sistema local, contendo um conjunto de arquivos. Vocë pode editar esses arquivos como desejar, e se os arquivos são códigos fonte, você pode compilar seu programa a partir desta cópia como sempre fez. Sua cópia de trabalho é sua própria área pessoal. Subversion nunca vai incorporar alterações de outras pessoas, nem disponibilizar suas alterações para outros, até que você mesmo o faça.
Depois que você fez algumas modificações nos seus arquivos em sua cópia de trabalho e verificou que estão funcionando corretamente, Subversion provê a você comandos para publicar suas alterações para outras pessoas que trabalham com você em seu projeto (através da escrita no repositório). Se outras pessoas publicarem suas próprias modificações, Subversion provê comandos para unificar estas modificações na sua cópia de trabalho (através da leitura do repositório).
A working copy also contains some extra files, created and maintained by Subversion, to help it carry out these commands. In particular, your working copy contains a subdirectory named .svn, also known as the working copy administrative directory. The files in this administrative directory help Subversion recognize which files contain unpublished changes, and which files are out-of-date with respect to others' work. Prior to 1.7 Subversion maintained .svn administrative subdirectories in every versioned directory of your working copy. Subversion 1.7 takes a completely different approach and each working copy now has only one administrative subdirectory which is an immediate child of the root of that working copy.
Um repositório típico do Subversion geralmente guarda os arquivos (ou código fonte) para diversos projetos; normalmente, cada projeto é um subdiretório na estrutura de arquivos do repositório. Desta forma, uma cópia de trabalho de um usuário normalmente corresponde a uma específica subestrutura do repositório.
Por exemplo, suponha que você tenha um repositório que contem dois projetos de software.


Em outras palavras, o diretório principal do repositório tem dois subdiretórios: paint e calc.
Para obter uma cópia de trabalho, você deve obter alguma sub-estrutura do repositório. (O termo obter pode parecer como algo que irá travar ou reservar os recursos, mas não é isso; ele simplesmente cria uma cópia local do projeto para você.)
Suponha que você fez mudanças para button.c. Já que o diretório .svn sabe a data de modificação do arquivo e seu conteúdo original, Subversion pode avisar que você fez modificações no arquivo. Contudo, Subversion não publica nenhuma alteração até que você realmente o faça. O ato de publicar suas alterações é mais conhecido como submeter (ou enviar) modificações para o repositório.
Para publicar suas modificações para outras pessoas, você pode usar o commando submeter do Subversion.
Agora suas modificações para button.c foram enviadas para o repositório; se outro usuário obter uma cópia de /calc, eles verão suas modificações na última versão do arquivo.
Suponha que vocë tenha uma colaboradora, Sally, que obteve uma cópia de /calc no mesmo momento que você. Quando você submeter suas modificações de button.c, a cópia de trabalho de Sally não será modificada; Subversion somente modificará as cópias dos usuários que solicitarem a atualização.
Para atualizar seu projeto, Sally deve pedir ao Subversion para atualizar sua cópia de trabalho, através do comando atualizar do Subversion. Isto incorporará sua modificação na cópia de trabalho dela, assim como qualquer outra modificação que tenha sido submetido desde que ela obteve sua cópia de trabalho.
Note que Sally não precisou especificar quais arquivos atualizar; Subversion usa a informação do diretório .svn, e além disso informações do repositório, para decidir quais arquivos precisam ser atualizados.

URLs do Repositório

Repositórios do Subversion podem ser acessados através de vários métodos direfentes - como disco local, ou através de vários protocolos de rede. Um local de repositório, contudo, é sempre uma URL. O esquema de URL indica o método de acesso:
Tabela 2.1. URLs de Acesso ao Repositório




Para a maioria, URLs do Subversion usam a sintaxe padrão, permitido nomes de servidores e números de porta em uma parte específica da URL. O método de acesso file:// é normalmente usado para acesso local, apesar de que isto pode ser usado com caminhos UNC em uma máquina da rede. A URL portanto usa o formato file://hostname/path/to/repos. Para a máquina local, a parte do hostname da URL deve ser suprimida ou deve ser localhost. Por esta razão, caminhos locais normalmente aparecem com três barras, file:///path/to/repos.
Também, usuários do esquema file:// em plataformas Windows vão precisar usar uma sintaxe padrão não oficial para acessar repositórios que estão na mesmo máquina, mas em um dispositivo diferente que o atual dispositivo de trabalho da máquina. Qualquer uma das duas seguintes sintaxes funcionarão onde X é o dispositivo no qual o repositório está:
file:///X:/path/to/repos
...
file:///X|/path/to/repos
...
Note que a URL usa barras normais embora a forma nativa (não URL) de um caminho no Windows seja barra invertida.
Você pode garantir o acesso a um repositório FSFS através de um compartilhamento de rede, mas você não pode acessar um repositório BDB desta forma.

Atenção

Não crie or acesse um repositório Berkeley DB em uma rede compartilhada. Isto não pode existir em um sistema de arquivos remoto. Nem mesmo se você tem dispositivos de rede mapeados em uma unidade de disco. Se você tentar usar Berkeley DB em uma rede compartilhada, os resultados são imprevisíveis - você poderá ver erros misteriosos imediatamente, ou meses antes descobrir que seu repositório está sutilmente corrompido.

Revisões

Um comando svn submeter pode publicar modificações de qualquer quantidade de arquivos e diretórios como uma única transação atômica. Em sua cópia de trabalho, você pode mudar o conteudo de um arquivo, criar, excluir, renomear e copiar arquivos e diretórios, e depois enviar todas as modificações como uma única e completa alteração.
Em um repositório, cada submissão é tratada como uma transação atômica: ou todas as mudanças são enviadas, ou nenhuma delas. Subversion mantém essa atomicidade por causa de falhas de programas, falhas de sistema, falhas de rede, e ações de outros usuários.
Cada vez que o repositório aceita uma submissão, ele cria um novo estado da estrutura de arquivos, chamada de revisão. Cada revisão é associada a um número natural, maior que o número da revisão anterior. A revisão inicial de um repositório recém criado é zero, e não contém nada mais que um diretório principal vazio.
Uma maneira interessante de enxergar o repositório é como uma série de estruturas. Imagine uma matriz de números de revisões, começando em 0, e se estendendo da esquerda para a direita. Cada número de revisão com uma estrutura de arquivos abaixo, e cada divisão já em seguida da maneira como o repositório realizou cada submissão. 


É importante notar que cópias de trabalho nem sempre correspondem a uma única revisão qualquer no repositório; eles podem conter arquivos de diferentes revisões. Por exemplo, suponha que você obteve uma cópia de trabalho de um repositório do qual a revisão mais recente é a 4:
calc/Makefile:4
     integer.c:4
     button.c:4
Neste momento, esta cópia de trabalho corresponde exatamente à revisão 4 no repositório. Entretanto, suponha que você fez modificações em button.c, e submeteu essas alterações. Assumindo que não houve nenhuma outra submissão, o envio vai criar a revisão 5 no repositório, e sua cópia de trabalho vai se parecer com isto:
calc/Makefile:4
     integer.c:4
     button.c:5
Suponha que, neste momento, Sally envia uma alteração do integer.c, criando a revisão 6. Se você usar o svn atualizar para atualizar sua cópia de trabalho, então você terá algo como isto:
calc/Makefile:6
     integer.c:6
     button.c:6
As modificações de Sally para integer.c vão aparecer em sua cópia de trabalho, e sua alteração vai continuar presente em button.c. Neste exemplo, o texto de Makefile é identifico nas revisões 4, 5 e 6, mas Subversion vai marcar sua cópia de trabalho do Makefile com a revisão 6 indicando que ainda é a versão atual. Então, depois que você completou todas as atualizações na sua cópia de trabalho, isto geralmente corresponderá a uma exata revisão do repositório.

Como Cópia de Trabalho Acompanham o Repositório

Para cada arquivo do diretório de trabalho, Subversion grava duas partes essenciais da informação na área administrativa .svn/:
  • qual revisão o arquivo da sua cópia de trabalho esta baseado (isto é chamado de revisão de trabalho do arquivo), e
  • a informação de data/hora de quando foi a última atualização da cópia do repositório.
Com estas informação, através de troca de informações com o repositório, Subversion pode identificar qual dos quatro estados seguintes é o estado de um arquivo:
Não modificado, e atualizado
O arquivo não foi modificado na cópia de trabalho, e nenhuma nova modificação foi submetida no repostório considerando a revisão de trabalho. Um submetero> do arquivo natualizar do arquivo tamb
Localmente alterado, e atualizado
O arquivo possui modificações no diretório de trabalho, e nenhuma modificação para o arquivo foi enviada para o repositório considerando a revisão atual. Existem alterações que não foram submetidas para o repositório, deste modo um submeter do arquivo vai obter sucesso ao publicar suas alterações, e um atualizar do arquivo não fará nada.
Não modificado, e desatualizado
O arquivo não possui alterações no diretório de trabalho, mas há modificações no repositório. O arquivo deverá eventualmente ser atualizado, para sincronizar com a revisão publica. Um submeter do arquivo não fará nada, e um atualizar do arquivo trará as últimas alterações para a cópia local.
Localmente modificado, e desatualizado
O arquivo possui modificações tanto no diretório de trabalho, como no repositório. Um submeter do arquivo vai falhar com o erro desatualizado. O arquivo deverá ser atualizado primeiro; o comando atualizar vai tentar unificar as alterações do repositório com as alterações locais. Se o Subversion não conseguir completar a unificação de forma plausível automaticamente, ele deixará para o usuário resolver o conflito.

Resumo

Nós apresentamos vários conceitos fundamentais do Subversion neste capítulo:
  • Nós introduzimos as noções de um repositório central, a cópia de trabalho do usuário, e uma porção da estrutura de revisões do repositório.
  • Nós mostramos alguns exemplos simples de como dois colaboradores podem usar o Subversion para publicar e receber alterações um do outro, usando o modelo 'copiar-modificar-unificar'.
  • Nós falamos um pouco sobre a forma como o Subversion acompanha e controla as informações em uma cópia de trabalho.

Nenhum comentário:

Postar um comentário