Utilizando git fetch e git remote update.
[cursogit.git] / Merge.mdwn
1 # Merge
2
3 Branches permitem experimentar com o repositório, e separar o
4 desenvolvimento de novas funcionalidades e correções. Também permite que
5 várias pessoas trabalhem no mesmo projeto, através de branches remotos.
6
7 Em algum momento, os vários branches devem ser reunidos em uma nova
8 versão. Há várias formas de fazê-lo. Uma das ferramentas que o permite é
9 o merge. Mas antes, revisaremos e veremos alguns conceitos.
10
11 ## Branches
12
13 Discutimos como criar branches na seção [[Branches]] e como obter
14 branches remotos na seção [[Remotes]]. Vejamos, no entanto, porque levam
15 esse nome.
16
17 A imagem abaixo mostra um repositório com poucos commits. Com exceção do
18 primeiro commit, todos os commits em Git possuem um ou mais genitores.
19 Isso faz com que a relação entre os commits constitua um grafo acíclico
20 dirigido, uma estrutura similar àquela associada a uma árvore
21 genealógica.
22
23 O exemplo abaixo mostra commits com apenas um genitor. Note, no entanto,
24 que há um ramo, representado pelo branch devel. Isto é o que chamamos de
25 histórico não-linear. Há formas de linearizar históricos e veremos mais
26 adiante as razões para fazê-lo, quando não fazê-lo, e como fazê-lo.
27
28 [[!img branches.png]]
29
30 ## Commit IDs
31
32 Vimos em [[Git_log]] que um commit é identificado por um ID. Este ID é
33 um hash SHA-1 do objeto do commit. O objeto é composto pelo log, autor,
34 data, a árvore de arquivos, outros metadados, e a lista de genitores.
35 Dada a natureza de um hash criptográfico como SHA-1, pequenas mudanças
36 no commit, seja no sumário, em algum arquivo, genitor, ou outros, causa
37 uma mudança no commit ID.
38
39 Vejamos como alterar um commit usando a opção --amend do comando git
40 commit. Para tanto, criaremos um novo branch a partir do master e
41 alteraremos nosso novo HEAD.
42
43         ~/project$ git checkout -b amend master
44         Switched to a new branch 'amend'
45         ~/project$ 
46
47 Veja como fica o nosso grafo após o novo branch ser criado na imagem
48 abaixo. Note que o grafo continua o mesmo e o branch amend é apenas uma
49 referência ao mesmo commit ao qual o branch master se refere.
50
51 [[!img branch.png]]
52
53 Neste exemplo, alteramos apenas a mensagem de log, usando a opção
54 --amend.
55
56         ~/project$ git commit --amend
57         [amend 571a638] Acrescenta lista de arquivos a serem ignorados.
58          1 file changed, 2 insertions(+)
59          create mode 100644 .gitignore
60         ~/project$ 
61
62 Note o resultado na figura abaixo. O commit foi alterado, mudando seu
63 ID. Ele ainda aponta para o mesmo genitor, mas é um commit diferente
64 daquele referenciado pelo branch master.
65
66 [[!img amend.png]]
67
68 ## Histórico
69
70 A sequência de commits que vemos em um branch é também chamada de
71 histórico. Como é utilizado um hash criptográfico e um link entre os
72 commits utilizando o ID, e esse faz parte do conteúdo criptografado, não
73 é possível alterar este histórico.
74
75 Quando alteramos um commit, como feito acima, o histórico original é
76 mantido enquanto ainda existir alguma referência a ele, através de
77 branches, por exemplo. Se algum commit tiver o commit alterado como seu
78 genitor, sua referência ainda será ao commit genitor original, não à
79 nova versão do commit. Sendo assim, para aproveitar os commits já
80 realizados, é necessário reescrevê-los para que apontem, em cadeia, às
81 novas versões dos commits reescritos. Isso se chama reescrevendo a
82 história, e pode ser feito com o comando git rebase, entre outros
83 comandos.
84
85 Veremos mais logo quando e como reescrever a história. Agora, veremos
86 quando não se deve reescrevê-la.
87
88 ## Fast-foward
89
90 ## Merge
91
92 Integração de código e histórico.
93
94         ~/project$ git merge devel
95         Faz o merge de testes.
96         Merge made by the 'recursive' strategy.
97          Makefile | 3 +++
98          1 file changed, 3 insertions(+)
99         ~/project$ 
100
101 [[!img merge.png]]