<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Merge on kenji.blog</title><link>http://kenji.blog/pt/tags/merge/</link><description>Recent content in Merge on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>pt</language><copyright>kenjinote</copyright><lastBuildDate>Sun, 13 Sep 2026 09:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/pt/tags/merge/index.xml" rel="self" type="application/rss+xml"/><item><title>【Comandos Git】A diferença entre rebase e merge e como usá-los corretamente na prática</title><link>http://kenji.blog/pt/p/git-rebase-vs-merge-practical-guide/</link><pubDate>Sun, 13 Sep 2026 09:00:00 +0900</pubDate><guid>http://kenji.blog/pt/p/git-rebase-vs-merge-practical-guide/</guid><description>&lt;img src="http://kenji.blog/p/git-rebase-vs-merge-practical-guide/img/eyecatch.jpg" alt="Featured image of post 【Comandos Git】A diferença entre rebase e merge e como usá-los corretamente na prática" />&lt;h1 id="1-introdução-por-que-merge-ou-rebase-é-um-dilema-eterno">1. Introdução: Por que &amp;ldquo;merge ou rebase&amp;rdquo; é um dilema eterno
&lt;/h1>&lt;p>Git é um sistema de controle de versão indispensável no desenvolvimento de software moderno. Quando vários desenvolvedores alteram uma base de código simultaneamente, o poderoso modelo de branches do Git entra em ação. No entanto, no desenvolvimento em equipe, a discussão sobre &amp;ldquo;qual usar: &lt;code>merge&lt;/code> ou &lt;code>rebase&lt;/code>&amp;rdquo; é um tópico que sempre atormenta os desenvolvedores, de iniciantes a veteranos.&lt;/p>
&lt;p>Neste artigo, desvendaremos a diferença entre os mecanismos de &lt;code>git merge&lt;/code> e &lt;code>git rebase&lt;/code>, explorando a estrutura interna do Git, como o DAG (Grafo Acíclico Direcionado) e as propriedades matemáticas dos hashes de commit. Além disso, explicaremos detalhadamente como usá-los corretamente na prática, com fluxos de trabalho específicos. Ao compreender as operações matemáticas que o Git realiza nos bastidores, e não apenas introduzir comandos, você perderá o medo de conflitos e poderá construir um histórico limpo e rastreável.&lt;/p>
&lt;hr>
&lt;h1 id="2-estrutura-interna-do-git-hashes-de-commit-e-modelo-de-objetos">2. Estrutura interna do Git: Hashes de commit e modelo de objetos
&lt;/h1>&lt;p>Para entender como o Git integra o histórico, primeiro precisamos saber como ele armazena dados. O Git não armazena apenas as diferenças (patches) de alterações de arquivos, mas sim um instantâneo (snapshot) de todo o sistema de arquivos em um determinado momento.&lt;/p>
&lt;h2 id="21-propriedades-criptográficas-dos-hashes-de-commit">2.1 Propriedades criptográficas dos hashes de commit
&lt;/h2>&lt;p>Cada commit no Git é identificado de forma única por um número hexadecimal de 40 dígitos gerado pela função de hash SHA-1 (Secure Hash Algorithm 1), calculada com base no seu conteúdo. Um objeto de commit é composto pelos seguintes elementos:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Ponteiro para o objeto Tree&lt;/strong>: O instantâneo da estrutura de diretórios e arquivos (Blob) naquele momento&lt;/li>
&lt;li>&lt;strong>Ponteiro para o commit pai&lt;/strong>: O valor do hash de um ou mais commits pais (o primeiro commit não tem pai e um commit de merge tem dois ou mais pais)&lt;/li>
&lt;li>&lt;strong>Informações do autor (Author)&lt;/strong>: A pessoa que escreveu o código e a data/hora&lt;/li>
&lt;li>&lt;strong>Informações do committer (Committer)&lt;/strong>: A pessoa que criou/aplicou o commit e a data/hora&lt;/li>
&lt;li>&lt;strong>Mensagem de commit&lt;/strong>: Texto explicando a intenção da alteração&lt;/li>
&lt;/ol>
&lt;p>Matematicamente, o valor do hash $H(C)$ para um objeto de commit $C$ é definido da seguinte forma:&lt;/p>
$$
H(C) = \text{SHA-1}( \text{tree} \parallel \text{parent} \parallel \text{author} \parallel \text{committer} \parallel \text{message} )
$$&lt;p>Aqui, $\parallel$ representa a concatenação de dados. Devido às propriedades da função de hash, mudar até mesmo um único caractere na mensagem de commit, ou ter um commit pai diferente, gerará um valor de hash completamente diferente. Ou seja, &lt;strong>os commits são imutáveis (Immutable)&lt;/strong>. Quando dizemos que o &lt;code>rebase&lt;/code>, que será explicado mais adiante, &amp;ldquo;reescreve o histórico&amp;rdquo;, na verdade ele &amp;ldquo;cria novos commits com conteúdos semelhantes, mas com hashes diferentes&amp;rdquo;.&lt;/p>
&lt;p>O tamanho do espaço de hash é $2^{160}$ e a probabilidade $P$ de ocorrer uma colisão (dois commits diferentes com o mesmo valor de hash) pode ser aproximada usando a teoria do Paradoxo do Aniversário (onde $n$ é o número de commits):&lt;/p>
$$
P(\text{collision}) \approx 1 - \exp\left(-\frac{n^2}{2 \times 2^{160}}\right)
$$&lt;p>Essa probabilidade é extremamente baixa e, na prática, é quase impossível que os hashes de commit do Git colidam.&lt;/p>
&lt;hr>
&lt;h1 id="3-teoria-dos-grafos-e-dag-o-modelo-matemático-do-histórico-do-git">3. Teoria dos grafos e DAG: O modelo matemático do histórico do Git
&lt;/h1>&lt;p>O histórico de commits do Git é modelado como um &amp;ldquo;Grafo Acíclico Direcionado (DAG - Directed Acyclic Graph)&amp;rdquo; na teoria dos grafos.&lt;/p>
&lt;h2 id="31-o-que-é-um-dag-grafo-acíclico-direcionado">3.1 O que é um DAG (Grafo Acíclico Direcionado)
&lt;/h2>&lt;p>Em um grafo $G = (V, E)$, $V$ é o conjunto de commits (vértices) e $E$ é o conjunto de arestas direcionadas que indicam as relações pai-filho entre os commits. No Git, a direção das arestas vai &amp;ldquo;do commit filho para o commit pai&amp;rdquo;. Isso ocorre porque um novo commit contém um ponteiro para um commit passado.&lt;/p>
&lt;pre class="mermaid">
graph BT
A[&amp;#34;Commit A (Inicial)&amp;#34;]
B[&amp;#34;Commit B&amp;#34;]
C[&amp;#34;Commit C (Main)&amp;#34;]
D[&amp;#34;Commit D (Feature)&amp;#34;]
E[&amp;#34;Commit E (Merge)&amp;#34;]
B --&amp;gt; A
C --&amp;gt; B
D --&amp;gt; B
E --&amp;gt; C
E --&amp;gt; D
&lt;/pre>
&lt;p>A maior característica do DAG é a &amp;ldquo;ausência de ciclos (loops)&amp;rdquo;. Isso garante que algoritmos que rastreiam o histórico de commits nunca entrem em um loop infinito e alcancem com segurança o fim (o commit inicial).&lt;/p>
&lt;h2 id="32-ordenação-topológica-e-a-ordem-do-histórico">3.2 Ordenação topológica e a ordem do histórico
&lt;/h2>&lt;p>Quando o histórico é exibido usando comandos como &lt;code>git log&lt;/code>, o DAG é ordenado como uma lista unidimensional usando o algoritmo de Ordenação Topológica (Topological Sort). Para qualquer aresta direcionada $u \to v$ no DAG ($u$ é filho de $v$), ele é reorganizado para que $u$ venha antes de $v$ na lista.&lt;/p>
&lt;hr>
&lt;h1 id="4-mecanismos-e-tipos-de-git-merge">4. Mecanismos e tipos de git merge
&lt;/h1>&lt;p>O comando mais básico para integrar alterações de uma branch é o &lt;code>git merge&lt;/code>. No entanto, dependendo do estado atual, o Git escolhe automaticamente estratégias de merge diferentes.&lt;/p>
&lt;h2 id="41-merge-fast-forward---ff">4.1 Merge Fast-Forward (&amp;ndash;ff)
&lt;/h2>&lt;p>Se a branch de destino (ex: &lt;code>main&lt;/code>) for um ancestral direto da branch de origem (ex: &lt;code>feature&lt;/code>), o Git executará um merge &amp;ldquo;Fast-Forward&amp;rdquo; (avanço rápido). Esta operação não cria um novo commit; ela simplesmente avança o ponteiro da branch.&lt;/p>
&lt;pre class="mermaid">
gitGraph
commit id: &amp;#34;A&amp;#34;
commit id: &amp;#34;B&amp;#34;
branch feature
checkout feature
commit id: &amp;#34;C&amp;#34;
commit id: &amp;#34;D&amp;#34;
checkout main
merge feature
&lt;/pre>
&lt;p>Um merge Fast-Forward mantém o histórico em linha reta, mas tem a desvantagem de perder o contexto de &amp;ldquo;quais commits agrupavam o desenvolvimento de uma única funcionalidade (feature)&amp;rdquo;.&lt;/p>
&lt;h2 id="42-merge-non-fast-forward---no-ff">4.2 Merge Non-Fast-Forward (&amp;ndash;no-ff)
&lt;/h2>&lt;p>Ao especificar explicitamente &lt;code>git merge --no-ff&lt;/code>, o Git sempre criará um novo &amp;ldquo;commit de merge&amp;rdquo;, mesmo que um Fast-Forward seja possível. Um commit de merge é um commit especial que tem dois pais.&lt;/p>
&lt;pre class="mermaid">
gitGraph
commit id: &amp;#34;A&amp;#34;
commit id: &amp;#34;B&amp;#34;
branch feature
checkout feature
commit id: &amp;#34;C&amp;#34;
commit id: &amp;#34;D&amp;#34;
checkout main
commit id: &amp;#34;Trabalho Principal 1&amp;#34;
merge feature type: NORMAL
&lt;/pre>
&lt;p>A vantagem desse método é que a existência e a história da branch da funcionalidade permanecem claras no DAG. Se ocorrer um problema, é possível desfazer (reverter) com segurança a funcionalidade inteira de uma vez, executando &lt;code>git revert -m 1 &amp;lt;hash do commit de merge&amp;gt;&lt;/code>.&lt;/p>
&lt;h2 id="43-algoritmo-3-way-merge-merge-de-3-vias">4.3 Algoritmo 3-Way Merge (Merge de 3 vias)
&lt;/h2>&lt;p>Se a branch de destino e a branch de origem tiverem seus próprios commits independentes, o Git executará um merge de 3 vias. Neste caso, o Git explora o DAG e encontra o &amp;ldquo;ancestral comum mais baixo&amp;rdquo; (LCA - Lowest Common Ancestor) das duas branches.&lt;/p>
&lt;p>A complexidade computacional $T_{\text{LCA}}$ do algoritmo para encontrar o LCA pode ser executada em tempo linear em relação ao número de vértices $|V|$ e arestas $|E|$:&lt;/p>
$$
T_{\text{LCA}} = \mathcal{O}(|V| + |E|)
$$&lt;p>O Git compara três estados: o &amp;ldquo;estado do LCA&amp;rdquo;, o &amp;ldquo;estado da branch atual&amp;rdquo; e o &amp;ldquo;estado da outra branch&amp;rdquo;. Se as alterações não entrarem em conflito, ele gerará um commit de merge automaticamente.&lt;/p>
&lt;hr>
&lt;h1 id="5-mecanismo-do-git-rebase-e-reconstrução-do-histórico">5. Mecanismo do git rebase e reconstrução do histórico
&lt;/h1>&lt;p>Enquanto o &lt;code>git merge&lt;/code> &amp;ldquo;integra&amp;rdquo; o histórico, o &lt;code>git rebase&lt;/code> &amp;ldquo;reconstrói (reorganiza)&amp;rdquo; o histórico.&lt;/p>
&lt;h2 id="51-o-processo-por-trás-do-rebase">5.1 O processo por trás do Rebase
&lt;/h2>&lt;p>Quando você faz o rebase da branch &lt;code>feature&lt;/code> na branch &lt;code>main&lt;/code> (&lt;code>git rebase main&lt;/code>), as operações internas são as seguintes:&lt;/p>
&lt;ol>
&lt;li>Encontra o ancestral comum (LCA) entre a branch &lt;code>feature&lt;/code> e a branch &lt;code>main&lt;/code>.&lt;/li>
&lt;li>Salva as diferenças (diffs) dos commits, do LCA até o topo da branch &lt;code>feature&lt;/code>, em uma área temporária.&lt;/li>
&lt;li>Move o ponteiro da branch &lt;code>feature&lt;/code> para o topo da branch &lt;code>main&lt;/code>.&lt;/li>
&lt;li>Aplica sequencialmente (Cherry-Pick) as diferenças salvas na nova base (o topo da &lt;code>main&lt;/code>), criando novos commits um por um.&lt;/li>
&lt;/ol>
&lt;pre class="mermaid">
graph TD
A[&amp;#34;Commit A&amp;#34;] --&amp;gt; B[&amp;#34;Commit B&amp;#34;]
B --&amp;gt; C[&amp;#34;Commit C (Main)&amp;#34;]
B --&amp;gt; D[&amp;#34;Commit D (Feature Antigo)&amp;#34;]
D -.-&amp;gt; E[&amp;#34;Commit D&amp;#39; (Novo Feature)&amp;#34;]
C --&amp;gt; E
style D stroke-dasharray: 5 5, fill: #f9f9f9, color: #999
&lt;/pre>
&lt;p>O ponto crucial aqui é que o commit gerado pelo rebase, $D'$, tem um &lt;strong>commit pai diferente do commit original $D$, portanto, ele tem um valor de hash completamente diferente&lt;/strong> (consulte a definição da função de hash $H(C)$ mencionada anteriormente).&lt;/p>
&lt;h2 id="52-interactive-rebase-rebase-interativo">5.2 Interactive Rebase (Rebase Interativo)
&lt;/h2>&lt;p>Ao usar &lt;code>git rebase -i&lt;/code> (ou &lt;code>--interactive&lt;/code>), você pode manipular o histórico de commits como quiser. Esta é a ferramenta mais poderosa para organizar seu histórico local.&lt;/p>
&lt;ul>
&lt;li>&lt;code>pick&lt;/code>: Mantém o commit como está.&lt;/li>
&lt;li>&lt;code>reword&lt;/code>: Altera apenas a mensagem do commit.&lt;/li>
&lt;li>&lt;code>edit&lt;/code>: Pausa para modificar o conteúdo do commit.&lt;/li>
&lt;li>&lt;code>squash&lt;/code>: Funde este commit com o commit anterior, combinando também suas mensagens.&lt;/li>
&lt;li>&lt;code>fixup&lt;/code>: Semelhante ao &lt;code>squash&lt;/code>, mas descarta a mensagem deste commit.&lt;/li>
&lt;li>&lt;code>drop&lt;/code>: Remove o commit completamente.&lt;/li>
&lt;/ul>
&lt;p>Matematicamente, se uma branch tem $N$ commits, as variações de histórico linear (permutações) $P$ que podem ser geradas pela reordenação no rebase são:&lt;/p>
$$
P = N!
$$&lt;p>O Git dá aos desenvolvedores $N!$ opções, permitindo-lhes manter o histórico lógico e elegante.&lt;/p>
&lt;hr>
&lt;h1 id="6-a-regra-de-ouro-do-rebase-the-golden-rule-of-rebase">6. A Regra de Ouro do Rebase (The Golden Rule of Rebase)
&lt;/h1>&lt;p>Embora o &lt;code>rebase&lt;/code> seja muito poderoso, existe uma regra absoluta:&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;Nunca faça rebase em um histórico público compartilhado.&amp;rdquo;&lt;/strong>
&lt;em>(Never rebase public history)&lt;/em>&lt;/p>
&lt;/blockquote>
&lt;h2 id="61-por-que-você-não-deve-fazer-rebase-em-um-histórico-público">6.1 Por que você não deve fazer rebase em um histórico público?
&lt;/h2>&lt;p>O Git é distribuído. Os commits que você enviou para o &lt;code>origin/main&lt;/code> também foram clonados nos repositórios locais de outros desenvolvedores. Se você fizer rebase de commits já enviados, reescrever o histórico e sobrescrever à força com &lt;code>git push --force&lt;/code>, o que acontecerá?&lt;/p>
&lt;p>O DAG no repositório local de outros desenvolvedores divergiria fundamentalmente do DAG remoto. Quando outros desenvolvedores executarem &lt;code>git pull&lt;/code>, o Git tentará forçar o merge de grupos de commits com históricos diferentes, gerando um número massivo de conflitos e commits duplicados (mesmo conteúdo, mas hashes diferentes), deixando o repositório em pânico.&lt;/p>
&lt;p>O rebase só deve ser executado em &lt;strong>&amp;ldquo;branches locais que você ainda não compartilhou com ninguém&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;hr>
&lt;h1 id="7-resolução-de-conflitos-e-git-rebase---continue">7. Resolução de conflitos e git rebase &amp;ndash;continue
&lt;/h1>&lt;p>Se várias pessoas alterarem a mesma parte do mesmo arquivo, ocorrerá um conflito. O processo de resolução de conflitos é diferente entre &lt;code>merge&lt;/code> e &lt;code>rebase&lt;/code>.&lt;/p>
&lt;h2 id="71-resolução-de-conflitos-no-merge">7.1 Resolução de conflitos no Merge
&lt;/h2>&lt;p>Com o &lt;code>git merge&lt;/code>, a resolução de conflitos ocorre &lt;strong>apenas uma vez&lt;/strong>. Antes de criar o commit de merge final, você corrige todas as partes conflitantes de uma só vez.&lt;/p>
&lt;h2 id="72-resolução-de-conflitos-no-rebase">7.2 Resolução de conflitos no Rebase
&lt;/h2>&lt;p>Com o &lt;code>git rebase&lt;/code>, como os commits são reaplicados um por um, &lt;strong>podem ocorrer conflitos em cada commit&lt;/strong>.&lt;/p>
&lt;p>Se ocorrer um conflito durante um rebase, o Git irá pausar o processo. O fluxo de resolução é o seguinte:&lt;/p>
&lt;ol>
&lt;li>Abra seu editor ou IDE (como VS Code) e resolva manualmente os marcadores de conflito (&lt;code>&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/code>, &lt;code>======&lt;/code> e &lt;code>&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code>).&lt;/li>
&lt;li>Adicione os arquivos modificados ao índice:
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git add &amp;lt;arquivo_modificado&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;li>Retome o processo de rebase sem criar um novo commit:
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git rebase --continue
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;/ol>
&lt;p>Se você quiser cancelar o rebase e retornar ao estado original, execute o seguinte comando:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git rebase --abort
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>(&lt;em>Se a resolução do conflito não for necessária e você quiser pular aquele commit específico, use &lt;code>git rebase --skip&lt;/code>&lt;/em>)&lt;/p>
&lt;hr>
&lt;h1 id="8-uso-correto-na-prática-workflow-prático">8. Uso correto na prática (Workflow prático)
&lt;/h1>&lt;p>Então, como devemos escolher entre &lt;code>merge&lt;/code> e &lt;code>rebase&lt;/code> no desenvolvimento real? Aqui apresentamos a abordagem mais padrão e segura.&lt;/p>
&lt;h2 id="81-cenário-1-organizar-o-histórico-de-trabalho-local-uso-do-rebase">8.1 [Cenário 1] Organizar o histórico de trabalho local (Uso do Rebase)
&lt;/h2>&lt;p>Imagine que, ao desenvolver em uma branch de funcionalidade, muitos commits pequenos (&amp;ldquo;correção de erro de digitação&amp;rdquo;, &amp;ldquo;salvamento temporário&amp;rdquo;, etc.) se acumularam. Antes de abrir um Pull Request (PR), você usa o rebase interativo para organizá-los em unidades significativas.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Execute enquanto estiver na branch feature&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git rebase -i HEAD~5
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># (O editor será aberto. Use squash ou fixup para limpar o histórico)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Isso criará um histórico de commits limpo e fácil para os revisores entenderem sua intenção.&lt;/p>
&lt;h2 id="82-cenário-2-acompanhar-as-atualizações-da-branch-main-uso-do-rebase">8.2 [Cenário 2] Acompanhar as atualizações da branch main (Uso do Rebase)
&lt;/h2>&lt;p>Se o desenvolvimento demorar e alterações de outras pessoas continuarem sendo mescladas na branch &lt;code>main&lt;/code>, sua branch &lt;code>feature&lt;/code> ficará desatualizada. Neste caso, faça o rebase da sua branch &lt;code>feature&lt;/code> na branch &lt;code>main&lt;/code> mais recente.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Obtenha as informações mais recentes da main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git fetch origin
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Faça o rebase da branch feature na versão mais recente da main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git rebase origin/main
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Isso mantém o histórico linear e evita conflitos em merges futuros. Também evita a criação de commits de merge desnecessários (&amp;ldquo;Merge branch &amp;lsquo;main&amp;rsquo; into feature&amp;rdquo;).&lt;/p>
&lt;h2 id="83-cenário-3-integrar-uma-funcionalidade-concluída-uso-do-merge">8.3 [Cenário 3] Integrar uma funcionalidade concluída (Uso do Merge)
&lt;/h2>&lt;p>O desenvolvimento na branch &lt;code>feature&lt;/code> está concluído e é hora de integrá-lo à branch &lt;code>main&lt;/code>. Aqui, usamos &lt;strong>&lt;code>git merge --no-ff&lt;/code>&lt;/strong> (equivalente a escolher &amp;ldquo;Create a merge commit&amp;rdquo; em um Pull Request do GitHub).&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git checkout main
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git merge --no-ff feature -m &lt;span class="s2">&amp;#34;Merge feature: Implementação da funcionalidade de login de usuário&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git push origin main
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Isso deixa um ponto de conexão histórico (commit de merge) no DAG da branch &lt;code>main&lt;/code> dizendo que &amp;ldquo;uma funcionalidade foi mesclada aqui&amp;rdquo;. Ao olhar para o histórico mais tarde, será mais fácil rastrear o código por funcionalidade.&lt;/p>
&lt;hr>
&lt;h1 id="9-conclusão">9. Conclusão
&lt;/h1>&lt;p>Na operação do Git, as abordagens extremas de &amp;ldquo;fazer tudo com Merge&amp;rdquo; ou &amp;ldquo;manter tudo linear com Rebase&amp;rdquo; têm seus prós e contras.&lt;/p>
&lt;p>A melhor prática no mundo real é uma abordagem híbrida: &lt;strong>&amp;ldquo;organize o histórico privado local de forma elegante com rebase e deixe o contexto no histórico público de integração com merge &amp;ndash;no-ff&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Local (Espaço de trabalho pessoal)&lt;/strong>: Use o &lt;code>rebase&lt;/code> para eliminar commits desnecessários e acompanhar a linha principal mais recente para manter um histórico linear.&lt;/li>
&lt;li>&lt;strong>Global (Espaço de trabalho compartilhado)&lt;/strong>: Use &lt;code>merge --no-ff&lt;/code> para registrar a existência da branch de funcionalidade como um commit de merge no DAG, facilitando a reversão e o rastreamento.&lt;/li>
&lt;/ul>
&lt;p>Ao compreender a matemática e a arquitetura por trás da estrutura DAG e da função hash, os comandos Git passam da simples memorização para um &amp;ldquo;design de histórico intencional&amp;rdquo;. Seguindo a Regra de Ouro do Rebase, vamos selecionar os comandos adequados à situação e construir um histórico de commits limpo, legível e de fácil manutenção para toda a equipe.&lt;/p></description></item></channel></rss>