Спајање (merge) — шта је, како ради merge и стратегије спајања

Аутор: IT Sectr Објављено: 2026-08-01 Време читања: 9 мин

Merge — то је операција спајања грана у Git-у, која обједињује промене из две различите линије развоја у једну циљну грану. За разлику од rebase, merge чува потпуну историју гранања, стварајући посебан merge-комит са два родитеља. Према званичној документацији Git (2026), merge је најбезбеднији начин спајања грана, јер не преписује историју и омогућава праћење када и које гране су спојене. Ово је стандардни избор за спајање у јавним гранама, као што су main, develop и release.

Главно

  • Merge — спајање грана са стварањем merge-комита, који чува историју обе гране.
  • Merge-комит — посебан комит са два родитеља, који бележи чињеницу спајања.
  • Стратегије спајања — recursive, octopus, ours, squash — свака одговара за различите сценарије.
  • Конфликти — настају при истовременој промени истих редова у обе гране и захтевају ручно решавање.
  • Безбедност — merge не мења постојеће комитове, зато је безбедан за јавне гране.

Шта је merge у Git-у

Merge — то је команда git merge која спаја промене из наведене гране у тренутну. Git налази заједничког претка (заједнички базни комит), израчунава diff сваке гране у односу на претка и ствара merge-комит који садржи обједињени скуп промена. Резултат — циљна грана се допуњава свим променама из спојене гране.

Синтакса: налазећи се у циљној грани (нпр. main), изврши git merge feature. Git аутоматски ствара merge-комит, ако нема конфликата. У подразумеваној поруци merge-комита наводи се: „Merge branch ’feature’ into main”. Порука се може променити преко флага -m или уредити у отвореном едитору.

Merge је недеструктивна операција. За разлику од rebase, merge не дира постојеће комитове: они остају са истим хешевима, ауторима и датумима. То чини merge јединим безбедним начином спајања за гране на којима истовремено ради више програмера. Ако нешто крене наопако, merge се може отказати командом git merge --abort.

bash
# Пређи на циљну грану
git checkout main

# Споји грану функције
git merge feature

# Резултат — merge комит са два родитеља
git log --oneline --graph

# Споји са прилагођеном поруком
git merge feature -m "feat: integrate authentication module"

Типови merge: regular, squash, fast-forward

Git подржава три режима спајања, који се бирају у зависности од жељеног резултата. Regular merge (подразумевани) ствара merge-комит. Squash merge спаја све комитове feature-гране у један. Fast-forward — помера показивач гране без стварања комита, ако је могуће. Избор режима зависи од workflow-а тима и правила историје.

Regular merge (--no-ff) — ствара merge-комит чак и ако се спајање може извршити као fast-forward. Препоручује се за main грану: merge-комит експлицитно означава моменат интеграције функције и омогућава лако враћање свих промена feature-гране једним revert merge-комита. GitHub подразумевано користи овај режим при спајању PR-а преко дугмета Merge.

Squash merge (--squash) — сакупља све комитове feature-гране у један комит у циљној грани. Користан када груба историја feature-гране не треба да уђе у main. Недостатак: губи се веза са оригиналним комитовима — не може се видети како је функција развијана корак по корак. GitHub користи овај режим при избору „Squash and merge” у PR-у.

Fast-forward (--ff) — ако циљна грана нема нових комитова након огранавања функције, Git једноставно помера показивач напред, без стварања merge-комита. Историја остаје линеарна. Флаг --no-ff присилно ствара merge-комит, --ff-only ће се завршити грешком ако fast-forward није могућ.

bash
# Обавезан merge комит (препоручује се за main)
git merge --no-ff feature

# Squash merge — сви комити у један
git merge --squash feature
git commit -m "feat: add authentication"

# Fast-forward само ако је могуће
git merge --ff-only feature

# Прекини конфликтно спајање
git merge --abort

Стратегије спајања Git

Стратегије спајања одређују алгоритам који Git користи за обједињавање промена. Свака стратегија одговара за различите сценарије. Git аутоматски бира одговарајућу стратегију, али програмер може да је наведе експлицитно преко флага --strategy. Разумевање стратегија помаже у предвиђању понашања Git-а при сложеним спајањима.

Recursive — подразумевана стратегија за спајање две гране. Git налази заједничког претка, израчунава промене у свакој грани и спаја их. Ако је заједнички предак пронађен, recursive исправно обрађује преименовање датотека и додавање нових. При конфликтима, recursive може користити додатне опције: ours (аутоматски бира нашу верзију) и theirs (бира њихову).

Octopus — за истовремено спајање више од две гране: git merge feature1 feature2 feature3. Octopus не подржава решавање конфликата — сви конфликти морају бити решени пре позива команде. Користи се ретко, углавном за спајање неколико независних грана које гарантовано не конфликтирају (нпр. различити модули).

СтратегијаБрој гранаРешавање конфликата
Recursive2Аутоматско + опције ours/theirs
Octopus3+Не — сви конфликти морају бити решени унапред
OursБило којиУвек бира нашу верзију, туђе промене се игноришу
Subtree2За спајање подстабала (subtree merge)

Ours — посебна стратегија која потпуно игнорише промене из спајане гране и чува тренутни садржај циљне гране. Merge-комит се ствара, али садржај остаје непромењен. Корисна када треба забележити у историји чињеницу спајања, али фактички одбацити све промене из туђе гране.

Решавање merge-конфликата

Merge-конфликт настаје када су исти редови датотеке измењени у обе гране на различите начине. Git не може аутоматски да одреди која верзија је исправна и зауставља merge. Конфликт може настати и при преименовању датотеке у једној грани и њеној измени у другој, или при истовременом брисању и модификацији исте датотеке.

Процес решавања: Git означава конфликтне датотеке маркерима. У датотеци се појављују делови са <<<<<<< HEAD (наша верзија), ======= (раздвајач) и >>>>>>> feature (њихова верзија). Програмер ручно уређује конфликтни део, бирајући потребне редове из обе верзије, уклања маркере, чува датотеку и додаје је у индекс преко git add.

За визуелно решавање конфликата Git подржава mergetool — спољни алат за поређење. Популарни mergetool алати: Meld, KDiff3, Beyond Compare, VS Code (уграђени едитор конфликата). Mergetool приказује три панела: нашу верзију, њихову верзију и резултат. Програмер визуелно бира блокове кода за укључивање у крајњу датотеку.

bash
# Покрени спајање и откриј конфликт
git merge feature
# КОНФЛИКТ (садржај): Конфликт спајања у src/main.swift

# Провери конфликтне датотеке
git status

# Отвори визуелни mergetool
git mergetool

# Након решавања — додај и комитуј
git add src/main.swift
git commit

# Прекини спајање
git merge --abort

Када изабрати merge уместо rebase

Merge је пожељнији од rebase у неколико кључних ситуација. Прва: при раду са јавним гранама доступним другим програмерима. Merge не преписује историју, и колеге се могу безбедно синхронизовати. Rebase у јавној грани створиће разилазећу историју и конфликте код свих који су већ примили старе комитове.

Друга ситуација: при завршетку feature-гране. Већина тимова преферира merge (са флагом --no-ff) у main како би забележили моменат интеграције функције. Ово поједностављује навигацију кроз историју и омогућава лако враћање целе функције једним git revert merge-комита. GitHub Flow подразумевано нуди три опције merge: једноставан merge, squash merge и rebase merge.

Трећа ситуација: при раду са pull request-ом који је прошао рецензију. GitHub и GitLab нуде merge дугме са различитим опцијама. Merge (Create a merge commit) — пуна историја са merge-комитом. Squash and merge — чиста историја без детаља развоја. Rebase and merge — линеарна историја без merge-комита, али са преписивањем комитова. Избор зависи од правила тима.

  • Јавне гране (main, develop) — само merge, никад rebase.
  • Завршетак PR-а — merge са --no-ff за бележење момента интеграције.
  • Гране са туђим комитовима — merge не преписује туђи рад.
  • Пре издања — merge је безбеднији, јер има мање ризика.
  • Заједничка грана — ако на грани ради више програмера, merge је обавезан.

