Git для щоденної роботи: rebase, cherry-pick і reflog
Як тримати історію чистою, переносити окремі коміти між гілками і повернути «втрачену» роботу після невдалого reset чи rebase.
Більшість розробників користуються десятком команд Git, і цього вистачає — доки щось не піде не так. Ця стаття про інструменти, які перетворюють «я все зламав» на «зараз поверну за хвилину».
merge чи rebase
Обидві команди об'єднують зміни, але по-різному:
merge: A---B---C main rebase: A---B---C main
\ \ \
D---E---M feature D'---E' feature- merge зберігає історію як є і додає коміт злиття.
- rebase «переписує» ваші коміти поверх свіжого main — історія лінійна, але хеші комітів змінюються.
Практичне правило: rebase для своєї локальної гілки, merge (або squash) — для злиття в main.
git switch feature
git fetch origin
git rebase origin/main # підтягнути свіжий main під свої коміти
# конфлікти? виправити файли, потім:
git add .
git rebase --continue
# передумали:
git rebase --abortОбережноНе робіть rebase гілки, з якою вже працюють інші люди. Ви переписуєте хеші комітів, і в колег виникнуть розбіжності. Якщо після rebase власної гілки треба оновити віддалену, використовуйте
git push --force-with-lease— він не перезапише чужі коміти, яких ви ще не бачили.
Інтерактивний rebase: прибрати хаос перед ревʼю
git rebase -i HEAD~5Відкриється список комітів. Змінюючи слово на початку рядка, можна:
| Команда | Дія |
|---|---|
pick |
залишити коміт |
reword |
змінити повідомлення |
squash / fixup |
злити з попереднім (з повідомленням / без) |
drop |
видалити коміт |
| перестановка рядків | змінити порядок |
Зручний прийом — fixup-коміти: виправлення одразу позначається, до якого коміту воно належить.
git commit --fixup=a1b2c3d
git rebase -i --autosquash origin/main # fixup сам стане на місцеcherry-pick: перенести один коміт
Хотфікс зробили в main, а він потрібен і в гілці релізу:
git switch release/2.4
git cherry-pick 9f8e7d6 # копія коміту з новим хешем
git cherry-pick -x 9f8e7d6 # + рядок «cherry picked from commit ...» у повідомленніreflog: машина часу
Git майже нічого не видаляє одразу. reflog записує, куди вказував HEAD після кожної операції — commit, reset, rebase, checkout.
git reflog
# 4c2a1f0 HEAD@{0}: reset: moving to HEAD~3
# 8d9e2b1 HEAD@{1}: commit: Додати експорт у CSV
# 1a7f3c5 HEAD@{2}: commit: Валідація формиЗробили git reset --hard HEAD~3 і втратили три коміти? Повертаємось:
git reset --hard 8d9e2b1 # або HEAD@{1}Невдалий rebase? Знайдіть у reflog запис перед ним (rebase (start)) і поверніться на коміт до нього.
ПорадаЗаписи reflog живуть за замовчуванням 90 днів, але лише локально. Для нескомічених змін reflog не допоможе — тому комітьте часто, навіть «WIP»-комітами, які потім злиєте через squash.
Корисні дрібниці
git switch -c fix/login # нова гілка (сучасна заміна checkout -b)
git restore --staged file.py # прибрати файл з індексу
git restore file.py # відкотити зміни у файлі
git stash push -m "wip: форма" # відкласти зміни
git stash list && git stash pop
git commit --amend --no-edit # додати зміни в останній коміт
git log --oneline --graph --all # історія деревом
git bisect start # бінарний пошук коміту, що зламав тестиНалаштування, які варто ввімкнути
git config --global pull.rebase true # pull = fetch + rebase замість merge
git config --global rebase.autoStash true # stash автоматично перед rebase
git config --global rerere.enabled true # запам'ятовувати розв'язані конфлікти
git config --global push.autoSetupRemote true # перший push сам створить upstreamВи випадково зробили git reset --hard і втратили останній коміт. Як його повернути?
Виконати git reflog, знайти хеш потрібного коміту (запис перед reset) і зробити git reset --hard <хеш> або створити з нього гілку: git branch rescue <хеш>.
Збережіть статтю собі
Увійдіть, щоб імпортувати її у власні нотатки, відмічати вивчене, ставити лайки й питати спільноту. Реєстрація безкоштовна: вхід через Google займає кілька секунд.
Увійти через Google Інші способи входу