Да бисмо заиста разумели како програм Гит барата гранањем, морамо да се вратимо корак уназад и да истражимо како програм Гит чува податке.
Као што се можда сећате из ch01-getting-started.asc, програм Гит не чува податке као низ скупова промена или разлика, већ као низ снимака.
Када направите комит, program Гит чува комит објекат који садржи показивач на снимак садржаја који сте стејџовали. Овај објекат такође садржи и ауторово име и мејл адресу, поруку која је унесена, као и показиваче на комит или комитове који су директно претходили овом комиту (тј. његовог родитеља или родитеље): нула родитеља за почетни комит, једног родитеља за нормални комит, и више родитеља за комит који је резултат спајања две или више грана.
Да бисмо ово сликовито приказали, претпоставимо да имате директоријум који садржи три фајла и да их све стејџујете, а затим комитујете. Стејџовање фајлова рачуна контролну суму сваког од њих (SHA-1 хеш као што смо поменули у ch01-getting-started.asc), чува ту верзију фајла у Гит репозиторијум (програм Гит то назива блобовима) и додаје ту контролну суму на стејџ:
$ git add README test.rb LICENSE
$ git commit -m 'Initial commit'Када са git commit направите комит, програм Гит прави контролну суму сваког поддиректоријума (у овом случају, само корени директоријум пројекта) и чува их у Гит репозиторијум као стабло.
Програм Гит онда креира комит објекат који има метаподатке и показивач на корен стабла пројекта тако да поново може креирати тај снимак онда када буде био потребан.
Ваш Гит репозиторијум сада садржи пет објеката: три блоба (од којих сваки представља садржај једног од три фајла), једно стабло које садржи листу садржаја директоријума и наводи која имена фајлова се чувају у ком блобу, као и један комит са показивачем на тај корен стабла и све комит метаподатке.
Ако направите неке измене и комитујете поново, следећи комит чува показивач на комит који је дошао непосредно пре њега.
Грана у програму Гит је просто један мали покретни показивач на неки од ових комитова.
Подразумевано име гране у програму Гит је master.
Када почнете да комитујете, даје вам се master грана која показује на последњи комит који сте направили.
Сваки пут када комитујете, показивач master гране се аутоматски креће унапред.
|
Note
|
„master” грана у програму Гит није посебна грана.
Она је потпуно иста као и свака друга грана.
Једини разлог због којег скоро сваки репозиторијум има такву грану је то што је команда |
Шта се дешава када направите нову грану?
Па, када то урадите, креира се нови показивач којим се крећете унаоколо.
Рецимо да направите нову грану коју ћете назвати testing.
То се ради командом git branch:
$ git branch testingОво прави нови показивач на исти комит на којем се тренутно налазите.
Како програм Гит зна на којој грани се тренутно налазите?
Он чува посебан показивач који се зове HEAD.
Обратите пажњу на то да је ово много другачије од HEAD концепта у осталим VCS системима на које сте можда навикли, као што су Subversion или CVS.
У програму Гит, ово је показивач на локалну грану на којој се тренутно налазите.
У овом случају, још увек сте на master грани.
Командом git branch сте само направили нову грану — нисте прешли на њу.
Ово лако можете да видите тако што ћете извршити обичну git log команду која вам приказује на шта показују показивачи грана.
Ова опција се зове --decorate.
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) add feature #32 - ability to add new formats to the central interface
34ac2 Fixed bug #1328 - stack overflow under certain conditions
98ca9 Initial commitВидите да су master и testing гране одмах поред комита f30ab.
Када желите да пређете на неку постојећу грану, извршавате команду git checkout.
Хајде да пређемо на нову грану testing:
$ git checkout testingОво помера показивач HEAD тако да показује на грану testing.
Зашто је ово битно? Па, хајде да урадимо још један комит:
$ vim test.rb
$ git commit -a -m 'made a change'Ово је занимљиво, јер се сада testing грана померила унапред, али ваша master грана још увек показује на комит на коме сте били када сте извршили git checkout да промените гране.
Хајде да се вратимо назад на грану master:
$ git checkout master|
Note
|
git log не приказује све гране све времеАко бисте сада извршили Грана није нестала; програм Git једноставно не зна да вас та грана интересује и покушава да вам прикаже оно што мисли да вас интересује.
Другим речима, команда Ако желите да видите историју комитова неке гране, морате експлицитно да је наведете: |
Ова команда је урадила две ствари.
Померила је показивач HEAD назад на место у грани master и вратила је фајлове у радном директоријуму на снимак на који показује master.
Ово такође значи и да ће се промене које правите одсад па надаље одвојити од старије верзије пројекта.
Команда у суштини премотава уназад, поништавајући рад у testing грани, како бисте могли да кренете другим путем.
|
Note
|
Мењање грана мења фајлове у радном директоријуму
Када у програму Гит прелазите с гране на грану, важно је приметити да ће се фајлови у радном директоријуму променити. Ако се пребаците на старију грану, радни директоријум ће се вратити на изглед који је имао у време када сте комитовали на тој грани. Ако програм Гит није у стању да то уради без проблема, уопште вам неће дозволити се пребаците. |
Хајде да направимо неколико промена и поново комитујемо:
$ vim test.rb
$ git commit -a -m 'made other changes'Сада се историја вашег пројекта раздвојила (погледајте Раздвојена историја).
Направили сте грану, пребацили сте се на њу, урадили нешто у њој, и онда се вратили назад на главну грану и урадили још мало посла.
Обе ове промене су изоловане у посебним гранама: можете да скачете с једне на другу напред-назад и да их спојите онда када будете спремни.
И све сте то урадили простим командама branch, checkout и commit.
Ово лако можете видети и са git log командом.
Ако извршите git log --oneline --decorate --graph --all, исписаће вам се историја комитова, показујући вам где се сада налазе показивачи на гране и како се историја раздвајала.
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 Initial commitПошто је грана у програму Гит заправо једноставан фајл који садржи 40 карактера SHA-1 контролне суме комита на који показује комит, прављење и уништавање грана је јефтино. Креирање нове грану је брзо и једноставно колико и уписивање 41 бајта у фајл (40 карактера и карактер за прелом линије).
Ово је у оштром контрасту са начином на који гранање ради већина старијих VCS алата, који подразумева копирање свих фајлова пројекта у други директоријум. Ово може потрајати неколико секунди или чак минута, у зависности од величине пројекта, док је у програму Гит тај процес увек тренутан. Такође, пошто бележимо родитеље када комитујемо, проналажење одговарајуће базе за спајање се аутоматски одради уместо да се ми бавимо тиме и у општем случају је тај процес веома једноставан. Ове особине подстичу програмере да често праве и користе гране.
Хајде да погледамо зашто и ви треба то да радите.
|
Note
|
Креирање нове гране и истовремени прелаз на њу
Врло је чест случај да желите креирати нову грану и да се одмах пребаците у њу — то можете обавити у једном кораку командом |
|
Note
|
Почевши од програма Гит верзије 2.23 па надаље уместо
|








