Keleto nepriklausomų pakeitimų suliejimas
(šis puslapis - viena iš LithuanianTutorial įvado dalių. Ankstesnė dalis - LithuanianTutorialExport, kita dalis - LithuanianTutorialConflict)
Jau mokame savo padarytais pakeitimais pasidalinti su kitais. Šiame skyrelyje pademonstruosime, kaip galima sulieti (Merge) pakeitimus, juos "ištraukiant" iš kitos saugyklos (Repository), kurioje atsirado nauja pakeitimų šaka. Tam naudojama komanda pull.
Visų pirma, tokiam suliejimui mums reikia kitos saugyklos. Taigi, dar kartą klonuokime mano-hello saugyklą.
$ cd .. $ hg clone mano-hello mano-hello-aprasymas updating working directory 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
hello.c failui suteiksime aprašymą, jį įterpdami tarp jau esančių komentarų.
$ cd mano-hello-aprasymas $ edit hello.c
Atsidariusiame teksto redaktoriuje pakeiskime antrą hello.c failo eilutę iš:
* hello.c
į tokią:
* hello.c - hello, world
Išsaugokime pakeitimą, uždarykime teksto redaktorių ir patvirtinkime mūsų pakeitimą. Šį kartą tai atliksime šiek tiek greičiau, nes su commit komanda naudosime -m parametrą, kad nebūtų atidaromas išorinio teksto redaktoriaus (Notepad) langas:
$ hg commit -m "Aprasymo iterpimas hello.c faile"
Dabar mano-hello-nauja-eilute saugyklos hello.c faile esame padarę vieną pakeitimą, o mano-hello-aprasymas saugyklos hello.c faile - kitokį pakeitimą. Kaip galėtume "sulieti" šias dvi atskiras pakeitimų šakas? Ar neiškils jokių problemų, jeigu norėsime iš vienos saugyklos pakeitimus pervesti į kitą?
Ne, tai veikia puikiai. Būdami mano-hello-aprasymas saugyklos kataloge, "ištraukime" pakeitimus iš saugyklos mano-hello-nauja-eilute (su komanda pull) ir pažiūrėkime, kas nutiks:
$ hg pull ../mano-hello-nauja-eilute pulling from ../mano-hello-nauja-eilute 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 praneša, kad į mūsų saugyklą įdėjo naują galvą (Head). Norėdami pamatyti saugyklos galvas, naudojame heads komandą:
$ hg heads changeset: 3:86794f718fb1 tag: tip parent: 1:82e55d328c8c user: mpm@selenic.com date: Mon May 05 01:20:46 2008 +0200 summary: Mokausi naudotis Mercurial ir man gerai sekasi changeset: 2:c3844fde99f0 user: mpm@selenic.com date: Tue May 06 20:10:35 2008 +0200 summary: Aprasymo iterpimas hello.c faile
Mercurial sistema turi naudingą plėtinį "GraphlogExtension", kuris gali parodyti saugyklos istorijos ASCII grafą (GraphlogExtension). Norint šiuo plėtiniu pasinaudoti, tereikia jį aktyvuoti Mercurial konfiguracijos faile (Windows: Mercurial.ini, Unix: ~/.hgrc), [extensions] skiltyje pridedant eilutę hgext.graphlog =:
[extensions] hgext.graphlog =
Jeigu tai padarėte, tuomet galėsite pasinaudoti papildoma komanda 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: Mokausi naudotis Mercurial ir man gerai sekasi | | @ changeset: 2:c3844fde99f0 |/ user: mpm@selenic.com | date: Tue May 06 20:10:35 2008 +0200 | summary: Aprasymo iterpimas hello.c faile | 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
Iš šio grafo matome, jog kątik į mūsų saugyklą įtraukėme pakeitimų rinkinį 86794f718fb1 (todėl dabar jis tapo viršūne). Kadangi abu pakeitimų rinkiniai – iš kitos saugyklos paimtas 86794f718fb1 ir mūsų "nuosavas" c3844fde99f0 - buvo sukurti iš to pačio pagrindo 82e55d328c8c ("tėvo"), buvo atsiskyrusi pakeitimų kryptis, taip pat dar vadinama "šaka" (Branch). Atkreipkite dėmesį, kad šiuo atveju atskira šaka gyvavo labai trumpai ir su Mercurial tokį išsišakojimą sulieti yra nesunku.
Žiūrėdami į pull komandos išvestas eilutes, galite pamanyti, jog jos jau buvo matytos anksčiau. Taigi tikriausiai paklaustumėte - kodėl gi dabar paprasčiausiai neatnaujinus darbinio katalogo failų su update komanda, kaip tai darėme vienos saugyklos pakeitimus taikydami kitai (LithuanianTutorialShareChange). Pabandykime ir žiūrėkime, kas atsitiks:
$ hg update abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes
Jau aišku, jog dabar čia kažkas yra kitaip. Tačiau, kaip matome, Mercurial sistema pati pasirūpina, kad nebūtų atlikta netinkama operacija. Taigi, jeigu kada nors po pull komandos įvykdymo ir nepastebėtume pranešimo "(+1 heads)", galime būti tikri, kad Mercurial mums primins, jog tokiu atveju turime atlikti kitokį veiksmą - sulieti pakeitimus su komanda merge.
Tačiau prieš padarydami pirmąjį mūsų suliejimą, pažiūrėkime, kuris pakeitimų rinkinys yra abiejų šakų pagrindas. Tam galime pasinaudoti parents komanda:
$ hg parents changeset: 2:c3844fde99f0 user: mpm@selenic.com date: Tue May 06 20:10:35 2008 +0200 summary: Aprasymo iterpimas hello.c faile
Iš to matome, kad darbinio katalogo (WorkingDirectory) turinys vis dar atitinka pakeitimų rinkinį c3844fde99f0 – taip ir turi būti, nes tai paskutinis mūsų patvirtintas rinkinys. Čia svarbu suprasti, jog iš kitos saugyklos įtrauktas pakeitimas buvo įdėtas į mūsų saugyklos istoriją, bet nepakeitė darbiniame kataloge esančių failų. Dar kartą pažvelkite į glog išvestas eilutes - vienas pakeitimų rinkinys yra pažymėtas "@" simboliu. Tai dabartinis darbinio katalogo tėvas (@c3844fde99f0).
Taigi, pagaliau pereikime prie pačio pakeitimų suliejimo. "Pakeitimų suliejimas" skamba kaip sudėtinga procedūra, ar ne? Iš tiesų, tai padaryti labai nesunku. Tiesiog vykdykime anksčiau atliktos pull komandos išvesties paskutinės eilutės nurodymus:
$ hg merge merging hello.c 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit)
Šati ir visas suliejimas! Mercurial galėjo automatiškai sulieti modifikuotus failus, nes juose padaryti pakeitimai buvo "nekonfliktiniai" - t.y. skirtingos pakeitimų šakos nemodifikavo tos pačios failo vietos (su "konfliktiniais" suliejimais susipažinsime skyrelyje LithuanianTutorialConflict). Jeigu dabar peržiūrėsime hello.c failą darbiniame kataloge, tai pamatysime, kad jame yra abu pakeitimai - tiek iš mano-hello-nauja-eilute, tiek iš mano-hello-aprasymas.
Dirbant su kitų žmonių padarytais pakeitimais, pagal dažnumą tokio tipo suliejimas turėtų būti antras. O dažniausiai viskas dar paprasčiau, ir atskirose pakeitimų šakose modifikuoti failai yra skirtingi. Taigi, daugumoje versijų suliejimo operacijų net nereikės sulieti jokių failų.
Dar nepatvirtinome mūsų naujo suliejimo. Prieš tą padarydami, pažiūrėkime, ką dabar mums parodys parents komanda (galime naudoti sutrumpinimą par):
$ hg par changeset: 2:c3844fde99f0 user: mpm@selenic.com date: Tue May 06 20:10:35 2008 +0200 summary: Aprasymo iterpimas hello.c faile changeset: 3:86794f718fb1 tag: tip parent: 1:82e55d328c8c user: mpm@selenic.com date: Mon May 05 01:20:46 2008 +0200 summary: Mokausi naudotis Mercurial ir man gerai sekasi
Tai mums pasako, kad darbinio katalogo failų pagrindą sudaro du pakeitimų rinkiniai – t.y. jis turi du tėvus. Atkreipkite dėmesį, kad šie du tėvai tarpusavyje turi eilės tvarką. Pirmasis tėvas (tėvas 1) yra mūsų ankstesnis pakeitimų rinkinys c3844fde99f0, kuriame mes į hello.c failą įdėjome aprašymą. merge komandos iškvietimo metu šis pakeitimų rinkinys buvo tuometinis tėvas. Antrasis tėvas (tėvas 2) - tai pakeitimų rinkinys 86794f718fb1, kurį mes įtraukėme iš kitos saugyklos, ir kurio pakeitimus suliejome su pirmojo tėvo pakeitimais.
Dabar glog komanda @ simboliu pažymi du tėvus:
$ hg glog @ changeset: 3:86794f718fb1 | tag: tip | parent: 1:82e55d328c8c | user: mpm@selenic.com | date: Mon May 05 01:20:46 2008 +0200 | summary: Mokausi naudotis Mercurial ir man gerai sekasi | | @ changeset: 2:c3844fde99f0 |/ user: mpm@selenic.com | date: Tue May 06 20:10:35 2008 +0200 | summary: Aprasymo iterpimas hello.c faile | 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
Jeigu persigalvoję ir norėdami panaikinti šį suliejimą, prieš patvirtindami naują pakeitimų rinkinį, atminkite, jog tam NEUŽTEKS tik hg revert -r2 --all komandos, nes ją įvykdžius iki antros revizijos (nr. 2) bus atstatytas tik darbinio katalogo failų turinys, tačiau darbinio katalogo tėvai nebus pakeisti (vistiek liks du tėvai vietoj vieno. Šiuo atveju, kad visiškai panaikintumėte suliejimą, turite naudoti komandą "hg update -C -r.".
Kad sėkmingai pabaigtume visą suliejimo procedūrą, turime nepamiršti patvirtinti šiuos vietinius pakeitimus (LocalModifications) - būtent tai mums siūlė paskutinė merge komandos išvesta eilutė:
$ hg commit -m "Sulieti pakeitimai is mano-hello-nauja-eilute"
Ši komanda neturėtų turėtų nieko neišvesti. Dabar suliejimas yra įrašytas į saugyklos atmintį kaip naujas "sulietas" pakeitimų rinkinys (MergeChangeset) ir jį galime panagrinėti su glog komanda:
$ 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: Sulieti pakeitimai is mano-hello-nauja-eilute | | | o changeset: 3:86794f718fb1 | | parent: 1:82e55d328c8c | | user: mpm@selenic.com | | date: Mon May 05 01:20:46 2008 +0200 | | summary: Mokausi naudotis Mercurial ir man gerai sekasi | | o | changeset: 2:c3844fde99f0 |/ user: mpm@selenic.com | date: Tue May 06 20:10:35 2008 +0200 | summary: Aprasymo iterpimas hello.c faile | 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
Norėdami detaliau peržiūrėti suliejimo operacijos padarytus pakeitimus, galime pasinaudoti annotate komanda, kuri pažymi atskiras pakeitimų rinkinyje modifikuotas failo eilutes. Nepamirškime, kad revizija nr. 2 - tai mano-hello-aprasymas saugykloje padarytas pakeitimas, o revizija nr. 3 - tai pakeitimų iš mano-hello-nauja-eilute saugyklos įtraukimas ir suliejimas su mano-hello-aprasymas saugyklos pakeitimais.
$ 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("Man patinka naudotis Mercurial!\n"); 0: return 0; 0: }
Kitame LithuanianTutorialConflict skyrelyje sužinosite, kaip sulieti failus, kai juose padaryti pakeitimai yra konfliktiniai.