Rebase — то је операција у Git-у која премешта комитове из једне гране на врх друге, стварајући линеарну историју без непотребних merge-комитова. За разлику од спајања, rebase преписује историју: сваки премештени комит добија нови хеш, јер се његов родитељ мења. Према документацији Git-а (2026), rebase се користи за синхронизацију feature-грана са актуелним стањем main-а пре креирања pull request-а. Команда git rebase је један од основних алата за одржавање чисте историје у пројектима који користе Git Flow.
Главно
Rebase — то је команда Git-а која пребазује тренутну грану на наведену: узима све комитове тренутне гране, привремено их чува, помера показивач гране на циљни комит и секвенцијално примењује сачуване комитове изнад њега. Резултат — историја изгледа као да је програмер радио директно од последњег комита циљне гране.
Основни синтаксис: git rebase main — налазећи се у feature-грани, ова команда премешта све feature комитове на врх main-а. Git користи стратегију three-way merge за сваки комит понаособ. Ако је комит A већ присутан у циљној грани (одређује се по хешу), Git га аутоматски прескаче, чиме се избегава дуплирање промена.
Rebase такође подржава onto режим за премештање дела комитова: git rebase --onto target start end — ова форма омогућава издвајање опсега комитова из једне гране и примену изнад друге. На пример, git rebase --onto main feature~3 feature ће преместити последња три комита feature гране на врх main-а.
# Пређи на feature грану
git checkout feature
# Пребазуј feature на main
git rebase main
# Након успешног rebase-а — историја је линеарна
git log --oneline --graph
# Премести последња 3 комита у main
git rebase --onto main HEAD~3 HEAD
Rebase и merge решавају исти задатак — обједињавање промена из различитих грана — али то чине на принципијелно различите начине. Merge чува пуну историју спајања, стварајући merge-комит са два родитеља. Rebase преписује историју, чинећи је линеарном. Избор између њих зависи од радног тока тима и правила рада са репозиторијумом.
Главна разлика — како се бележи чињеница спајања. Merge чува: „у овој тачки смо спојили feature у main” — то је информативно за историју пројекта, али затрпава дневник при честим спајањима. Rebase показује: „комитови feature-а су урађени секвенцијално од последњег стања main-а” — то је чисто, али скрива чињеницу да се рад одвијао паралелно.
Друга разлика — обрада конфликата. Код merge-а конфликти се решавају једном, а решење се бележи у merge-комиту. Код rebase-а конфликти могу настати за сваки премештени комит и сваки захтева посебно решавање. То је захтевније, али омогућава прецизнију контролу над тим које промене улазе у коначну верзију.
| Критеријум | Rebase | Merge |
|---|---|---|
| Историја | Линеарна, без merge-комитова | Нелинеарна, са merge-комитовима |
| Хешеви комитова | Преписују се (нови) | Оригинални се чувају |
| Конфликти | За сваки комит посебно | Једном у merge-комиту |
| Јавне гране | Забрањен | Дозвољен |
| Команда за отказивање | git rebase --abort | git merge --abort |
Интерактивни rebase (git rebase -i) — то је режим у којем Git отвара уређивач са списком комитова и доступним радњама за сваки од њих. Програмер може да препише историју пре слања у удаљени репозиторијум. Ово је основни алат за одржавање чистоће комитова у feature-грани.
Доступне команде у интерактивном режиму: pick (остави комит какав јесте), reword (промени поруку комита), edit (заустави се ради измена), squash (споји са претходним комитом, чувајући обе поруке), fixup (споји, одбацујући поруку), drop (уклони комит). Свака команда се наводи испред хеша комита у отвореном уређивачу.
Squash и fixup — најчешће коришћене команде за спајање комитова. Ако је програмер направио 5 малих комитова са исправкама током рада, squash ће их спојити у један логички комит са смисленом поруком. Fixup је користан за исправљање грешака у куцању: промене улазе у претходни комит без чувања сопствене поруке.
# Отвори уређивач за последња 4 комита
git rebase -i HEAD~4
# Уређивач ће показати:
pick a1b2c3d Add authentication
pick e4f5g6h Fix typo in login
squash i6j7k8l Additional login fixes
pick m9n0o1p Add auth tests
# Након чувања — Git извршава rebase
# и отвара уређивач за спојену поруку комита
# Auto-squash без отварања уређивача
git rebase -i HEAD~4 --autosquash
Заставица --autosquash аутоматски поставља fixup/squash за комитове чије поруке почињу са fixup! или squash!. Убрзава рад ако програмер унапред означава комитове за касније спајање. Заставица --committer-date-is-author-date чува оригинални датум комита при пребазирању — корисно за очување хронологије у историји.
Конфликти при rebase-у настају када Git не може аутоматски да примени премештени комит због противречности са променама у циљној грани. За разлику од merge-а, где се конфликт решава једном, код rebase-а сваки комит може изазвати конфликт и мора се решавати секвенцијално за сваки комит од најстаријег до најновијег.
Када настане конфликт, Git зауставља rebase и јавља који комит је изазвао проблем. Програмер отвара конфликтни фајл (Git означава конфликтне делове маркерима <<<<<<<, =======, >>>>>>>), уређује га, додаје у индекс (git add) и наставља rebase командом git rebase --continue. Ако решење није пронађено — git rebase --abort потпуно отказује пребазирање.
Савет: код вишеструких конфликата ефикасније је користити git mergetool, који отвара визуелни уређивач за решавање противречности. Такође се може прескочити проблематични комит (git rebase --skip), али то ће уклонити његове промене из коначне историје, што ретко бива исправно решење.
# Започни rebase са конфликтом
git rebase main
# Auto-merging file.txt
# КОНФЛИКТ (садржај): Конфликт спајања у file.txt
# Провери статус
git status
# оба измењена: file.txt
# Уреди конфликтне делове → git add → настави
git add file.txt
git rebase --continue
# Ако нисте сигурни — прекини
git rebase --abort
Златно правило rebase-а: никада не пребазирати комитове који су већ послати у удаљени репозиторијум и доступни другим програмерима. Пошто rebase преписује хешеве комитова, код колега ће настати конфликти при покушају синхронизације — њихова локална историја ће се разилазити са преписаном удаљеном.
Ситуација у којој је rebase категорички забрањен: ако је неко већ креирао грану на основу ваших комитова (на пример, ваш колега је направио feature од вашег feature-а), промена историје ће покварити његов рад. У таквим случајевима треба користити merge. Такође се не препоручује радити rebase непосредно пре рока — грешка при решавању конфликата може трајати дуже него што се очекивало и блокирати издање.
Изузетак: ако грану користи само један програмер (лична feature-грана, необјављена или објављена у draft режиму), rebase пре push-а је стандардна пракса. Након објављивања и почетка колективног рада — само merge. GitHub и GitLab подразумевано нуде squash merge као компромис: спаја комитове у један, али не преписује историју циљне гране.
У савременим тимовима најчешће се користи радни ток оријентисан на rebase у комбинацији са GitHub Flow-ом. Процес изгледа овако: програмер креира feature-грану од main-а, ради у њој, периодично се синхронизује кроз git rebase main, а пре креирања pull request-а обавља интерактивни rebase за чишћење историје.
Након креирања PR-а (ако је потребно повући нове промене из main-а) користи се git pull --rebase main уместо обичног git pull-а. Ово омогућава увлачење промена без стварања непотребног merge-комита. Git pull са заставицом --rebase је еквивалентан git fetch + git rebase — Git прво учитава нове комитове, затим пребазује локалне промене изнад њих.
Git омогућава подешавање rebase-а као подразумеваног понашања за pull: git config --global pull.rebase true. Након ове конфигурације, git pull увек ради rebase уместо merge-а. Ако је потребан обичан pull — користи се git pull --no-rebase. Многи тимови такође укључују autostash: git config --global rebase.autoStash true — ово аутоматски скрива непотврђене промене пре rebase-а и враћа их након тога.
Често постављана питања
Ребазирати — значи извршити git rebase: преместити комитове тренутне гране на врх друге. Као резултат, историја постаје линеарна, сваки комит добија нови хеш, а merge-комитови се не стварају. Команда се користи за синхронизацију грана без непотребних тачака спајања у дневнику.
Merge ствара merge-комит са два родитеља, чувајући паралелну историју и оригиналне хешеве. Rebase преписује историју — комитови добијају нове хешеве, а историја постаје линеарна. Merge је сигурнији за јавне гране, rebase даје чистији дневник.
Команда git rebase -i HEAD~N отвара уређивач са последњих N комитова. За сваки комит се може изабрати радња: pick (остави), reword (преименуј), edit (измени), squash (споји са претходним), fixup (споји без поруке), drop (уклони). Након чувања, Git примењује изабране промене.
Rebase преписује хешеве комитова, што чини историју некомпатибилном са копијама истих комитова код других програмера. Ако је колега већ примио ваше комитове кроз git pull, а ви сте их потом пребазирали, његов git push ће бити одбијен, а git pull ће створити дуплиране комитове и конфликте.
Пре завршетка — git rebase --abort потпуно отказује. Након завршетка може се вратити претходно стање кроз git reflog — пронаћи хеш комита пре rebase-а и извршити git reset --hard на њега. Reflog чува историју кретања HEAD-а подразумевано 30 дана.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође