== Tutoriál 8 - Slučování změn ==

''Předchozí kapitolou [[CzechTutorial|Tutoriálu]] je [[CzechTutorialExport|Export změny do souboru]], následující je  [[CzechTutorialConflict|Řešení konfliktu]]''

V předchozí kapitole jsme se dozvěděli, jak sdílet změny prostřednictvím emailu s jinou osobou.  V této části si ukážeme slučování ([[Merge|merge]]) změn, stažených příkazem {{{pull}}} z jiného [[Repository|repozitáře]]. 

Nejprve si musíme vytvořit něco, co bychom mohli slučovat. Proveďme si další klon adresáře `moje-halo`:

{{{
> cd ..
> hg clone moje-halo moje-halo-desc
updating working directory
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
}}}

Do souboru `hello.c` doplníme popisný text.

{{{
> cd moje-halo-desc
> notepad++ hello.c
}}}

Změňme druhý řádek:

{{{
 * hello.c
}}}

na:

{{{
 * hello.c - hello, world
}}}

Změnu uložíme, zavřeme editor a změnu [[Cmd:commit|komitujeme]].  Tentokrát to provedeme s volbou `-m` k příkazu `commit`, čímž vypustíme ze hry editor: 

{{{
$ hg commit -m "Doplněn popis hello.c"
}}}

V tomto okamžiku máme jednu změnu souboru `hello.c` v adresáři `moje-halo-output` a druhou změnu v adresáři `moje-halo-desc`.
Jak "sloučíme" tyto dvě odlišné linie vývoje?  Vznikne nějaký problém, když se pokusíme stáhnout (pull) jednu do druhé?

Se samotným stažením nebude problém.  Jsa stále v `moje-halo-desc`, proveďme stažení změn z `moje-halo-output` a hleďme, co se stane:

{{{
> hg pull ../moje-halo-output
pulling from ../moje-halo-output
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
}}}

Mercurial nám říká, že přidal další čelo ([[Head|head]])  do našeho repozitáře. Také nás nabádá, abychom si je prohlédli a abychom provedli sloučení:

{{{
> hg heads
changeset:   3:86794f718fb1
tag:         tip
parent:      1:82e55d328c8c
user:        mpm@selenic.com
date:        Mon May 05 01:20:46 2008 +0200
summary:     Ať žije DVCS Hg Merkuriál!

changeset:   2:c3844fde99f0
user:        mpm@selenic.com
date:        Tue May 06 20:10:35 2008 +0200
summary:     Doplněn popis hello.c
}}}

Součástí Mercurialu je pěkné rozšíření ([[UsingExtensions|extension]]) které umí zobrazit graf historie repozitáře ve formátu ASCII: [[GraphlogExtension]]. Nastavení této extenze se provede tak, že se povolí v konfiguračním souboru `~/.hgrc` (nebo `Mercurial.ini` ve Windows) nebo přídá řádek `hgext.graphlog =` v sekci `[extensions]`:

{{{
[extensions]
hgext.graphlog =  # případně jen graphlog =
}}}

Pokud jsme si extenzi aktivovali, máme přístupný další příkaz `glog` (viz také `hg help glog`):

{{{
> hg glog
o  changeset:   3:86794f718fb1
|  tag:         tip
|  parent:      1:82e55d328c8c
|  user:        mpm@selenic.com
|  date:        Mon May 05 01:20:46 2008 +0200
|  summary:     Ať žije DVCS Hg Merkuriál!
|
| @  changeset:   2:c3844fde99f0
|/   user:        mpm@selenic.com
|    date:        Tue May 06 20:10:35 2008 +0200
|    summary:     Doplněn popis hello.c
|
o  changeset:   1:82e55d328c8c
|  user:        mpm@selenic.com
|  date:        Fri Aug 26 01:21:28 2005 -0700
|  summary:     Create a makefile
|
o  changeset:   0:0a04b987be5a
   user:        mpm@selenic.com
   date:        Fri Aug 26 01:20:50 2005 -0700
   summary:     Create a standard "hello, world" program
}}}

Na grafu vidíme, že stáhnutý changeset `86794f718fb1` se stal novým tipem. Protože oba poslední changesety byly odvozeny od stejného rodiče (changeset `82e55d328c8c`), vytváří se nám větvení ([[Branch|branch]]), s nímž si v tomto případě Mercurial snadno poradí.
 
Další příkaz, který máme provést je `merge`. Nemohli bychom provést `update` jako jsme to udělali v lekci [[CzechTutorialShareChange|Sdílení změn ...]]? Zkusme to a uvidíme, co to udělá:

{{{
> hg update
abort: crosses branches (use 'hg merge' or 'hg update -C')
}}}

Jak vidíme, Mercurial odmítá provést něco, co se v této chvíli provést nemá.

Než však provedeme svůj první "merge", zkontrolujme si, na který changeset jsme aktuálně napojeni. Provedeme to příkazem `parents`:

{{{
> hg parents
changeset:   2:c3844fde99f0
user:        mpm@selenic.com
date:        Tue May 06 20:10:35 2008 +0200
summary:     Doplněn popis hello.c
}}}

Říká se nám, že obsah [[WorkingDirectory|pracovního adresáře]] je stále synchronizován s revizí `2:c3844fde99f0` – což je změna, kterou jsme komitovali naposledy . Je důležité vědět, že příkaz "pull", který jsme právě provedli, pouze přetáhl tu další změnu do složky /store/data/  našeho repozitáře. Nic jiného v našem pracovním adresáři nezměnil.

