Entender o histórico do Git

Azure DevOps Services | Azure DevOps Server 2020 | Azure DevOps Server 2019 | TFS 2018

O Git armazena o histórico como um grafo de instantâneos — chamados de commits — de todo o repositório. Cada confirmação também contém um ponteiro para uma ou mais confirmações anteriores. As confirmações podem ter vários pais, criando um histórico que se parece com um grafo em vez de uma linha reta. Essa diferença no histórico é incrivelmente importante e é o principal motivo pelo qual os usuários acham o Git confuso.

Observação

Se você não conseguir encontrar uma alteração em seu histórico do Git que você sabe que fez, saiba mais sobre como a simplificação do histórico do Git funciona no Git e minhas alterações foram perdidas: dando uma olhada na simplificação do histórico do Git.

Noções básicas do histórico de confirmação

Comece com um exemplo de histórico simples: um repositório com três confirmações lineares.

three commits in a line

Commit A é o pai do commit B e commit B é o pai da confirmação C. Essa história é muito semelhante a um CVCS. A seta que aponta para confirmar C é um branch. Ele é nomeado main porque esse é o nome padrão para o branch de linha principal em um repositório Git. Branches são ponteiros para confirmações específicas, e é por isso que a ramificação é tão leve e fácil no Git.

Uma diferença importante no Git em comparação com o CVCS é que tenho minha própria cópia completa do repositório. Preciso manter meu repositório local em sincronia com o repositório remoto obtendo as confirmações mais recentes do repositório remoto. Para fazer isso, eu puxarei o branch principal com o seguinte comando:

git pull origin main

Isso copia ("pulls") todas as confirmações do main branch do repositório remoto (chamado origin por padrão) para o main branch do repositório local. A operação de pull copiou uma nova confirmação e a main ramificação no repositório local agora está apontando para essa nova confirmação.

a fourth commit, D, is added to the line

Entender o histórico do branch

Agora quero fazer uma alteração no meu código. É comum ter vários branches ativos em que você está trabalhando em diferentes recursos em paralelo. Isso contrasta fortemente com o CVCS, onde novas ramificações são pesadas e raramente criadas. A primeira etapa é fazer check-out para um novo branch usando o seguinte comando:

git checkout -b cool-new-feature

Esse é um atalho que combina dois comandos: git branch cool-new-feature criar o branch seguido para git checkout cool-new-feature começar a trabalhar no branch.

Branch cool-new-feature is added

Duas ramificações agora apontam para a mesma confirmação. Farei algumas alterações na ramificação cool-new-feature em duas novas confirmações, E e F.

added two new commits

Minhas confirmações podem ser acessadas pelo cool-new-feature branch desde que as fiz naquela ramificação. Terminei meu recurso e quero mesclá-lo main. Para fazer isso, usarei o seguinte comando:

git merge cool-feature main

after the merge

A estrutura de grafo da história fica visível quando há uma mesclagem. O Git cria uma nova confirmação quando mescla minha ramificação em outra ramificação. Essa é uma confirmação de mesclagem. Não há nenhuma alteração incluída nesta confirmação de mesclagem, pois eu não tinha conflitos. Se eu tivesse conflitos, a confirmação de mesclagem incluiria as alterações necessárias para resolver esses conflitos.

História no mundo real

Aqui está um exemplo do histórico do Git que se assemelha mais ao código no desenvolvimento ativo em uma equipe. Há três pessoas que mesclam confirmações de suas próprias ramificações na ramificação principal ao mesmo tempo.

console log of git graph

Agora que você entende como branches e mesclagens criam a forma do grafo, isso não deve ser muito assustador!