-
1. Почетак
- 1.1 О контроли верзије
- 1.2 Кратка историја програма Гит
- 1.3 Шта је Гит?
- 1.4 Командна линија
- 1.5 Инсталирање програма Гит
- 1.6 Подешавања за први пут
- 1.7 Тражење помоћи
- 1.8 Резиме
-
2. Основе програма Гит
- 2.1 Прављење Гит репозиторијума
- 2.2 Снимање промена над репозиторијумом
- 2.3 Преглед историје комитова
- 2.4 Опозив
- 2.5 Рад са удаљеним репозиторијумима
- 2.6 Означавање
- 2.7 Гит алијаси
- 2.8 Резиме
-
3. Гранање у програму Гит
- 3.1 Укратко о гранању
- 3.2 Основе гранања и спајања
- 3.3 Управљање гранама
- 3.4 Процеси рада са гранањем
- 3.5 Удаљене гране
- 3.6 Ребазирање
- 3.7 Резиме
-
4. Гит на серверу
- 4.1 Протоколи
- 4.2 Постављање програма Гит на сервер
- 4.3 Генерисање јавног SSH кључа
- 4.4 Подешавање сервера
- 4.5 Гит демон
- 4.6 Паметан HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Опције за хостовање које нуде трећа лица
- 4.10 Резиме
-
5. Дистрибуирани Гит
-
6. GitHub
-
7. Гит алати
- 7.1 Избор ревизија
- 7.2 Интерактивно стејџовање
- 7.3 Скривање и чишћење
- 7.4 Потписивање вашег рада
- 7.5 Претрага
- 7.6 Поновно исписивање историје
- 7.7 Демистификовани ресет
- 7.8 Напредно спајање
- 7.9 Rerere
- 7.10 Отклањање грешака са програмом Git
- 7.11 Подмодули
- 7.12 Паковање
- 7.13 Замена
- 7.14 Складиште акредитива
- 7.15 Резиме
-
8. Прилагођавање програма Гит
- 8.1 Конфигурисање програма Гит
- 8.2 Гит атрибути
- 8.3 Гит куке
- 8.4 Пример полисе коју спроводи програм Гит
- 8.5 Резиме
-
9. Гит и остали системи
- 9.1 Гит као клијент
- 9.2 Мигрирање на Гит
- 9.3 Резиме
-
10. Гит изнутра
- 10.1 Водовод и порцелан
- 10.2 Гит објекти
- 10.3 Гит референце
- 10.4 Pack фајлови
- 10.5 Рефспек
- 10.6 Протоколи за пренос
- 10.7 Одржавање и опоравак податак
- 10.8 Променљиве окружења
- 10.9 Резиме
-
A1. Додатак А: Програм Гит у другим окружењима
- A1.1 Графички интерфејси
- A1.2 Гит у Visual Studio
- A1.3 Гит у Visual Studio Code
- A1.4 Гит у IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Гит у Sublime Text
- A1.6 Гит унутар Bash
- A1.7 Гит у Zsh
- A1.8 Гит у Powershell
- A1.9 Резиме
-
A2. Додатак Б: Уграђивање програма Гит у ваше апликације
- A2.1 Гит из командне линије
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Додатак В: Гит команде
- A3.1 Подешавање и конфигурација
- A3.2 Набављање и креирање пројеката
- A3.3 Основно снимање
- A3.4 Гранање и спајање
- A3.5 Дељење и ажурирање пројеката
- A3.6 Инспекција и поређење
- A3.7 Отклањање грешака
- A3.8 Крпљење
- A3.9 Имејл
- A3.10 Спољни системи
- A3.11 Администрација
- A3.12 Водоводне команде
7.1 Гит алати - Избор ревизија
До сада сте научили већину команди које се свакодневно користе, процесе рада који су вам потребни за управљање или одржавање Гит репозиторијума за контролу вашег изворног кода. Успешно сте завршили основне задатке праћења и комитовања фајлова и укротили сте снагу стејџа и једноставног тематског гранања и спајања.
Сада ћете истражити више веома моћних ствари које програм Гит може да уради, а које вероватно нећете свакодневно користити. Али у неком тренутку ће вам бити потребне.
Избор ревизија
Програм Гит вам омогућава да на неколико начина наведете одређене комитове или опсег комитова. Они нису обавезно очигледни, али је добро да се познају.
Просте ревизије
Један комит очигледно можете да наведете његовом пуном SHA-1 контролном сумом дужине 40 карактера, али такође постоје и начини навођења комитова који су лакши за људе. Овај одељак представља различите начине на које можете навести један комит.
Кратак SHA-1
Програм Гит је довољно паметан да одреди на који комит мислите када откуцате неколико првих карактера, све док је делимичан SHA-1 дужине барем четири карактера и није двосмислен – то јест, само један објекат у текућем репозиторијуму почиње тим делимичним SHA-1.
На пример, ако желите да погледате један комит, претпоставимо да извршите команду git log
и пронађете комит у којем сте додали одређену функционалност:
$ git log
commit 734713bc047d87bf7eac9674765ae793478c50d3
Author: Scott Chacon <schacon@gmail.com>
Date: Fri Jan 2 18:32:33 2009 -0800
Fix refs handling, add gc auto, update tests
commit d921970aadf03b3cf0e71becdaab3147ba71cdef
Merge: 1c002dd... 35cfb2b...
Author: Scott Chacon <schacon@gmail.com>
Date: Thu Dec 11 15:08:43 2008 -0800
Merge commit 'phedders/rdocs'
commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b
Author: Scott Chacon <schacon@gmail.com>
Date: Thu Dec 11 14:58:32 2008 -0800
Add some blame and merge stuff
У овом случају, рецимо да се заинтересовани за комит чији хеш почиње са 1c002dd…
.
Тај комит можете да испитате било којом од следећих варијација комаде git show
(под претпоставком да су краће верзије недвосмислене):
$ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b
$ git show 1c002dd4b536e7479f
$ git show 1c002d
Програм Гит може да одреди кратку, јединствену скраћеницу ваших SHA-1 вредности.
Ако команди git log
проследите --abbrev-commit
, излаз ће приказати краће вредности, али ће остати јединствене; подразумевано користи седам карактера, али ако је потребно да се одржи недвосмисленост SHA-1 биће дужи:
$ git log --abbrev-commit --pretty=oneline
ca82a6d Change the version number
085bb3b Remove unnecessary test code
a11bef0 Initial commit
У општем случају, осам до десет карактера је више него довољно да буде јединствено у оквиру пројекта. На пример, у фебруару 2019, Линукс кернел (који је прилично стабилан пројекат) у својој бази података објеката име преко 875.000 комитова и скоро седам милиона објеката, а не постоје објекти чије су SHA-1 контролне суме идентичне у првих 12 карактера.
Белешка
|
КРАТКА НАПОМЕНА У ВЕЗИ SHA-1
Доста људи је у неком тренутку постало забринуто да ће, неким случајем, имати у свом репозиторијуму два различита објекта који имају исту SHA-1 контролну суму. Шта онда? Ако се деси да комитујете објекат чија је SHA-1 вредност контролне суме иста као неког ранијег различитог објекта у вашем репозиторијуму, програм Гит ће видети претходни објекат који се већ налази у бази података, претпоставиће да је већ уписан и једноставно ће да поново искористити. Ако у неком тренутку покушате да одјавите так објекат, увек ћете добити податке из првог објекта. Међутим, требало би да сте свесни колико је невероватно мала вероватноћа оваквог сценарија.
The SHA-1 хеш је дужине 20 бајтова или 160 битова.
Број насумично хешираних објеката који су потребни да се обезбеди 50% вероватноће једне једине колизије је око 280
(формула за одређивање вероватноће колизије је Ево примера који вам даје идеју шта би требало да се догоди па да дође до SHA-1 колизије. Ако би свих 6,5 милијарди људи на Земљи програмирало и сваке секунде, свако од њих генерише кôд еквивалентан комплетној историји Линукс кернела (3,6 милиона Гит објеката) и гура га на један огроман Гит репозиторијум, требало би да прође отприлике 2 године док тај репозиторијум буде садржао довољно објеката да има 50% вероватноће за једну једину SHA-1 колизију објеката. Дакле, природна SHA-1 колизија је мање вероватна од тога да у истој ноћи, у невезаним инцидентима сваког од чланова вашег програмерског тима нападну и убију вукови. Ако томе посветите рачунарску снагу вредну неколико хиљада долара, могуће је да се синтетишу два фајла са истом контролном сумом, као што је у фебруару 2017. године доказано на https://shattered.io/. Програм Гит прелази на SHA256 као подразумевани алгоритам хеширања, јер је он много отпорнији на нападе колизијом, и садржи уграђен кôд којим се овај напад ублажава (мада није могуће да се потпуно елиминише). |
Референце грана
Један једноставан начин да се наведе одређени комит може да се употреби ако је то комит на врху неке гране; тада у било којој Гит команди која очекује референцу на комит просто можете да наведете име гране.
Не пример, ако желите да испитате последњи комит објекат на грани, следеће две команде су еквивалентне, под претпоставком да грана topic1
показује на ca82a6d
:
$ git show ca82a6dff817ec66f44342007202690a93763949
$ git show topic1
Ако желите да видите на који тачно SHA-1 грана показује, или ако желите да видите на шта се своди било који од ових примера у смислу SHA-1 вредности, можете употребити Гит водоводни алат под називом rev-parse
.
За више информација у вези водоводних алата, можете погледати Гит изнутра; у основи, rev-parse
служи за операције ниског нивоа и није дизајнирана за свакодневне операције.
Међутим, понекада може бити од помоћи када желите да видите шта се заиста догађа.
Овде над својом граном можете да извршите rev-parse
.
$ git rev-parse topic1
ca82a6dff817ec66f44342007202690a93763949
RefLog кратка имена
Једна од ствари које програм Гит обавља у позадини док ви радите је да чува reflog – лог у којем чува где су се у последњих неколико месеци налазили ваш HEAD и референце грана.
Свој reflog можете погледати командом git reflog
:
$ git reflog
734713b HEAD@{0}: commit: Fix refs handling, add gc auto, update tests
d921970 HEAD@{1}: merge phedders/rdocs: Merge made by the 'recursive' strategy.
1c002dd HEAD@{2}: commit: Add some blame and merge stuff
1c36188 HEAD@{3}: rebase -i (squash): updating HEAD
95df984 HEAD@{4}: commit: # This is a combination of two commits.
1c36188 HEAD@{5}: rebase -i (squash): updating HEAD
7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD
Сваки пут када се из неког разлога ажурира врх ваше гране, програм Гит ту информацију чува у овој привременој историји.
Reflog податке такође можете искористите и да наведете старије комитове.
На пример, ако желите да видите пету претходну вредност показивача HEAD вашег репозиторијума, можете да искористите @{5}
референцу коју видите у reflog излазу:
$ git show HEAD@{5}
Ову синтаксу можете и да употребите ако желите да видите где је пре неког одређеног времена била грана.
Рецимо, да видите где је јуче била ваша master
грана, откуцајте:
$ git show master@{yesterday}
То би вам приказало где је јуче био врх master
гране.
Ова техника функционише само за податке који се још увек налазе у вашем reflog дневнику, тако да је не можете употребити за комитове старије од неколико месеци.
Ако желите да се reflog информације форматирају као git log
излаз, можете да извршите git log -g
:
$ git log -g master
commit 734713bc047d87bf7eac9674765ae793478c50d3
Reflog: master@{0} (Scott Chacon <schacon@gmail.com>)
Reflog message: commit: Fix refs handling, add gc auto, update tests
Author: Scott Chacon <schacon@gmail.com>
Date: Fri Jan 2 18:32:33 2009 -0800
Fix refs handling, add gc auto, update tests
commit d921970aadf03b3cf0e71becdaab3147ba71cdef
Reflog: master@{1} (Scott Chacon <schacon@gmail.com>)
Reflog message: merge phedders/rdocs: Merge made by recursive.
Author: Scott Chacon <schacon@gmail.com>
Date: Thu Dec 11 15:08:43 2008 -0800
Merge commit 'phedders/rdocs'
Важно је приметити да су reflog информације стриктно локалне – то је дневник онога што сте ви урадили у свом репозиторијуму.
Референце неће бити исте у нечијој копији репозиторијума; а такође и непосредно након што иницијално клонирате репозиторијум, reflog ће бити празан јер се још увек није догодила никаква активност у репозиторијуму.
Извршавање git show HEAD@{2.months.ago}
ће вам приказати одговарајући комит само ако сте клонирали пројекат барем пре два месеца – ако сте га клонирали раније од тога, видећете само свој први локални комит.
Савет
|
Посматрајте reflog као Гитову верзију историје љуске
Ако познајете ЈУНИКС или Линукс, reflog можете сматрати за Гитову верзију историје љуске, што јасно наглашава чињеницу да је оно што се тамо налази важно само за вас и за вашу „сесију” и не тиче се миког другог ко можда ради на истој машини. |
Белешка
|
Означавање заграда у PowerShell
Када се користи PowerShell, заграде као што су
|
Референце на предаке
Још један главни начин за навођење комитова је путем његових предака.
Ако на крај референце поставите ^
, програм Гит то разрешава у значење родитеља наведеног комита.
Рецимо да погледате у историју свог пројекта:
$ git log --pretty=format:'%h %s' --graph
* 734713b Fix refs handling, add gc auto, update tests
* d921970 Merge commit 'phedders/rdocs'
|\
| * 35cfb2b Some rdoc changes
* | 1c002dd Add some blame and merge stuff
|/
* 1c36188 Ignore *.gem
* 9b29157 Add open3_detach to gemspec file list
Претходни комит можете видети тако што наведете HEAD^
, што значи „родитељ од HEAD”:
$ git show HEAD^
commit d921970aadf03b3cf0e71becdaab3147ba71cdef
Merge: 1c002dd... 35cfb2b...
Author: Scott Chacon <schacon@gmail.com>
Date: Thu Dec 11 15:08:43 2008 -0800
Merge commit 'phedders/rdocs'
Белешка
|
Означавање циркумфлекса на Виндоуз систему
У
|
Такође можете да наведете и број након ^
– на пример, d921970^2
значи „други родитељ од d921970”.
Ова синтакса је корисна само код комитова спајања који имају више од једног родитеља.
Први родитељ је грана на којој сте били када сте покренули спајање, а други је комит на грани у коју се спајате:
$ git show d921970^
commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b
Author: Scott Chacon <schacon@gmail.com>
Date: Thu Dec 11 14:58:32 2008 -0800
Add some blame and merge stuff
$ git show d921970^2
commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548
Author: Paul Hedderly <paul+git@mjr.org>
Date: Wed Dec 10 22:22:03 2008 +0000
Some rdoc changes
Још једна главна спецификација родитељства је ~
.
Ово такође показује на првог родитеља, тако да су HEAD~
и HEAD^
исто.
Разлика се јавља када наведете број.
HEAD~2
значи „први родитељ првог родитеља”, или „деда” – она пролази по првим родитељима онолико пута колико наведете.
На пример, у историји наведеној раније, HEAD~3
би било:
$ git show HEAD~3
commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d
Author: Tom Preston-Werner <tom@mojombo.com>
Date: Fri Nov 7 13:47:59 2008 -0500
Ignore *.gem
Ово такође може да се наведе и као HEAD~~~
, што представља првог родитеља од првог родитеља од првог родитеља:
$ git show HEAD~~~
commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d
Author: Tom Preston-Werner <tom@mojombo.com>
Date: Fri Nov 7 13:47:59 2008 -0500
Ignore *.gem
Ове синтаксе такође можете и да комбинујуете – са HEAD~3^2
можете добити другог родитеља претходне референце (под претпоставком да је то комит спајања) и тако даље.
Опсези комитова
Сада када можете да наведете појединачне комитове, хајде да видимо како се наводе опсези комитова. То је од посебне користи за управљање гранама – ако имате доста грана, можете употребити навођења опсега за одговоре на питања као што је „који рад на овој грани још увек спојен у моју главну грану?”
Двострука тачка
Најчешћи начин задавања опсега је синтаксом са двоструком тачком. Ово у суштини тражи да програм Гит разреши опсег комитова који су доступни од једног, али нису доступни од другог комита. На пример, рецимо да имате историју комитова која изгледа као Пример историје за избор опсега.
Желите да видите шта из ваше експерименталне гране још увек није спојено у вашу master
грану.
Можете затражити да вам програм Гит прикаже лог само тих комитова помоћу master..experiment
– што значи „сви комитови до којих може да се дође из experiment
али до којих не може да се дође од master
”.
У циљу јасноће и сажетости, у следећим примерима ће се уместо стварног лог излаза користити слова комит објеката са дијаграма у редоследу у којем би се приказали:
$ git log master..experiment
D
C
С друге стране, ако бисте желели да видите супротно – све комитове у master
који нису у experiment
– можете да замените места гранама.
experiment..master
вам приказује све у master
до чега не може да се стигне из experiment
:
$ git log experiment..master
F
E
Ово је корисно ако желите да experiment
грану одржавате ажурном и да најпре погледате шта ћете то спојити.
Још једна честа употреба ове синтаксе је се види шта ће те управо гурнути на удаљени репозиторијум:
$ git log origin/master..HEAD
Ова команда вам приказује све комитове у вашој текућој грани који се не налазе у master
грани origin
удаљеног репозиторијума.
Ако извршите git push
и ваша текућа грана прати origin/master
, комитови које прикаже git log origin/master..HEAD
су комитови који ће се пренети на сервер.
Једну страну синтаксе можете да изоставите, па програм Гит онда узима да то значи HEAD.
На пример, исти резултат као у претходном примеру можете добити ако откуцате git log origin/master..
– програм Гит замењује оно што недостаје на једној страни са HEAD.
Вишеструке тачке
Синтакса двоструке тачке је корисна као скраћеница, али вероватно бисте желели да наведете више од две гране када желите да задате ревизију, као што је приказ комитова који се налазе у било којој од неколико грана и који се не налазе у грани на којо се тренутно налазите.
Програм Гит вам омогућава да то урадите било карактером ^
било са --not
испред оне референце за коју не желите да видите комитове коју су доступни из ње.
Тако да су следеће три команде еквивалентне:
$ git log refA..refB
$ git log ^refA refB
$ git log refB --not refA
То је корисно, јер овом синтаксом у свом упиту можете да наведете више од две референце, што није могуће употребом синтаксе са двоструком тачком.
На пример, ако желите да видите све комитове до којих може да се дође из refA
или refB
, али не може из refC
, можете да откуцате било коју од следеће две команде:
$ git log refA refB ^refC
$ git log refA refB --not refC
Ово чини врло моћан систем за упит ревизија који би требало да вам помогне у одређивању онога што се налази у вашим гранама.
Трострука тачка
Последња главна синтакса избора опсега је синтакса троструке тачке која наводи све комитове до којих може да се дође из било које од датих референци, али не из обе истовремено.
Погледајте претходни пример историје комитова у Пример историје за избор опсега.
Ако желите да видите шта се налази у master
или experiment
али не и заједничке референце, можете да извршите:
$ git log master...experiment
F
E
D
C
Да поновимо, ово вам исписује обичан log
излаз, али приказује само комит информације за ова четири комита, које се појављују у традиционалном редоследу по датуму комитовања.
У овом случају је уопбичајено да се у команди log
користи прекидач --left-right
који вам приказује на којој страни опсега се налази сваки од комитова.
Тако су подаци још кориснији:
$ git log --left-right master...experiment
< F
< E
> D
> C
Помоћу ових алата можете много лакше навести програму Гит комит или комитове које желите да испитате.