Најбоље праксе спајања грана

Прво правило: увек бити на актуелној верзији циљне гране пре merge-а. Изврши git checkout main && git pull пре него што спојиш функцију. Ово минимизира конфликте и гарантује да ће merge-комит садржати све актуелне промене. Ако је циљна грана знатно одмакла, прво изврши git merge main унутар feature-гране за решавање конфликата у њеном контексту.

Друго правило: тестирати код након merge-а. Merge може променити понашање, чак и ако није било конфликата. CI/CD цевовод треба да проведе тестове на merge-комиту пре слања у продукцију. Неки тимови користе merge gates — обавезне провере које блокирају merge док се не прођу.

Треће правило: документовати merge-комитове. Стандардна порука „Merge branch ’feature’ into main” је мало корисна. Препоручује се додавање описа онога што је спојено: „Merge authentication module: login, registration, password recovery”. Ово поједностављује анализу историје и тражење регресија. У великим пројектима, merge-комитови се аутоматски генеришу из назива PR-а.

  • Ажурност — пре merge-а уверите се да је циљна грана ажурирана (git pull).
  • Тестирање — CI/CD треба да проведе тестове на резултујућем merge-комиту.
  • Описне поруке — наведите у merge-комиту која функција је спојена.
  • Учесталост — спајајте feature-гране што раније и чешће (максимум недељу дана).
  • Отказивање — git revert merge-комита враћа целу функцију у целини.

Често постављана питања

Шта значи спојити (merge) гране у Git-у?

Спојити (merge) — извршити git merge за обједињавање промена из једне гране у другу. Резултат је merge-комит који бележи чињеницу спајања и садржи промене из обе гране. Ово је основни начин интеграције feature-грана у main, develop или release у Git Flow-у.

Чим се squash merge разликује од обичног merge-а?

Squash merge спаја све комитове feature-гране у један комит у циљној грани, губећи међуисторију развоја. Обичан merge ствара merge-комит, чувајући све комитове feature-гране. Squash merge даје чисту историју, али не омогућава праћење корачног развоја функције.

Како решити merge-конфликт у Git-у?

Отворите конфликтну датотеку, пронађите делове са маркерима <<<<<<< HEAD и >>>>>>>. Уредите садржај, остављајући потребне редове из обе верзије, уклоните маркере. Сачувајте датотеку, извршите git add и git commit. Можете користити git mergetool за визуелно решавање.

Када користити merge уместо rebase?

Merge се увек користи за јавне гране (main, develop, release), јер не преписује историју. Rebase се примењује у личним feature-гранама пре њиховог објављивања. Након што је грана постала део заједничког репозиторијума и колеге су јој приступили, дозвољен је само merge.

Како отказати merge у Git-у?

Пре завршетка merge-а (током конфликта) — git merge --abort отказује спајање у потпуности. Након завршетка — git revert <merge-commit-hash> -m 1 ствара повратни комит. Флаг -m 1 означава коју родитељску грану задржати (циљну). Git revert је безбеднији од git reset за објављене гране.

Закључак

  • Merge — безбедно спајање грана са чувањем историје и стварањем merge-комита са два родитеља.
  • Режими спајања — regular (--no-ff), squash (--squash) и fast-forward (--ff) за различите циљеве.
  • Стратегије — recursive (подразумевана), octopus (3+ гране), ours (игнорисање туђих промена).
  • Конфликти — решавају се ручно кроз уређивање означених делова или mergetool.
  • Безбедност — merge не мења постојеће комитове, зато је безбедан за јавне гране.
  • Squash merge — спаја све комитове у један, губећи међуисторију развоја.
  • Отказивање merge-а — git revert merge-комита са флагом -m 1 за безбедно враћање објављених промена.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође