Idioma
Categoria
Pesquisar

Entendendo o funcionamento básico do Git e o uso de branches

Uma introdução ao git: como implementar em um projeto, definir configurações básicas, gerenciar branches, ver históricos e lidar com conflitos

Em Terminal Por Rudi Drusian Lange
Publicado em
Última atualização

Sobre

Do manual: Git é um sistema de controle de revisão distribuído, rápido e dimensionável, com um conjunto de comandos excepcionalmente rico que oferece operações de alto nível e acesso total aos componentes internos.

Ajuda

Para consultar o manual do Git, use man git. Existem duas formas para saber mais informações sobre um comando específico como git log: man git-log ou git help log.

Iniciando um projeto

Antes de mais nada é uma boa prática configurar o nome e o email que serão usados nos projetos:

Shell

git config --global user.name "Seu Nome Aqui"
git config --global user.email seu@email.com

Supondo que o projeto a ser gerenciado se encontre na pasta meu-projeto, inicie o Git:

cd meu-projeto
git init

# Repositório Git vazio iniciado em .git/
Initialized empty Git repository in .git/

Um novo diretório .git/ foi criado dentro da pasta meu-projeto. Em seguida, para fazer uma cópia de todo o conteúdo de todos os arquivos no diretório atual, use:

# O ponto '.' representa o diretório atual
git add .

O estado atual dos arquivos é normalmente referido como snapshot, que seria no sentido de tirar uma foto instantânea dos arquivos. Com git add o snapshot é salvo temporariamente no index, para que o conteúdo seja armazenado definitivamente use:

git commit

Commit inicial
# Please enter the commit message for your changes. Lines starting  # with '#' will be ignored, and an empty message aborts the commit. ...

Será solicitado que você digite uma mensagem para definir este armazenamento, neste exemplo foi usado Commit inicial. Não digitar uma mensagem cancela o processo. O editor vi foi utilizado, Esc + i habilita a inserção de texto, após digitar a mensagem salve e saia pressionando Esc e depois digitando :wq (write and quit).

Você também pode definir a mensagem na linha de comando usando -m:

git commit -m "Commit inicial"

Modifique alguns arquivos, adicione o conteúdo atualizado ao index e execute o commit. Abaixo alguns comandos úteis para auxiliar no processo.

# Para adicionar múltiplos arquivos no index
git add arquivo1 arquivo2 arquivo3

# Mostra alterações que não foram adicionadas ao index
git diff

# Mostra alterações já no index mas ainda não salvas
git diff --cached # Retorna um resumo da situação git status # Remove um arquivo do index git restore --staged nome-do-arquivo # Para salvar permanentemente git commit

Lembre de digitar a mensagem do commit, salvar e sair.

git commit -a

O comando acima irá identificar qualquer modificação em arquivos pré existentes, adicioná-los ao index e executar o commit, tudo ao mesmo tempo. Arquivos novos serão ignorados.

É uma boa prática usar a primeira linha da mensagem de commit como título, algo que resuma a alteração sendo realizada em menos de 50 caracteres. Deixe uma linha em branco após o título e escreva uma mensagem mais detalhada. O texto acima da linha em branco é considerado como título e será usado em diversas situações no comando git.

Exemplo: git format-patch transforma o commit em um email, usa o título como assunto e o restante do texto do commit como mensagem.

Histórico do projeto

O histórico pode ser consultado a qualquer momento através do comando git log.

# Histórico de commit
git log

# Diferença completa em cada etapa
git log -p

# Visão geral das alterações
git log --stat --summary

Gerenciando ramificações (Branches)

Será abordado abaixo o uso de ramificações ou subdivisões de um projeto, o ato de iniciar e gerir um novo projeto baseado no original. No comando é usado o termo em inglês branches e para se referir ao projeto inicial usa-se master. Estes termos serão usados no inglês na sequência desta documentação com objetivo de facilitar o aprendizado.

Um único repositório Git pode manter múltiplos branches de desenvolvimento.

# Criando um novo branch chamado experimental
git branch experimental

Listando todos os branches, asterisco marca o branch atual:

git branch

  experimental 
* master

Mudando para o branch experimental:

git switch experimental

Mude para o branch experimental com o comando acima, altere um arquivo qualquer e com os comandos abaixo de commit e volte ao branch master:

git commit -a
git switch master

Verifique que a alteração realizada no arquivo enquanto no branch experimental não está presente no master. Para mesclar o branch experimental com o branch master use o comando:

git merge experimental 

Ao mesclar o branch experimental com o master, todas as alterações realizadas no arquivo do branch experimental serão adicionadas ao master. Neste exemplo acima somente foram feitas alterações no arquivo enquanto no branch experimental.

Se as alterações fossem feitas no mesmo arquivo em ambos os branches, porém em linhas diferentes, ao mesclar os branches as duas alterações seriam mantidas.

Exemplo prático

Vamos criar o arquivo projeto.txt com o conteúdo abaixo e adicioná-lo a ambos os branches:

# Mude para o branch master
git switch master      

# Crie o arquivo projeto.txt
vi projeto.txt

projeto.txt

1
2
3
# Adicione projeto.txt ao index
git add projeto.txt

# Salve
git commit -a   

# Mude para o branch experimental
git switch experimental  

# Mescla todas as alterações feitas em master incluindo
# uma cópia do arquivo projeto.txt para experimental
git merge master

Ao executar o commit, lembre-se de adicionar uma descrição, salvar e sair.

Adicione o número 0 na primeira linha do arquivo projeto.txt estando no branch experimental e adicione o número 4 ao final do mesmo arquivo porém estando no branch master.

vi projeto.txt

projeto.txt | branch experimental

0
1
2
3
git commit -a 
git switch master  
vi projeto.txt

projeto.txt | branch master

1
2
3
4
git commit -a
git merge experimental

Ao mesclar o branch experimental com o master usando o comando acima, o resultado será:

projeto.txt | branch master

0
1
2
3
4

Vale lembrar que no branch experimental o arquivo continua igual, com 0,1,2,3.

Conflitos

Se alterações fossem feitas na mesma linha em ambos os branches master e experimental, ao usar o comando merge um erro de conflito seria exibido e o processo interrompido solicitando a resolução. Neste caso o Git não sabe qual das alterações manter e por isso precisa da intervenção humana para resolver o conflito.

Continuando o exemplo anterior, agora entre no branch experimental, adicione -1 na primeira linha, de o commit, volte ao branch master, adicione +1 na primeira linha e de o commit.

Antes de mesclar os branches, vamos ver como está cada arquivo agora

projeto.txt

# branch master     # branch experimental
+1                  -1
0                    0
1                    1
2                    2
3                    3
4

Mesclando:

git merge experimental
                                                                   
Auto-merging projeto.txt CONFLICT (content): Merge conflict in projeto.txt Automatic merge failed; fix conflicts and then commit the result.

Git diff irá exibir este e outros conflitos existentes e é usado justamente para este fim.

git diff

Para corrigir o conflito iremos utilizar o comando:

git mergetool

Este comando não irá necessariamente abrir um editor para resolver o conflito a não ser que você tenha uma das opções suportadas instalada. Neste exemplo usaremos o vimdiff, se tiver acesso a interface gráfica pode ser uma vantagem usar o gvimdiff. Execute as seguintes configurações no Git:

# Define o vimdiff como padrão
git config merge.tool vimdiff
# Usa o estilo diff3 para exibição dos conflitos git config merge.conflictstyle diff3
# Não pergunta qual editor deve ser usado git config mergetool.prompt false

Para mais informações sobre os comandos acima:

git help config mergetool

# Lista de editores compatíveis
git mergetool --tool-help

Resolvendo o conflito:

git mergetool

vimdiff

╔═══════╦══════╦════════╗
║       ║      ║        ║
║ LOCAL ║ BASE ║ REMOTE ║
║       ║      ║        ║
╠═══════╩══════╩════════╣
║                       ║
║        MERGED         ║
║                       ║
╚═══════════════════════╝

As quatro visualizações são:

  • LOCAL: arquivo do branch atual (master em nosso exemplo)
  • BASE:  versão anterior as alterações
  • REMOTE: arquivo do branch que estamos mesclando (experimental em nosso exemplo)
  • MERGED: este é o resultado da mesclagem, o que será usado no final

No vimdiff o atalho Ctrl + W 2x é usado para navegar entre as janelas. Use o comando :help window-moving dentro do editor para mais informações sobre a navegação entre as janelas.

Para escolher qual versão usar, pressione Esc e depois digite:

vimdiff

# Para usar o arquivo base
:diffg BA
# Para usar o arquivo local :diffg LO   # Para usar o arquivo remoto :diffg RE

Agora salve, feche, commit e limpe:

# Salva e fecha o vimdiff
Esc :wqa   

# Commit
git commit -m "mensagem"

# Remove arquivos adicionais (ex: *.orig)
# Cuidado! arquivos não rastreados serão removidos
git clean -f

Você também pode editar o arquivo mesclado(merged) digitando um novo código e salvá-lo ao em vez de usar uma das versões disponíveis.

Histórico

O comando abaixo irá mostrar uma bela representação gráfica do histórico das alterações. Aqui as mensagens usadas a cada commit farão melhor sentido.

gitk

Excluindo um branch

Neste ponto o branch experimental serviu seu propósito de alterar o projeto sem comprometer a versão original e pode ser deletado, use o comando:

git branch -d experimental

Esse comando verifica se as alterações do branch experimental já foram aplicadas antes da exclusão. Se você desenvolveu uma ideia ruim e deseja descartar as alterações deste branch, use:

git branch -D ideia-ruim

Conclusão

Use e abuse de branches, eles são fáceis e baratos :-), é uma ótima maneira de experimentar algo diferente.

Este artigo foi dividido em partes para que não fique muito longo e desestimule o aprendizado, você pode continuar a aprender sobre Git lendo: Usando Git para compartilhar e colaborar em um projeto, que é a continuação deste artigo.

Referências