Git e Controles de Versionamento – O que é e como usar?
Exceto se você for uma pessoas excepcional na compreensão da mente de outras pessoas, e se todos os seus usuários forem perfeitamente compreendidos no primeiro contato e seu software ou sistema seja extremamente simples do tipo somar dois números inteiros e positivos ou jamais precise sofrer uma atualização por qualquer modificação e também seja produzido unica e exclusivamente por você, e mesmo assim com algumas exceções você não precisa de um controle de versão. Por qualquer outro motivo, você vai se beneficiar de alguma maneira por um controlador de versionamento de software. E resolvi abordar este tema neste artigo.
Antes de mais nada, vamos falar sobre o que é um controle de versão, indiferente do ambiente ou contexto, o controle de versão é uma forma de gerenciar as diferenças, em informática, especificamente o controle de versão é uma forma de gerenciar as mudanças de um software ao passar do tempo.
Com base nessa informação, o que é importante, para que isso funcione? Quatro coisas, saber o que mudou, quando mudou, quem mudou e como pode ser desfeito. Os controles de versão devem atender a estes quatro requisitos básicos para serem minimamente utilizáveis. GIT não é o único controlador de versão que existe, nem tampouco o único, porém, é na atualidade um dos mais amplos e mais viáveis para serem aplicados a todo e qualquer conteúdo textual, ou seja, ele não é eficiente para versionamento de conteúdos que envolvem imagens/audios/videos e outros conteúdos binários. Portanto, a aplicabilidade do GIT é para ser um controle de versão de código fonte, indiferente da linguagem utilizada.
Esse tipo de sistema é muito presente em empresas e instituições de tecnologia e desenvolvimento de software. É também muito comum no desenvolvimento de software livre. É útil, em diversos aspectos, tanto para projetos pessoais pequenos e simples como também para grandes projetos comerciais.
Entre os mais comuns encontram-se as soluções livres: CVS, Mercurial, Git e SVN (Subversion) e as comerciais SourceSafe, TFS, PVCS (Serena) e ClearCase. O Git, vem substituindo o SVN, que por sua vez é um sucessor do CVS. Optar por uma solução comercial geralmente está relacionada à garantia, pois as soluções livres não se responsabilizam por erros no software e perdas de informações, porém as soluções livres podem ter melhor desempenho e segurança que as comerciais.
Principais vantagens no uso de Controladores de Versão
- Controle do histórico: facilidade em desfazer e possibilidade de analisar o histórico do desenvolvimento, como também facilidade no resgate de versões mais antigas e estáveis. A maioria das implementações permitem analisar as alterações com detalhes, desde a primeira versão até a última.
- Trabalho em equipe: um sistema de controle de versão permite que diversas pessoas trabalhem sobre o mesmo conjunto de documentos ao mesmo tempo e minimiza o desgaste provocado por problemas com conflitos de edições. É possível que a implementação também tenha um controle sofisticado de acesso para cada usuário ou grupo de usuários.
- Marcação e resgate de versões estáveis: a maioria dos sistemas permite marcar onde é que o documento estava com uma versão estável, podendo ser facilmente resgatado no futuro.
- Ramificação de projeto: a maioria das implementações possibilita a divisão do projeto em várias linhas de desenvolvimento, que podem ser trabalhadas paralelamente, sem que uma interfira na outra.
- Segurança: Cada software de controle de versão usa mecanismos para evitar qualquer tipo de invasão de agentes infecciosos nos arquivos. Além do mais, somente usuários com permissão poderão mexer no código.
- Rastreabilidade: Com a necessidade de sabermos o local, o estado e a qualidade de um arquivo; o controle de versão traz todos esses requisitos de forma que o usuário possa se embasar do arquivo que deseja utilizar.
- Organização: Alguns softwares disponibilizam uma interface visual onde podem ser vistos todos os arquivos controlados, desde a origem até o projeto por completo.
- Confiança: O uso de repositórios remotos (na nuvem) ajuda a não perder arquivos por eventos inesperados. Além disso, e possível fazer novos projetos sem danificar o desenvolvimento do atual.
Cada um deles possui vantagens e desvantagens, e é mais uma questão de gosto pessoal, já que praticamente todos atendem um ou mais requisitos e podem ser mais fáceis em algumas situações.
O CVS, ou Concurrent Version System (Sistema de Versões Concorrentes) é um sistema de controle de versão que permite que se trabalhe com diversas versões de arquivos organizados em um diretório e localizados local ou remotamente, mantendo-se suas versões antigas e os logs de quem e quando manipulou os arquivos. É especialmente útil para se controlar versões de um software durante seu desenvolvimento, ou para composição colaborativa de um documento ou documentação. Porém, por manter um histórico individual dos arquivos não tem como recurso manter um repositório de todas as alterações de um grupo de arquivos para um mesmo propósito.
Apache Subversion (também conhecido por SVN) é um sistema de controle de versão desenhado especificamente para ser um substituto moderno do CVS, que se considera ter algumas limitações. Surgiu em 2004 e só não ganhou mais mercado por ter ficado um pequeno passo atras do Git nas suas versões e gosto da comunidade de software livre.
MediaWiki é um software livre e de código aberto do tipo Wiki escrito na linguagem de programação PHP e utiliza sistemas de gestão com base de dados MySQL. Desenvolvida na fundação Wikimedia, que a utiliza para seus principais projetos, incluindo a Wikipédia, Wikcionário e o Wikimedia Commons, entre outros. Seu maior trunfo é manter o versionamento de páginas específicas e edições, muito utilizado para documentação, é ideal para ser usado por exemplo com versionamento de documentos, mais devido as limitações de manter arquivos não tem seu propósito voltado a manter código-fonte de software.
Revision Control System (RCS), ou Sistema de Controle de Revisão (SCR) em português, é uma implementação de software de controle de revisão, que automatiza o armazenamento, recuperação, registro, identificação e fusão de revisões. O RCS é útil para texto que é revisado com freqüência, por exemplo, programas, documentação, gráficos processuais, documentos e cartas. Ele também é capaz de lidar com arquivos binários, embora com uma eficiência reduzida. Revisões são armazenados, com o auxílio do utilitário diff.
Git é um sistema de controle de versões distribuído, usado principalmente no desenvolvimento de software, mas pode ser usado para registrar o histórico de edições de qualquer tipo de arquivo como livros digitais, foi inicialmente projetado e desenvolvido por Linus Torvalds para o desenvolvimento do kernel Linux, mas foi adotado por muitos outros projetos. Cada diretório de trabalho do Git é um repositório com um histórico completo e habilidade total de acompanhamento das revisões, não dependente de acesso a uma rede ou a um servidor central. O Git também facilita a reprodutibilidade científica em uma ampla gama de disciplinas, da ecologia à bioinformática, arqueologia à zoologia. Hoje é sem dúvida o mais utilizado em controle de código e software e sobre ele que vamos aprofundar neste artigo.
Como funciona o GIT?
O GIT foi basicamente criado por Linus Torvalds, e que o conhece sabe que ele tem uma maneira no mínimo peculiar de fazer as coisas a moda dele, como nenhum dos controladores de versão da época o agradava, ele resolveu partir de diversas ferramentas distintas que ele usava e que já faziam parte do contexto do linux e desenvolver uma ferramenta que suprisse as necessidades dele e as automatizasse de maneira mais simplista e que pudesse ser facilmente utilizada para manter o código do kernel linux. Na época, o projeto do kernel era mantido em um controlador de versão comercial e livre chamado BitKeeper, que deixou de ser livre.
Linus então queria algo que permitisse trabalho distribuído, controle de tudo o que foi alterado e por quem, além de uma garantia de que o que foi inserido era o que foi devolvido, sem risco de corrupção de arquivos por qualquer tipo de falha. E que se assemelhasse ao processo de PATCH e TARBAL que ele já estava acostumado. E como não encontrou nada, resolveu fazer algo, e o resultado foi o GIT.
Um dos problemas dele e de quase todos os desenvolvedores, é que você escreve um código, e acaba salvando-o em um arquivo e depois de algum tempo, você precisa alterar este arquivo e uma série de outros para digamos fazer uma nova funcionalidade ou refatorar um código, e você acaba copiando pastas ou arquivos, renomeando-os e ficando com um monte de coisas duplicadas que você não sabe ao certo depois de alguns anos se estão em uso ou não. Além, de duplicidade, imagine que você alterou uma função e quebrou a compatibilidade com uma versão anterior e só depois de ter colocado o código em produção, você acaba percebendo que precisa voltar e desfazer essa alteração em todos os arquivos que foram alterados, ou seja em pouco tempo você vai acabar com uma dezena de versões diferentes de arquivos e terá uma grande chance de perder alguma coisa ou excluir um arquivo errado e sacrificar horas de desenvolvimento.
O segundo problema, você agora precisa trabalhar no desenvolvimento de uma funcionalidade e vai precisar alterar algumas dezenas de arquivos e diretórios do seu projeto, e seu colega também vai desenvolver e editar arquivos que talvez afetem o que você fez, e precisa controlar essas alterações. Se você usa um compartilhamento padrão de arquivos, corre o risco de ter suas alterações perdidas por que alguém sobrescreveu uma alteração, e se você usava um controle que fazia o bloqueio do arquivo para edição, teria que esperar um programador terminar para começar seu trabalho. Agora imagina isso em uma empresa com 30 ou 40 programadores.
Como funciona tecnicamente o Git, ele faz a comparação dos dois arquivos, criando um relatório das diferenças deles, exatamente como o comando DIFF gerando um resultado similar ao que você já deve ter acompanhado em serviços como o github com as diferenças dos arquivos, os chamados patchs (remendos). Veja abaixo mais ou menos como funciona.
Um repositório git, mantém só essas diferenças salvas, a partir de um arquivo original, dessa maneira, acaba sendo muito mais rápido e econômico o armazenamento dos dados de arquivos em disco. Adicione a isso a capacidade de criar tudo em um arquivo único como um TAR e a compressão GZIP e você tem um arquivo de transferência das alterações muito eficiente.
Por outro lado, esse algoritmo é complexo para analisar diversos arquivos, então, para melhora-lo, linuz adicionou a funcionalidade de comparar pelo diff somente o que foi alterado na árvore de diretórios, para isso ele usa um outro algoritmo muito mais rápido que é o de gerar o hash dos diretórios e arquivos e compara-los como os algoritmos de hash armazenados da versão anterior. Agora você um comparador de dezenas de centenas e de milhares de arquivos rápido e eficiente.
Para melhorar o fluxo de trabalho, ele adicionou a capacidade de branch (galho) que é uma cópia do projeto no ponto atual, para que o desenvolvedor possa realizar suas alterações e gerar novos patchs que serão incorporados ao projeto principal (merge) ou darão origem a ramificações separadas e independentes (fork), é um fluxo similar ao visto aqui, o que nos leva ao próximo ponto:
Termos e expressões comuns do GIT
repositório – é a coleção de documentos, commits, branches e históricos necessários e funcionais para se recriar o projeto. A biblioteca de dados do projeto ou da cópia original;
local – a cópia que está no seu computador, onde você pode fazer as alterações e modificações, criar forks ou mesmo inicializa-la como um projeto inteiro;
remoto – que está no servidor, este pode ser o repositório principal em outro diretório do seu computador, pode ser o repositório da sua empresa ou o repositório que está em um servidor como o github ou gitbucket ou gitlab ou qualquer outro;
origin – esse é o repositório remoto original, de onde a primeira cópia do seu projeto foi clonada, pode ser qualquer um ou o servidor do bitbucket/github/gitlab entre outros;
branch – um galho de desenvolvimento independente, geralmente o seu galho de desenvolvimento, e de onde suas modificações serão enviadas e recebidas para se manterem atualizadas com o repositório principal;
master – o branch padrão de desenvolvimento, ou a versão que tem todas as mudanças e que é a base do desenvolvimento. O github especificamente trocou o nome padrão em 2019/2020 para main. Seus documentos estão nesse galho, quando você inicia um projeto (init);
pull – esse é um comando, e ele puxa as mudanças do repositório remoto para o local, atualizando o local com as ultimas alterações do mesmo branch;
commit – é uma “versão” dos documentos ou repositórios, quando você salva as alterações no repositório master, geralmente são um conjunto de alterações que juntas corrigem uma falha ou implementam um conjunto de funcionalidades, é uma boa prática manter esses commits sempre comentados e separados por funcionalidade;
push – envia as mudanças para o repositório remoto, pode ser um único commit ou diversos commits juntos;
head – é o estado atual do seu repositório. Como ele está nesse momento;
clone – uma cópia do repositório remoto, feita localmente, para ser usada ou alterada;
merge – é a união de um branch com outro, formando um ponto comum aos dois branch, geralmente o merge é feito de um branch para o repositório master;
pull request – é uma solicitação de integrar um conteúdo ao repositório principal, criar uma pull request, significa que você fez uma alteração e vai submete-la aos responsáveis por manter o código principal do projeto, como uma sugestão de melhoria;
fork – é fazer uma cópia de um projeto, como o nome diz, dá uma garfada no projeto de outro e cria a sua própria versão master, imagina, você vê um projeto que quer utilizar de um software de contatos, porém, você quer ter a opção de estender ele tornando-o um crm, porém, não é o escopo original, então você cria um FORK e faz s suas mudanças e passa a ter seus próprios branch. Resumidamente é uma distribuição diferente daquele projeto original.
Porque usar Git?
Simplesmente porque ele facilita seu fluxo de trabalho, permite que cada desenvolvedor da equipe pegue uma porção para desenvolver, faça suas modificações e mantenha o repositório central sempre atualizado e disponível para os usuários e programadores.
Não vou entrar em detalhes dos comandos do git, pois o objetivo aqui não é ser um tutorial e sim um artigo sobre ele, se você quiser aprender a usar o git, pode acessar: https://git-scm.com/book/pt-br/v2 que é o site do projeto e este link leva direto a um livro em PDF/EPUB em portugues com TODOS os comandos do git explicados e exemplificados.
Além de que, existem dezenas de ambientes gráficos que implementam o git, um deles é o próprio vs-code e basta uma busca no google e você encontra diversas implementações com mais ou menos recursos e que você escolhe qual a maneira que prefere.
Uma confusão muito comum, é GIT e GITHUB são coisas totalmente diferente, GIT é um sistema de controle de versão, já GitHub ou GitLab ou utro, são serviços que implementam o git em um fluxo de trabalho e hospedam repositórios (vulgarmente, seriam servidores git) onde os usuários podem manter seus repositórios e utilizar um conjunto de ferramentas para usar este fluxo de trabalho, o que pode automatizar algumas tarefas conforme o prestador de serviços quiser.