-
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 Водоводне команде
3.2 Гранање у програму Гит - Основе гранања и спајања
Основе гранања и спајања
Хајде да прођемо кроз једноставан пример гранања и спајања у процесу рада какав се често јавља у реалном свету. Пратићете ове инструкције:
-
Одрадићете неки посао на веб сајту.
-
Направите грану за нову корисничку причу на којој радите.
-
Одрадићете нешто на тој грани.
У овом тренутку, добићете позив да постоји критичан проблем који морате да решите истог тренутка. Урадићете следеће:
-
Пребацићете се на грану за продукцију.
-
Направићете нову грану на којој ћете додати кôд који решава проблем.
-
Када га тестирате, спојићете грану са решењем проблема, и гурнућете на продукцију.
-
Вратићете се назад на корисничку причу на којој сте радили и наставити посао.
Основе гранања
Најпре, претпоставимо да радите на пројекту у коме на master
грани већ имате неколико комитова.
![Једноставна историја комитова](png/basic-branching-1.png)
Одлучили сте да ћете радити на проблему #53
који се налази на неком систему за праћење проблема који користи ваша компанија.
Да бисте направили грану и истовремено скочили на њу, извршите команду git checkout
са прекидачем -b
:
$ git checkout -b iss53
Switched to a new branch "iss53"
Ово је скраћеница за:
$ git branch iss53
$ git checkout iss53
![Креирање новог показивача на грану](png/basic-branching-2.png)
Радите неке ствари на свом веб сајту и вршите неке комитове.
Док то радите, грана iss53
се креће унапред, јер сте је одјавили (односно, HEAD
показује на њу):
$ vim index.html
$ git commit -a -m 'Create new footer [issue 53]'
![Грана `iss53` се померила напред у складу с послом који сте обавили](png/basic-branching-3.png)
iss53
се померила унапред у складу с послом који сте обавилиСада добијате позив да постоји проблем са веб сајтом, и морате одмах да га поправите.
Са програмом Гит, не морате да решавате проблем заједно са iss53
променама које сте направили, и не морате да улажете много труда у то да опозовете те промене пре него што почнете рад на примени исправке за оно што је у продукцији.
Потребно је само да се пребаците назад на master
грану.
Ипак, пре него што то урадите, обратите пажњу на то да ако ваш радни директоријум или стејџ има некомитоване промене које су у конфликту са граном коју одјављујете, програм Гит вам неће дозволити да промените грану.
Најбоље да радно стање буде чисто вршите скок између грана.
Постоје начини да се ово заобиђе (наиме, скривање и исправљање комита) које ћемо обрадити касније, у Скривање и чишћење.
Засад, претпоставимо да сте комитовали све промене, тако да се безбедно можете вратити на master
грану:
$ git checkout master
Switched to branch 'master'
У овом тренутку, радни директоријум вашег пројекта изгледа исто онако како је изгледао пре него што сте почели да радите на проблему #53, па можете да се концентришете на хитни случај. Ово је битна ствар коју треба запамтити: када мењате гране, програм Гит ресетује радни директоријум тако да изгледа онако како је изгледао када сте последњи пут комитовали на тој грани. Аутоматски додаје, брише и мења фајлове тако да ваша радна копија изгледа тачно онако како је изгледала када сте на грани урадили последњи комит.
Следеће, треба да решите хитан проблем.
Направићемо hotfix
грану на којој ћемо радити све док не решимо проблем:
$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'Fix broken email address'
[hotfix 1fb7853] Fix broken email address
1 file changed, 2 insertions(+)
![`Hotfix` грана базирана на `master` грани](png/basic-branching-4.png)
Hotfix
грана базирана на master
граниСада можете да тестирате оно што сте урадили, да будете сигурни да је проблем решен и да грану hotfix
спојите назад са граном master
.
Ово можете да урадите командом git merge
.
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
У овом комиту ћете приметити израз „fast-forward” (премотавање унапред).
Пошто се комит C4
на који показује грана hotfix
коју сте се спојили налазио директно испред комита C2
на ком се налазите, програм Гит једноставно помера показивач унапред.
Да то преформулишемо, када покушате да спојите један комит са комитом до ког се може стићи пратећи историју првог комита, програм Гит поједностављује ствари тако што само помери показивач унапред, јер нема раздвојеног рада којом би требало се спаја — ово зове премотавање унапред.
Промена се сада налази у снимку комита на који показује master
грана, па можете да примените исправку.
![`master` се премотала унапред до `hotfix`](png/basic-branching-5.png)
master
се премотала унапред до hotfix
Када се примени ваша супер-важна исправка, време је да се вратите на оно што сте радили пре него што сте били прекинути.
Ипак, најпре ћете обрисати hotfix
грану, јер вам више није потребна — master
грана показује на исто место.
Можете је обрисати помоћу опције -d
команде git branch
:
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
Сада можете да се вратите на свој тикет #53 и настављате да радите на њему.
$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'Finish the new footer [issue 53]'
[iss53 ad82d7a] Finish the new footer [issue 53]
1 file changed, 1 insertion(+)
![Рад се наставља на `iss53`](png/basic-branching-6.png)
iss53
Овде вреди напоменути да се посао који сте одрадили у грани hotfix
не садржи у фајловима на грани iss53
. Ако треба да га повучете у њу, можете да спојите грану master
у грану iss53
извршавањем команде git merge master
, или можете да сачекате са интегрисањем тих промена док касније не одлучите да повучете грану iss53
назад у master
.
Основе спајања
Претпоставимо да сте одлучили да је ваш рад на проблему #53 готов и да је кôд спреман за спајање са master
граном.
Да бисте то урадили, спојићете грану iss53
са граном master
, као што сте раније спојили hotfix
грану.
Све што треба да урадите јесте да одјавите грану у коју желите да спојите и да онда извршите git merge
команду:
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
Ово изгледа мало другачије од ранијег спајања hotfix
гране.
У овом случају, историја вашег развоја се раздвојила од неке старије тачке.
Пошто комит на грани на којој се налазите није директан предак гране у коју спајате, програм Гит мора одради неки посао.
У овом случају, програм Гит ради једноставан троструки спој, користећи два снимка на које показују врхови грана и њихов заједнички предак.
![Три снимка који се користе у типичном спајању](png/basic-merging-1.png)
Уместо да само помери показивач гране унапред, програм Гит прави нови снимак који је резултат овог троструког спајања и аутоматски прави нови комит који показује на њега. Ово се назива комит спајања (merge commit) и посебан је једино у том смислу што има више од једног родитеља.
![Комит спајања](png/basic-merging-2.png)
Сада када је комплетан рад спојен, више нема потребе за iss53
граном.
Можете да затворите тикет у вашем систему за праћење проблема и да обришете грану:
$ git branch -d iss53
Основни конфликти при спајању
Овај процес често неће тећи овако глатко.
Ако сте у две различите гране које спајате променили исти део истог фајла на различит начин, програм Гит неће моћи лепо да их споји.
Ако је ваша исправка за тикет #53 изменила исти део фајла као и hotfix
грана, добићете конфликт при спајању који изгледа отприлике овако:
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
Програм Гит није аутоматски направио нови комит спајања.
Паузирао је процес док ви не решите конфликт.
Ако желите да видите који фајлови нису спојени у било ком тренутну након конфликта при спајању, треба да извршите git status
:
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
Све што има конфликте при спајању који нису решени наведено је под неспојено (unmerged). Програм Гит додаје стандардне маркере за решавање конфликта у фајлове са конфликтима, тако да ручно можете да их отворите и решите конфликте. Фајл садржи секцију која изгледа слично овоме:
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
Ово значи да је верзија у HEAD
(ваша master
грана, јер сте то одјавили када сте покренули команду merge
) на врху тог блока (све изнад =======
), док је верзија из гране iss53
приказана у доњем делу.
Да бисте решили конфликт, морате или да изаберете једну или другу страну, или да ручно спојите садржину фајла.
На пример, овај конфликт се може решити тако што ћете цео горњи блок заменити следећим:
<div id="footer">
please contact us at email.support@github.com
</div>
Ово решење има помало текста из обе секције, а линије <<<<<<<
, =======
и >>>>>>>
су комплетно уклоњене.
Након што решите сваку од оваквих секција у сваком фајлу са конфликтом, извршите git add
за сваки фајл чиме означавате да је разрешен.
У програму Гит, стејџовање фајла означава да је конфликт разрешен.
Ако желите да користите графички алат за решавање оваквих проблема, можете да извршите команду git mergetool
, која покреће одговарајући визуелни алат и води вас кроз конфликте:
$ git mergetool
This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html
Normal merge conflict for 'index.html':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (opendiff):
Ако хоћете да користите неки други алат за спајање који није подразумевани (у овом случају је програм Гит је изабрао opendiff
јер је команда била покренута на Меку), можете видети све подржане алате наведене при врху након „one of the following tools”.
Једноставно укуцајте име алата који бисте радије користили.
Белешка
|
Ако су вам потребни напреднији алати за решавање компликованих конфликта при спајању, погледаћемо неке од њих у Напредно спајање. |
Када изађете из алата за решавање конфликта при спајању, програм Гит ће вас питати да ли је спајање било успешно.
Ако скрипти одговорите да јесте, она ће стејџовати фајл и уместо вас га означити као разрешен.
Можете да извршите git status
и тако се уверите да су сви конфликти разрешени:
$ git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: index.html
Ако сте задовољни тиме и ако сте потврдили да је све што је имало конфликте сада на стејџу, можете да откуцате git commit
чиме завршавате комит спајања.
Подразумевана комит порука изгледа слично овако:
Merge branch 'iss53'
Conflicts:
index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
# .git/MERGE_HEAD
# and try again.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
# modified: index.html
#
Можете да измените ову комит поруку додавањем детаља о томе како сте разрешили спој ако мислите да ће то бити корисно другима који буду гледали ово спајање у будућности — зашто сте урадили то што сте урадили, ако није очигледно.