sábado, 17 de março de 2018

Controle de versão???


Controle de versão???

Impressionante o quanto evolui esse negócio de TI. Atividades ligadas a desenvolvimento de software que antes eram traumáticas e que demandavam bastante tempo, agora estão mais suaves e mais ágeis.

Mesmo quando trabalhamos sozinho, levando-se em conta que podemos ter que sustentar várias versões de um mesmo sistema, corremos o risco de sobrescrever algum código fonte.

Imagine quando trabalhamos em equipe e temos que lidar com várias pessoas fazendo sustentação ao mesmo tempo de várias versões desse sistema? Sem dúvida, uma situação no mínimo caótica.

Quem nunca sobrescreveu o código de algum colega por acidente que atire a primeira pedra. O trabalho em equipe também implica em dificuldade em responder questões do tipo quem, quando e quais alterações foram feitas no código fonte do sistema. Como recuperar código de versões anteriores a versão de produção e ainda como manter variações do sistema ao mesmo tempo. Foda, né!? As soluções de controle de versão surgiram para sanar esses problemas.

Como funciona?

As soluções são compostas basicamente de duas partes: Um repositório que armazena todo o histórico de evoluções do código, registrando toda e qualquer alteração feita sobre ele e um local conhecido como Área de Trabalho que contém a cópia do arquivos do projeto que é alterada pelos desenvolvedores. Cada desenvolvedor possui uma área de trabalho.

Para manter o repositório atualizado e a área de trabalho de cada desenvolvedor atualizada de acordo com as versões de código dos demais colegas de trabalho, é necessário realizar uma sincronização entre esse repositório(com código desenvolvido pela equipe) e a trabalho de cada desenvolvedor presente em sua área de trabalho.

Chamamos de COMMIT a operação de atualização do repositório e de UPDATE, a operação de atualização da área de trabalho.

Cada COMMIT gera uma nova revisão(tira uma espécie de foto) no repositório contendo as modificações feitas, a data e o autor dessas modificações.  

No exemplo que dei, existe um único repositório e várias áreas de trabalho o que confere a solução de controle versão, um viés CENTRALIZADO, mas existem também cenários nos quais podemos ter além de uma área de trabalho, um repositório para cada desenvolvedor, dando a solução um esteriótipo DISTRIBUÍDO.

As operações de sincronização entre a área de trabalho e o repositório local continuam as mesmas neste caso. Entretanto, para trabalhar em conjunto com outros desenvolvedores, é necessário haver o sincronismo entre os repositórios locais dos desenvolvedores envolvidos no projeto.

PULL(puxar) é o nome dado a operação de atualização de um repositório local(destino) com todas as alterações feitas em outro repositório(origem).

PUSH(empurrar) é a operação responsável por enviar as alterações do repositório local(origem) para um outro repositório(destino), ou seja, não existe um repositório local mais importante que o outro, embora seja interessante atribuir um desses repositórios com sendo central, de modo a organizar o fluxo de trabalho.

Para cópia de um repositório para a área de trabalho, utilizamos a operação CLONE(no caso de soluções distribuídas) ou CHECKOUT(no caso de soluções centralizadas).

As revisões registradas no repositório precisam ter uma identificação única. No caso de soluções centralizadas, cada revisão recebe um número sequencial, mas como isso é feito em uma solução distribuída? Nestes casos, um hash é utilizado como identificador o que torna improvável a repetição com um hash produzido por outro repositório.

Como dissemos inicialmente as soluções de controle de versão visam possibilitar o trabalho concorrente de vários desenvolvedores sobre os mesmos arquivos, evitando que um sobrescreva o código dos outros. Mas como isso é feito? Em parte, a existência da área de trabalho resolve esse problema, entretanto como é possível mediar os conflitos de alterações código feitas no momento da sincronização entre a área de trabalho e um repositório por exemplo? A solução de controle de versão combina as revisões cocorrentes em uma única resultante através de uma operação a qual chamamos de MERGE(mesclagem).

Explicação através de um exemplo:

Fulano  e Beltrano são desenvolvedores da empresa  X.

Quando chegam a Empresa para trabalhar, eles realizam cada um, uma operação de checkout em suas áreas de trabalho(Neste momento as áreas de trabalho deles encontram-se no mesmo estado).

Os dois desenvolvedores executam modificações no código fonte presente em suas áreas de trabalho.

Beltrano publica as modificações feitas por ela no repositório.

Quando Fulano tenta publicar as modificações feitas por ele no repositório, o controlador de versão recusa a publicação alegando que as alterações feitas por ele foram realizadas em arquivos desatualizados, visto que os arquivos alterados por Fulano já haviam sido atualizados por Beltrano antes.

Neste caso será necessário que Fulano antes de tentar atualizar o repositório, faça uma operação de UPDATE de modo a atualizar a área de trabalho dele com as alterações realizadas por Beltrano. (Nessa operação, o controlador de versão já mescla automaticamente as revisões feitas por Fulano e Beltrano).

Após conferir se a atualização e a mesclagem produziram o resultado desejado, Fulano envia as mudanças para o repositório. Beltrano resolve continuar a trabalhar executando novas alterações e não terá problemas com o controlador de versão, caso a versão do código área de trabalho dele não esteja conflitando com versões de código já enviadas por Fulano para o Repositório.

O exemplo se adequa perfeitamente a um cenário de controlador de versão centralizado. Vejamos como ficaria essa situação em um cenário de controlador de versão distribuído:

Roberto clona o repositório de Aline. Agora ambos partem do mesmo ponto.

Aline e roberto publicam suas alterações nos seus respectivos repositórios, sem interferir no repositório um do outro.

Para sincronizar seu repositório com as revisões publicadas por Aline, Roberto realiza uma operação de PULL cuja origem é o repositório de Aline. Isso não afeta a área de trabalho de Roberto.

A mesclagem das revisões realizadas por Aline e Roberto se dão na área de trabalho de Roberto através de uma operação de MERGE.

Após verificação do resultado,  Roberto envia as mudanças ao seu repositório. Em paralelo Aline publica outras alterações em seu repositório.

Roberto envia as revisões feitas por ele ao repositório de Aline, que as combina com o histórico de revisões já existente.

No próximo post, colocaremos isso em prática utilizando o GIT, uma solução gratuita de controle de versão de código disponível para instalação em diversas plataformas. Até lá

Nenhum comentário: