GIT

Você vai ler sobre:

Cada vez mais as empresas investem em projetos de tecnologias para facilitar negócios, automatizar tarefas, difundir informações entre vários outros propósitos. Geralmente uma das primeiras etapas de desenvolvimento de projetos é definir como você irá controlar e manter as alterações que irão ocorrer ao longo do desenvolvimento. Existem algumas ferramentas de mercado com esta finalidade.

Neste artigo você irá aprender conceitos básicos sobre Git, uma ótima opção para este propósito. Entre os controles de versões disponíveis no mercado, o Git é o mais utilizado, principalmente em projetos open source. Esta ferramenta armazena todas as alterações ocorridas nos arquivos do seu projeto permitindo regressões para um estado anterior. Além disso, permite que várias pessoas trabalhem simultaneamente no mesmo projeto e até nos mesmos arquivos.

CVCS x  DVCS 

Existem diversos sistemas de controle de versão no mercado. Há sistemas de controle de versão centralizado, o CVCS (Centralized Version Control System), como Subversion (SVN), CVS e Perforce. E há sistemas de controle de versão distribuído, o DVCS (Distributed Version Control System), como Git, Mercurial e Bazaar.

CVCS-x-DVCS.png

O CVCS possui um repositório central do projeto, geralmente localizado em um servidor, que contém todo o histórico do projeto. Qualquer membro do projeto que desejar colaborar, precisará fazer um checkout de uma versão do projeto. Essa operação irá baixar uma cópia da versão selecionada para a máquina do contribuidor, porém nesta máquina não existirá o histórico do projeto. O histórico só existe no repositório central e por isso, vários comandos são executados remotamente, o que gera uma dependência de conexão à internet e explica o motivo da maioria dos comandos serem mais lentos, dado que existe o overhead da rede.

O DVCS por outro lado não depende necessariamente de um repositório central. Isso porque os contribuidores podem clonar repositórios existentes ou criar seus próprios repositórios locais. Esse processo de clonagem baixa todo o conteúdo remoto e também o histórico completo do projeto. Por isso, a maioria das operações podem ocorrer localmente, sem depender de conexão com internet, o que resulta em uma velocidade maior comparado aos CVCSs. Pelo histórico estar distribuído, há uma quantidade maior de backups comparado a um CVCS, já que nesse, o histórico só existe no repositório central. Se o repositório central estiver localizado em um servidor interno vulnerável, isso poderia comprometer todo o histórico do projeto. 

Local x remoto

No Git é possível criar o próprio repositório através do comando git init, que irá criar o diretório oculto ".git". Porém, é importante que esse repositório esteja armazenado remotamente, isso porque tal opção pode servir como backup do repositório. Para armazenamento remoto você pode considerar as plataformas de hospedagem para repositórios Git, como Bitbucket, GitLab e GitHub ou até mesmo um servidor próprio. Caso ocorra um problema irreparável em seu computador, você estará seguro pois o repositório também existe na opção que você está utilizando.

Além disso, é interessante que o projeto esteja disponível remotamente para possibilitar o trabalho colaborativo. Outras pessoas podem baixar uma cópia do repositório (clone), realizar modificações e enviar (push) tais alterações novamente para o repositório remoto. Quando for necessário atualizar o repositório porque outro contribuidor submeteu novas versões, basta atualizar o repositório local puxando as modificações envolvidas (pull).

As três áreas 

O Git possui 3 áreas principais: a área de trabalho, a área de preparo e o repositório.

 As-tres-areas.png

A área de trabalho (Working Directory) é o checkout de uma versão do projeto. Corresponde aos arquivos e diretórios visíveis e alteráveis. 

Ao realizar qualquer alteração, seja mudança em arquivos existentes, como inclusão de novos arquivos, antes de gerar uma nova versão, você primeiramente deve adicionar tais alterações para a área de preparo (Staging Area). 

Por fim, você poderá executar um commit, que irá considerar todas as alterações que estiverem na área de preparo. Isso irá produzir uma nova versão no histórico do projeto.

Commits

O histórico de versões no Git é formado por objetos de commit. Esse histórico é baseado em uma estrutura denominada DAG (Directed Acyclic Graph). Um commit é uma imagem do atual estado do seu repositório. Ou seja, é uma "foto" de como está cada arquivo no momento deste commit. É possível retornar para qualquer commit feito no passado.

O commit está associado a uma hash SHA-1, tal hash possui metadados como autor, data de criação, mensagem e commit pai. Todos esses metadados mais o conteúdo do arquivo formam o SHA-1 do commit, que é imutável. Ou seja, não pode ser alterado. Por isso, qualquer comando utilizado com o propósito de alterar algo relacionado ao commit, irá resultar em um novo SHA-1.

Desfazendo commit 

Veremos duas formas de desfazer commits, por revert ou reset. A primeira opção cria um novo commit desfazendo tudo que foi realizado no commit selecionado a ser desfeito. Como pode ser visto na imagem abaixo, o segundo commit incluiu uma funcionalidade XPTO, mas posteriormente foi verificado que essa funcionalidade poderia ser descartada, então um commit de revert foi gerado.artigo_GIT_-_blog_-_interna_01.png

A segunda opção é utilizar o comando reset. O reset faz que a funcionalidade XPTO conste como se nunca tivesse existido no histórico. Considere a imagem abaixo como resultado de um reset ao invés de revert do exemplo anterior:

artigo_GIT_-_blog_-_interna_02.png

É importante destacar que qualquer ação que resulte na eliminação de um commit já existente deve ser realizada com bastante cautela. O uso de reset e outros comandos destrutivos exigem que você possua sólidos conhecimentos em Git e compreenda as situações que não são recomendadas a utilização desses comandos, inclusive, para não comprometer outros contribuidores.

Branches

Em teoria, uma branch é uma ramificação de um projeto. Na prática, no Git, uma branch é uma referência para um commit. A branch principal de um projeto chama-se “master”. Porém, há iniciativas para alterar este nome a longo prazo, devido ao termo “master” ser considerado racista.

 Há vários benefícios na utilização de branches como:

Considere a imagem abaixo como um exemplo de um repositório com mais de uma ramificação:

artigo_GIT_-_blog_-_interna_03.png

Na imagem acima, uma ramificação do projeto é criado a partir da versão "first commit". Nesse instante, cada ramo terá seus próprios commits enquanto não houver algum mecanismo de fusão entre os ramos. Os principais mecanismos de fusão são: merge ou rebase.

A referência HEAD

A HEAD é uma referência que normalmente vai apontar para a branch corrente. Já uma branch, como visto anteriormente, é uma referência para um commit. Este commit por sua vez, será a última versão de tal ramificação. Para um melhor entendimento, considere a sequência a seguir. 

Inicialmente existe somente uma branch chamada master que aponta para o commit "first commit". Também existe uma referência chamada HEAD que aponta para a branch master, ou seja, indiretamente aponta para o commit "first commit". Aqui existe uma referência simbólica, que ocorre quando uma referência aponta para outra referência.

artigo_GIT_-_blog_-_interna_05.png

É criado uma nova branch chamada xpto a partir do commit "first commit". 

 artigo_GIT_-_blog_-_interna_06.png

Ao realizar checkout na nova branch, o Git altera a referência HEAD para apontar para a branch xpto. Isso significa que qualquer novo commit será aplicado na ponta dessa nova branch. Veja o resultado de um commit "creating service" na branch xpto.

artigo_GIT_-_blog_-_interna_07.png 

Observe que se outro commit for realizado, o rótulo da branch xpto irá referenciar o novo commit. Para a referência HEAD não há mudanças, ela permanecerá apontando para a branch corrente.
artigo_GIT_-_blog_-_interna_08.png 

Agora para gerar novos commits na branch principal, basta realizar primeiramente um checkout na branch master.artigo_GIT_-_blog_-_interna_09.png 

Pronto, agora qualquer novo commit será aplicado na branch master. Veja o resultado de um commit "hotfix" nesta situação.
 artigo_GIT_-_blog_-_interna_10.png

Tags

Geralmente nos sistemas de controle de versão existe um recurso chamado tags e com o Git não é uma exceção. As tags são utilizadas para demarcar marcos importantes, tais marcos estão associados a um commit específico. Geralmente, as pessoas utilizam esta funcionalidade para liberações de release em produção. Por exemplo, é possível marcar commits com rótulos 1.0, 1.1, 1.2, 2.0 e assim por diante.

 Além de trazer mais organização para o histórico, as tags também são referências e podem ser usadas com qualquer comando que utiliza referências como entrada. Vale destacar que diferentemente de branches, que são referências mutáveis pois mudam conforme cada nova versão, as tags são referências imutáveis, uma vez criadas associadas a um commit elas não irão mudar.

Conclusão

Como vimos, o Git é um sistema de controle de versão distribuído que possui diversos recursos para auxiliar na gestão de alterações. É uma ferramenta muito utilizada principalmente no contexto de software e que também permite que um grupo de pessoas possa trabalhar de forma colaborativa no mesmo projeto, editando e criando novos arquivos.

Sobre o autor

Rodrigo Santana

Rodrigo Santana é Analista de Sistemas na Lumis. Formado em ciência da computação pela Universidade do Estado do Rio de Janeiro (UERJ), técnico de informática pela Fundação de Apoio à Escola Técnica (FAETEC). Com mais de 6 anos de experiência na área de desenvolvimento de sistemas, no momento, atua como Líder Técnico. Apaixonado por tecnologia e adepto do aprendizado contínuo. Possui enorme satisfação em compartilhar conhecimento. É extremamente dedicado para atingir objetivos profissionais e pessoais. Possui experiência em múltiplos segmentos como: Shoppings centers, distribuição de gás, cursos de idioma, escolas e hospitais.

https://www.linkedin.com/in/rodrigo-anselmo-santana/