Informática

Git: três estados, commit, branch e merge com conflito executado

O controle de versão com Git entrou nos editais de cargos de tecnologia: quem trabalha com desenvolvimento no serviço público precisa saber o que é um repositório, o que significa preparar (stage) uma alteração e por que um merge às vezes dá conflito. As questões de concurso cobram conceitos e a leitura de saídas de comando. Este guia explica o modelo mental do Git e mostra uma sequência real de comandos que foi executada em um repositório de teste, com a saída conferida.

Não há lei sobre o tema. A fonte é a documentação oficial do projeto Git, o livro “Pro Git”, lido no site do projeto, cujo texto de licença aberta é a referência técnica de uso corrente.

O que o Git controla

O Git é um sistema de controle de versão distribuído: cada cópia do repositório contém todo o histórico. Ele guarda o projeto como uma série de instantâneos (snapshots), chamados commits, cada um com autor, mensagem e ligação com o commit anterior.

Os três estados e as três áreas

O livro oficial resume o fundamental assim: um arquivo pode estar em três estados.

Estado O que significa
Modificado (modified) Você alterou o arquivo, mas ainda não o confirmou no banco de dados
Preparado (staged) Você marcou a versão atual de um arquivo modificado para entrar no próximo commit
Confirmado (committed) Os dados estão armazenados com segurança no banco de dados local

E esses estados correspondem a três áreas de um projeto:

  • Diretório de trabalho (working tree): a cópia em disco dos arquivos que você edita.
  • Área de preparação (staging area, ou index): um arquivo que guarda o que irá para o próximo commit.
  • Diretório Git (repositório): onde ficam os metadados e o banco de objetos; é o que se copia quando você clona um repositório.

O fluxo básico: modificar arquivos; preparar apenas as alterações desejadas (git add); fazer o commit (git commit), que grava o instantâneo da área de preparação.

Sequência executada: do arquivo novo ao commit

Em um repositório vazio, criei o arquivo a.txt com uma linha e acompanhei o estado com git status -s (formato curto). Saídas observadas:

  1. Arquivo novo, ainda não rastreado: ?? a.txt
  2. Depois de git add a.txt: A a.txt (A na primeira coluna: adicionado à área de preparação)
  3. Depois de git commit: o status -s não mostra nada (árvore limpa)
  4. Depois de editar o arquivo: M a.txt (M na segunda coluna: modificado no diretório de trabalho, ainda não preparado)

As duas colunas do formato curto são úteis para a prova: a primeira coluna representa a área de preparação e a segunda representa o diretório de trabalho. Por isso M (M na primeira) é “preparado” e M (M na segunda) é “modificado, não preparado”.

Diferença entre git diff e git diff –staged

Após editar e antes de git add, git diff mostrou a linha acrescentada (+linha 2) e git diff --staged não mostrou nada. Depois do git add, aconteceu o inverso: git diff ficou vazio e git diff --staged mostrou a linha. Regra: git diff compara o diretório de trabalho com a área de preparação; git diff --staged compara a área de preparação com o último commit.

Desfazendo uma preparação

Com a alteração preparada (M no status), o comando git restore --staged a.txt a tira da área de preparação (voltou para M), e git restore a.txt descarta a alteração no diretório de trabalho (status limpo). Atenção: o segundo comando joga fora a edição sem volta.

Branches e merge

Um branch (ramo) é uma linha independente de desenvolvimento, na prática um ponteiro leve para um commit. Criei o ramo ajuste com git switch -c ajuste, fiz um commit nele, voltei ao ramo principal e fiz outro commit lá.

O histórico, mostrado por git log --oneline --graph --all, ficou assim:

* 9603770 principal
| * f53622b ajuste
|/
* c93a5a2 segundo
* 16ad352 primeiro

Os dois ramos divergiram a partir do commit “segundo”. Quando o ramo principal recebeu o merge do ramo ajuste, o Git informou:

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

Por que houve conflito

Os dois ramos alteraram a mesma região do mesmo arquivo (o fim do a.txt): um acrescentou “linha 3 da principal”; o outro, “linha 3 do ajuste”. O Git não sabe qual escolher e pede ajuda. O status passou a mostrar UU a.txt (modificado nos dois lados, não resolvido), e o arquivo ficou com marcadores:

<<<<<<< HEAD
linha 3 da principal
=======
linha 3 do ajuste
>>>>>>> ajuste

Entre <<<<<<< e ======= está a versão do ramo atual (HEAD); entre ======= e >>>>>>>, a do ramo que está sendo integrado.

Como resolver

  1. Abra o arquivo e decida o resultado (aqui, manter as duas linhas) apagando os marcadores.
  2. Prepare o arquivo: git add a.txt.
  3. Conclua com git commit.

O histórico passou a ter um commit de merge com dois pais, que o gráfico mostrou como o losango |\ e |/.

Se os ramos tivessem alterado partes diferentes, ou se apenas um deles tivesse commits novos, o merge ocorreria sem conflito (neste último caso, como simples avanço do ponteiro, o chamado fast-forward). Mesclar um ramo que já está contido no atual resulta em “Already up to date”.

Comandos para reconhecer em prova

Comando O que faz
git init Cria um repositório novo
git clone Copia um repositório existente, com todo o histórico
git status Mostra o estado dos arquivos
git add Prepara alterações para o próximo commit
git commit Grava um instantâneo da área de preparação
git log Lista o histórico
git branch Lista ou cria ramos
git switch Troca de ramo
git merge Integra o histórico de outro ramo no ramo atual

Pegadinhas

  • Achar que git add grava no histórico: ele só prepara; quem grava é o commit.
  • Achar que commit envia ao servidor remoto. O commit é local; o envio exige outro comando.
  • Dizer que o conflito é “erro de sistema”: é uma decisão que só uma pessoa pode tomar.
  • Confundir Git (ferramenta de versão) com serviços de hospedagem de repositórios.
  • Esquecer que cada clone contém o histórico completo.

Próximos passos

Combine com engenharia de software: requisitos e testes, ciclos de vida de software e desenvolvedor de software no serviço público.

Fontes e atualização

Sem norma jurídica sobre o tema. Fonte técnica lida: o livro Pro Git, seções sobre o que é o Git, o registro de alterações e ramificação, no site do projeto. Os comandos foram executados em repositório de teste, e as saídas citadas são as observadas. Versões do Git podem mudar mensagens; confira o edital e veja a metodologia do site.

Leia também

Para continuar no site

Viu algo errado, desatualizado ou confuso? Relatar erro nesta página