Acrescenta um índice com outras páginas.
[cursogit.git] / Merge.mdwn
index 3c5c709..09639f8 100644 (file)
@@ -87,9 +87,63 @@ quando não se deve reescrevê-la.
 
 ## Fast-foward
 
+Quando realizamos um push em um repositório, enviamos nossas
+atualizações. No entanto, existe uma condição para que o Git aceite esta
+atualização sem emitir um aviso. O novo commit enviado deve conter todos
+os commits já presentes no branch sendo atualizado. Significa que o novo
+commit deve ter o velho commit como ancestral em seu grafo de histórico.
+
+No exemplo anterior em que fizemos o amend, tanto o branch amend quanto
+o branch devel não têm o branch master como ancestral. Isto significa
+que a atualização do branch master para um destes commits não avançaria
+o histórico. Não seria o que chamamos de fast-forward.
+
+Fazer uma atualização que não é fast-forward seria como apagar o
+histórico que já ocorreu. Substituir um ramo por outro. É o que muitos
+chamam de fork. Fazer fork utilizando diferentes repositórios por
+diferentes pessoas, ou diferentes branches com o propósito de realizar
+merges é saudável pra uma comunidade. É o que permite o envolvimento de
+mais pessoas em um projeto, e a experimentação. Mas substituir um mesmo
+branch público por algo que apaga parte de seu histórico pode introduzir
+vários problemas no fluxo de trabalho de uma comunidade, como merges
+duplicados e desnecessários, reescritas de histórico em toda a cadeia de
+branches e forks, criando um efeito cascata.
+
+Portanto, não publique branches que não pretenda manter de forma
+fast-forward, a não ser que fique claro no workflow como aquele branch
+será consumido em outro branch fast-forward, ou deixando claro que o
+branch será reescrito, e não deve ser utilizado como base a não ser que
+o contribuidor esteja preparado para lidar com as reescritas.
+
+Na prática, fast-forward facilita a leitura do histórico, evita
+problemas com push e merges, e facilita reescrita de históricos, nas
+situações em que estes devem ser feitos, em branches ainda não
+publicados.
+
 ## Merge
 
-Integração de código e histórico.
+Como podemos, então, produzir um commit fast-forward que integre o
+trabalho feito no branch devel? É possível criar um commit que seja
+fast-forward tanto do branch master quanto do branch devel? Ou de
+quaisquer dois commits?
+
+Lembre-se que dissemos que um commit pode ter um ou mais genitores. Se
+pudermos criar um commit que tenha os dois commits apontados pelos
+branches master e devel como genitores, teremos um commit que permite
+fast-forward para ambos.
+
+Esse é um dos papéis do merge. O comando git merge permite criar um
+commit com mais de um genitor. Mas ele faz mais que isso. Ele combina as
+árvores de arquivos dos commits que farão parte do merge. A estratégia
+utilizada para fazê-lo pode ser configurada e o padrão depende de
+quantos commits fazem parte do merge. No caso comum, dois commits fazem
+parte do merge, e a estratégia de combinar as duas árvores é um 3-way
+merge recursivo, que compara as árvores dos dois commits com um
+ancestral comum, e aplica as mudanças encontradas em ambas as árvores
+dos dois commits.
+
+O resultado é um novo commit com dois genitores, e uma árvore com
+mudanças realizadas nos dois branches.
 
        ~/project$ git merge devel
        Faz o merge de testes.