Merge — је операција у Git-у која обједињује измене из једне гране у другу, стварајући комит спајања (merge commit). Git подржава неколико стратегија: fast-forward (линеарна историја), three-way merge (са стварањем merge commit-а) и squash merge (сажимање свих комита у један). Према подацима git-scm.com, 2025, merge остаје најчешће коришћени механизам интеграције кода у тимском Git развоју.
Главно
Merge (спајање) — је фундаментална операција у Git-у која обједињује измене из једне гране (source) у другу (target). Као резултат спајања, циљна грана добија све комите из изворне гране којих још увек није било у њој. У зависности од ситуације, Git може извршити merge на три различита начина.
Основна вредност merge-а је очување историје: merge commit бележи чињеницу спајања грана, чува информацију о томе када и које гране су спојене. То олакшава ревизију промена, тражење регресија и разумевање хронологије развоја. У великим пројектима, merge commit је стандардни начин интеграције кода.
Према подацима GitLab Flow, merge commit-ови се користе у 73% тимова који раде са Git-ом. Алтернативне приступе (rebase, squash) преферирају тимови оријентисани на линеарну историју. Избор стратегије зависи од величине тима, учесталости издања и прихваћених договора у пројекту.
Merge је потребан када је програмер завршио рад на функцији и жели да је интегрише у develop или main. Типичан сценарио: програмер је креирао грану функције од develop-а, радио неколико дана, а за то време су се у develop-у појавили нови комити од других учесника. Пре спајања потребно је објединити измене — и за то се користи merge.
Без merge-а није могуће заједнички радити на једном коду у Git-у. Сваки пут када два програмера истовремено уносе измене у исту базу кода, њихове гране се разилазе. Merge — једини начин да се те измене врате заједно без губитка података.
Git подржава три врсте merge-а, од којих је свака намењена свом сценарију. Избор врсте спајања утиче на историју комита, удобност враћања и читљивост лога.
Fast-forward настаје када циљна грана није имала нове комите од тренутка креирања изворне. У овом случају Git једноставно помера показивач циљне гране напред, на последњи комит изворне. Историја остаје линеарна, без merge commit-а.
# Fast-forward merge: develop се није мењао од тренутка креирања feature
git checkout develop
git merge feature/new-login
# Резултат: показивач develop се померио на крај feature
# Није креиран ниједан merge commit
Fast-forward је погодан за краткотрајне гране, где је програмер радио сам. Али овај приступ има недостатак: губи се информација да је грана постојала — сви комити изгледају као да су направљени директно у develop-у.
Three-way merge се извршава када обе гране имају нове комите после тачке разилажења. Git ствара посебан merge commit са два родитеља, који бележи чињеницу спајања грана. Овај приступ се препоручује за гране функција у тимском развоју.
# Принудни three-way merge са заставицом --no-ff
git checkout develop
git merge --no-ff feature/new-login
# Креиран merge commit са подразумеваном поруком
# Може се поставити сопствена порука преко -m
git merge --no-ff feature/new-login -m "Merge feature/new-login into develop"
Заставица --no-ff гарантује стварање merge commit-а, чак и ако је fast-forward могућ. Ово је најбоља пракса за очување информације о гранању у пројекту.
Squash merge сажима све комите изворне гране у један и примењује га на циљну. Историја функције се губи — у грану стиже један комит са свим променама. Ово је згодно када детаљни комити у грани функције не носе вредност за општу историју.
# Squash merge: сви комити feature-а сажети у један
git checkout develop
git merge --squash feature/experimental
git commit -m "feat: experimental login flow (squashed)"
Squash је погодан за нацрте, експерименталне гране и ситуације када је важно одржати чистоту историје. Минус — губи се веза са оригиналним комитима, што отежава враћање појединачних промена.
Ours и Theirs — две специјалне стратегије merge-а у Git-у. Ours потпуно игнорише измене из изворне гране, остављајући само оно што је у циљној. Theirs, напротив, прихвата верзију изворне гране при сваком конфликту. Ове стратегије су корисне при спајању великих количина кода, када је унапред познато која верзија треба да победи.
Механизам merge-а у Git-у се заснива на поређењу три тачке: заједничког претка (merge base), стања изворне гране и стања циљне гране. Git проналази merge base — последњи комит заједнички за обе гране — и израчунава које су промене настале у свакој грани после разилажења.
Git користи тространи алгоритам спајања, који узима у обзир не само две упоређиване верзије датотеке, већ и њиховог заједничког претка. Захваљујући томе, Git може аутоматски да реши ситуације када промене у једној грани не утичу на измењене делове друге — чак и ако су обе датотеке измењене.
Размотримо сценарио: два програмера раде на различитим датотекама у истој грани функције. Први је изменио LoginActivity.kt, други — ProfileFragment.kt. Када споје своје промене, Git види да су промене захватиле различите датотеке и извршава merge аутоматски, без људске интервенције.
Ако су оба програмера изменила LoginActivity.kt, али у различитим методама — Git ће се такође снаћи аутоматски, обједињујући промене ред по ред. Конфликт настаје само ако су оба изменила исте редове или ако је један обрисао код који је други изменио.
Конфликт merge-а настаје када Git не може аутоматски да обједини промене, јер су обе гране измениле исте редове на различите начине. У овом случају Git означава конфликтне делове у датотекама и очекује ручно решавање од програмера.
Конфликтни делови се обележавају посебним маркерима: <<<<<<< HEAD приказује код из циљне гране, ======= — раздвајач, >>>>>>> source-branch — код из изворне гране. Програмер мора ручно да изабере коју варијанту да задржи или да их споји.
# 1. Покренути merge и видети конфликт
git merge feature/new-login
# Излаз: CONFLICT (content): Merge conflict in LoginActivity.kt
# 2. Погледати листу датотека са конфликтима
git status
# both modified: src/ui/login/LoginActivity.kt
# 3. Решити конфликт: уредити датотеку, уклонити маркере
# 4. Додати решену датотеку и завршити merge
git add src/ui/login/LoginActivity.kt
git merge --continue
# или: git commit (без --continue)
За решавање конфликата постоје алати: git mergetool отвара визуелни merger (Meld, Beyond Compare, VS Code). Многи програмери преферирају да решавају конфликте у IDE-у — IntelliJ IDEA и Android Studio пружају уграђени алат са тропанелним поређењем, који значајно поједностављује овај процес.
Савети за решавање конфликата: увек разумите шта ради свака страна конфликта, не бришите туђи код без разумевања његове логике, а ако је конфликт превише сложен — укључите аутора обе гране у заједничко решавање.
Избор између Merge-а и Rebase-а — једна од најчешћих архитектонских одлука у Git-у. Оба приступа обједињују промене, али то чине различито: merge чува историју гранања, rebase преписује историју, чинећи је линеарном.
Многи тимови користе хибридни приступ: rebase за довођење гране функције у актуелно стање develop-а (git rebase develop), затим merge са заставицом --no-ff за фиксирање спајања. Ово даје чисту историју унутар функције и информативне тачке спајања на нивоу develop-а.
Често постављана питања
Без --no-ff Git извршава fast-forward merge, ако је могуће — једноставно помера показивач гране. Са --no-ff Git увек ствара merge commit, чувајући информацију о гранању. Препоручује се за гране функција у тимском развоју.
Користите git mergetool или уграђени алат IDE-а. Ако конфликт захвата десетине датотека — можда су се гране превише разишле. У том случају вреди разговарати са тимом о плану спајања, можда га поделити у неколико фаза.
Да: git merge --abort отказује merge ако још није завршен (конфликт). Ако је merge већ завршен — користите git reset --hard HEAD~1 или git revert -m 1 <merge-commit> за безбедно враћање.
Препоручује се за тимски рад. Merge commit бележи чињеницу спајања, садржи референце на обе гране и поједностављује разумевање историје. За личне или експерименталне гране допуштен је squash merge или fast-forward.
Git не може аутоматски да спаја бинарне датотеке — бира једну од верзија у целини. За бинарне датотеке (слике, .aab, .apk) препоручује се минимизирање паралелних измена и коришћење Git LFS за велике датотеке.
Закључци
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође