Neste artigo iremos ver quais os conceitos básicos de utilização do GIT. Trata-se de um sistema de controle de versões (VCS – Version Control System do inglês). Ele ajuda os programadores a trabalharem em equipa e a manterem um histórico do seu trabalho.
Algumas funcionalidades dos VCS, são:
- Permitir que vários programadores trabalhem ao mesmo tempo num projecto
- Impedir que um programador elimine o trabalho de outro elemento da equipa
- Manter o histórico de cada versão
Alguns tipos de VCS, são:
- Sistema de controle de versões centralizado (CVCS)
- Sistema de controle de versões distribuído (DCVS)
Neste artigo, iremos concentrar-nos nos sistemas de controle de versões distribuídos, dos quais o GIT é um elemento destacado.
Sistemas de Controle de Versões Distribuídos (DCVS)
Os sistemas de controle de versões centralizados utilizam um servidor central que guarda todos os ficheiros e que permite o trabalho em equipa. No entanto, esta arquitectura tem um ponto fraco, que passa por uma eventual falha do servidor. Ainda que esta possa ser parcialmente coberta com base em backups, ela impede o trabalho dos programadores, enquanto o servidor estiver inoperacional.
Por isso, a grande vantagem dos sistemas distribuídos, é que não fazem somente o download (checkout) do ficheiro ou pasta de trabalho, mas sim de todo o repositório. Se, por acaso, o servidor ficar inoperacional, pode-se, no limite, copiar o repositório inteiro de qualquer um dos programadores e assim repor o repositório, no seu todo.
Assim, a utilização do GIT não se baseia unicamente num servidor central e essa é a principal razão porque se pode trabalhar mesmo estando offline, quer fazendo “commits” (actualizações), criando “branches” (ramos) ou verificando logs. Deste modo, só é necessário estar online, quando se pretende fazer as actualizações no repositório central (Github, Bitbucket, Gitlab, etc).
Vantagens do GIT
Gratuito e de código aberto
O GIT é distribuído com base na licença de código aberto GPL e está disponível gratuitamente na Internet. Deste modo, utiliza-se o GIT para gerir projectos sem qualquer custo. Além disso, como é código aberto, o mesmo está totalmente disponível e pode ser alterado de acordo com as necessidades.
Rápido e pequeno
Como a maior parte das operações são feitas localmente, do lado do cliente, isto torna o sistema extremamente rápido. O GIT não depende de um servidor central, pelo que não necessita de interagir com o mesmo por cada operação a executar. A maior parte do código está escrito na linguagem C, o que permite ganhos de velocidade em comparação com outras linguagens de alto nível. Por isso, embora o GIT faça uma cópia do repositório inteiro, essa cópia tem um tamanho reduzido, devido à forma extremamente eficiente como a informação é guardada do lado do cliente.
Cópia implícita (Backup)
Deste modo, as possibilidades de perda de dados são muito difíceis, já que existem tantas cópias do repositório, quantos os programadores. Como cada utilizador tem uma cópia completa do repositório, é possível repor uma segurança (backup), no caso de uma falha num disco (avaria ou corrupção de dados).
Segurança
O GIT usa uma função criptográfica de uso comum, que se chama SHA1 para identificar os seus objectos na base de dados. Assim, cada ficheiro e cada “commit” (actualização) são verificados através de um “checksum” (soma de controlo). Isto impede que sejam alterados os ficheiros, as datas, as mensagens e outros objectos da base de dados sem que o GIT dê por isso.
Não existe necessidade de hardware potente
No caso de um sistema centralizado (CVCS), o servidor deve ser suficientemente potente para satisfazer os pedidos de toda a equipa. No caso de pequenas equipas, isto pode não ser um problema, mas à medida que a equipa cresce, as limitações de hardware podem impedir um funcionamento normal. Pelo contrário, no caso dos sistemas distribuídos (DVCS), os programadores só interagem com o servidor central, quando necessitam de fazer uma actualização importante. Até lá, todas as interacções são feitas no repositório local, não havendo necessidade de um servidor central robusto.
Criação de “branches”
No caso do sistema centralizado, quando criamos um “branch”, ele simplesmente faz uma cópia de todo o repositório, o que pode demorar bastante tempo. Também a eliminação e a fusão (“merge”) de “branches” é complicada e morosa. Pelo contrário, quando trabalhamos com o GIT, a criação, eliminação e fusão de “branches” é muito rápida, podendo levar tão somente alguns segundos.
Conceitos básicos do GIT
Repositório Local
Cada sistema VCS disponibiliza uma área de trabalho onde é feita uma cópia dos ficheiros a serem trabalhados. Deste modo, os programadores podem fazer as alterações necessárias e depois fazem a actualização para o servidor central. O GIT tem uma filosofia mais avançada, já que em vez de permitir fazer o download dos ficheiros a trabalhar, ele faz o download de todo o repositório. Assim, o programador pode localmente criar ficheiros, eliminar ficheiros, renomear ficheiros, mover ficheiros, actualizar alterações e muito mais.
Área de Trabalho e Área Intermédia
A área de trabalho é o local para onde é feita a cópia do(s) ficheiro(s) a trabalhar. Nos sistemas centralizados, os programadores fazem as alterações necessárias aos ficheiros e actualizam directamente o servidor central. O GIT, por outro lado, tem uma filosofia diferente. Ele não controla todos os ficheiros que foram alterados. Quando é feito um “commit” (actualização), ele somente actualiza os ficheiros que estiverem na área intermédia. Somente esses ficheiros são passíveis de actualização e não todos os que tiverem sido alterados.
Assim, vejamos os passos básicos de funcionamento do GIT:
- O programador modifica um ficheiro na área de trabalho
- O programador adiciona esse ficheiro à área intermédia
- O progamador faz “commit”, que vai actualizar o repositório local, retirando o ficheiro da área intermédia. Quando é feito o “push”, é feita a cópia do repositório local para o repositório central
Blobs
“Blob” são as iniciais de Binary Large Object, que é um tipo de objecto utilizado para guardar todas as versões dos ficheiros. Os “blobs” são referenciados na base de dados do GIT, por um ID (código SHA1), uma vez que, no GIT, não existem nomes de ficheiros.
Trees (Árvores)
As “trees” são objectos que representam directórios, que contêm “blobs” ou outros directórios, referenciados por um ID (código SHA1).
Commits (Actualizações)
A operação “commit” guarda as alterações feitas a um ou mais ficheiros. Ela é similar ao comando guardar das aplicações, mas em vez de utilizar um nome, ela atribui um ID (código SHA1) que identifica o que foi alterado e também quem fez essa alteração. Podemos imaginar os “commits”, como os elementos de uma lista ligada que têm um apontador para o “commit” anterior, permitindo assim deslocar-nos na lista e consequentemente obter o histórico das alterações. Se o “commit” tem origem em dois “branches” diferentes, então ele foi consequência de um “merge” (fusão dos “branches”).
Branches (Ramos)
Os “branches” são criados quando se pretende iniciar uma nova linha de desenvolvimento, como, por exemplo, desenvolver uma nova funcionalidade do software. Por defeito, o GIT tem o “branch” principal ou master. Assim, quando o desenvolvimento da funcionalidade tiver terminado os “branches” são “merged” (fundidos) e o “branch” auxiliar poderá ser eliminado. Cada “branch” tem um apontador específico, o HEAD, que aponta para o último “commit” no “branch”. Concluindo, sempre que é feito um “commit” no “branch”, o apontador HEAD é actualizado.
Tags (Etiquetas)
As “tags” associam um nome com significado a uma determinada versão no repositório. Elas são similares aos “branches”, com uma diferença fundamental. Não podem mais ser alteradas, ou seja são como um “branch” que ninguém mais vai alterar. Mesmo que seja feito um novo “commit”, ele não terá efeito. Assim, as “tags” estão normalmente associadas a versões específicas do software em desenvolvimento (Ex.: Ver 1.0)
Clone (Cópia)
A operação “clone” cria uma nova instância do repositório, copiando inteiramente o repositório remoto para um novo repositório local. O programador pode fazer as alterações que entender a este repositório, mesmo não estando online. Assim, só vai necessitar de interagir com o repositório central quando for necessário fazer uma actualização geral.
Pull (Sincronizar Remotamente)
A operação “pull” copia as alterações feitas no repositório remoto para o repositório local, actualizando-o. Assim, esta operação sincroniza os dois repositórios.
Push (Actualizar Remotamente)
A operação “push” faz a actualização do repositório remoto a partir do repositório local.