Rovněž si všimneme, že na výstupu příkazu `glog` je jeden changeset označen zavináčem "`@`". Takto je označen aktuální changeset pracovního adresáře.

Nyní tedy přikročíme k vlastnímu slučování. Provedeme pokyn z výstupu našeho posledního "pull":

{{{
> hg merge
merging hello.c
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
}}}

A je to! Mercurial provedl sloučení bez našeho zásahu protože slučované části nebyly konfliktní (sloučení s konfliktem si probereme v [[TutorialConflict|Řešení konfliktu]]). Prohlédneme-li si soubor `hello.c`, zjistíme, že obsahuje části jak z `moje-halo-output`, tak z `moje-halo-desc`.

Zatím jsme neprovedli commit, jak jsme byli žádáni. Než tak učiníme, podívejme se, co nám nyní prozradí příkaz `parents` (použijeme zkratku  `par`):

{{{
> hg par
changeset:   2:c3844fde99f0
user:        mpm@selenic.com
date:        Tue May 06 20:10:35 2008 +0200
summary:     Doplněn popis hello hello.c

changeset:   3:86794f718fb1
tag:         tip
parent:      1:82e55d328c8c
user:        mpm@selenic.com
date:        Mon May 05 01:20:46 2008 +0200
summary:     Ať žije DVCS Hg Merkuriál!
}}}

Výstup z příkazu nám říká, že pracovní adresář je založen na dvou rodičovských changesetech.

Potvrdí nám to výstup z příkazu `glog`, kde budou oba rodiče označeni zavináčem `@`:

{{{
$ hg glog
@  changeset:   3:86794f718fb1
|  tag:         tip
|  parent:      1:82e55d328c8c
|  user:        mpm@selenic.com
|  date:        Mon May 05 01:20:46 2008 +0200
|  summary:     Express great joy at existence of Mercurial
|
| @  changeset:   2:c3844fde99f0
|/   user:        mpm@selenic.com
|    date:        Tue May 06 20:10:35 2008 +0200
|    summary:     Add description of hello.c
|
o  changeset:   1:82e55d328c8c
|  user:        mpm@selenic.com
|  date:        Fri Aug 26 01:21:28 2005 -0700
|  summary:     Create a makefile
|
o  changeset:   0:0a04b987be5a
   user:        mpm@selenic.com
   date:        Fri Aug 26 01:20:50 2005 -0700
   summary:     Create a standard "hello, world" program
}}}

/!\ Zapamatujme si, že sloučení nestvrzené  příkazem `commit` lze ještě zrušit příkazem `hg revert -r2 --all`, což vrátí stav souborů v pracovním adresáři zpět k revizi 2 ale __nezredukuje počet rodičů pracovního adresáře na jednoho__.

Celou slučovací proceduru ukončíme, jak nám bylo napovězeno výstupem z  posledního příkazu `merge`:

{{{
> hg commit -m "Sloučené změny z moje-halo-output"
}}}

Provedení tohoto příkazu je bez výstupu. Sloučení je ale zapsáno v repozitáři jako nový slučovací changeset ([[MergeChangeset|merge changeset]]), který můžeme prozkoumat příkazem `glog`:

{{{
> hg glog
@    changeset:   4:d2ecac0134d8
|\   tag:         tip
| |  parent:      2:c3844fde99f0
| |  parent:      3:86794f718fb1
| |  user:        mpm@selenic.com
| |  date:        Tue May 06 23:44:19 2008 +0200
| |  summary:     Sloučené změny z mojeHalo-output
| |
| o  changeset:   3:86794f718fb1
| |  parent:      1:82e55d328c8c
| |  user:        mpm@selenic.com
| |  date:        Mon May 05 01:20:46 2008 +0200
| |  summary:     Ať žije DVCS Hg Merkuriál!
| |
o |  changeset:   2:c3844fde99f0
|/   user:        mpm@selenic.com
|    date:        Tue May 06 20:10:35 2008 +0200
|    summary:     Doplněn popis hello.c
|
o  changeset:   1:82e55d328c8c
|  user:        mpm@selenic.com
|  date:        Fri Aug 26 01:21:28 2005 -0700
|  summary:     Create a makefile
|
o  changeset:   0:0a04b987be5a
   user:        mpm@selenic.com
   date:        Fri Aug 26 01:20:50 2005 -0700
   summary:     Create a standard "hello, world" program
}}}

Pro zobrazení změn v našem souboru můžeme také použít příkaz `annotate`, který nám ukáže text souboru řádek po řádku:

{{{
$ hg annotate hello.c
0: /*
2:  * hello.c - hello, world
0:  *
0:  * Placed in the public domain by Bryan O'Sullivan
0:  *
0:  * This program is not covered by patents in the United States or other
0:  * countries.
0:  */
0:
0: #include <stdio.h>
0:
0: int main(int argc, char **argv)
0: {
0:      printf("hello, world!\n");
3:      printf("to jsem rád, že mám Merkuriál!\n");
0:      return 0;
0: }
}}}

Řešení [[Conflict|konfliktních]] změn při slučování poznáme v další kapitole 
[[CzechTutorialConflict|Řešení konfliktu]].

----
CategoryCzech