Interactive rebase, cherry-pick, bisect, worktrees, порятунок через reflog та стратегії гілкування, які реально працюють. Git-команди, якими я користуюся щодня, а більшість розробників не знає.
Більшість розробників вивчають п'ять Git-команд і на цьому зупиняються. add, commit, push, pull, merge. Можливо, checkout і branch, якщо почувають себе сміливо. Цього вистачає на перший рік. Потім ваша гілка має 47 комітів з повідомленнями на кшталт «fix» і «wip» і «please work», ви випадково скинули щось, чого не слід було, і витрачаєте 40 хвилин на Stack Overflow, намагаючись скасувати невдалий мердж.
Я використовую Git роками. Не побіжно — інтенсивно. Кілька гілок, кілька репозиторіїв, кілька співпрацівників, цілий день, кожен день. Далі — команди та воркфлоу, якими я реально користуюсь. Не ті, що добре виглядають у туторіалі. Ті, що економлять мені реальний час, щотижня.
Ваша гілка має дванадцять комітів. Половина з них — «fix typo». Один каже «undo previous commit». Інший — «actually fix it this time». Ви збираєтесь відкрити PR. Нікому не потрібно бачити цю історію.
Interactive rebase — це спосіб переписати історію вашої гілки перед тим, як поділитися нею. Він дозволяє об'єднувати коміти разом, переформулювати повідомлення, змінювати порядок або видаляти їх повністю.
git rebase -i HEAD~5Це відкриває редактор з вашими останніми 5 комітами, від найстарішого:
pick a1b2c3d Add user authentication endpoint
pick d4e5f6g Fix typo in auth middleware
pick h7i8j9k Add rate limiting
pick l0m1n2o Fix rate limit bug
pick p3q4r5s Update auth testsКожен рядок починається з команди. Змініть pick на одну з цих:
squash (або s) — Об'єднати цей коміт з тим, що вище, поєднати повідомленняfixup (або f) — Те саме, що squash, але відкинути повідомлення цього комітуreword (або r) — Зберегти коміт, але змінити його повідомленняdrop (або d) — Видалити цей коміт повністюedit (або e) — Зупинити rebase на цьому коміті, щоб ви могли його змінитиОсь що я реально роблю. Та брудна історія вище перетворюється на:
pick a1b2c3d Add user authentication endpoint
fixup d4e5f6g Fix typo in auth middleware
pick h7i8j9k Add rate limiting
fixup l0m1n2o Fix rate limit bug
pick p3q4r5s Update auth testsЗбережіть і закрийте. Тепер у вас три чистих коміти замість п'яти. Виправлення помилки друку складається в коміт автентифікації. Виправлення бага rate limit складається в коміт rate limiting. Ваш ревю'ер PR бачить чистий, логічний прогрес.
Ви можете буквально переставляти рядки. Якщо коміт тестів повинен іти перед комітом rate limiting, просто перемістіть рядок:
pick a1b2c3d Add user authentication endpoint
pick p3q4r5s Update auth tests
pick h7i8j9k Add rate limitingGit переграє ваші коміти в цьому новому порядку. Якщо є конфлікти, він зупиниться і дасть вам їх вирішити.
Якщо ви знаєте, що коміт є виправленням попереднього, позначте це при коміті:
git commit --fixup=a1b2c3dЦе створює коміт з повідомленням fixup! Add user authentication endpoint. Потім при rebase:
git rebase -i --autosquash HEAD~5Git автоматично переставляє fixup-коміти прямо під їхні цілі та позначає їх як fixup. Ви просто зберігаєте і закриваєте. Без ручного редагування.
Я використовую це постійно. Це найшвидший спосіб ітерувати на гілці, зберігаючи фінальну історію чистою.
Ніколи не робіть rebase комітів, які вже запушені до спільної гілки. Якщо інші люди базували роботу на цих комітах, переписування історії спричинить реальні проблеми. Робіть rebase своїх власних feature-гілок перед мерджем. Ніколи не робіть rebase main.
Якщо ви вже запушили свою feature-гілку і потрібно зробити rebase:
git push --force-with-leaseПрапорець --force-with-lease безпечніший за --force. Він відмовляється пушити, якщо хтось інший запушив у ту ж гілку з часу вашого останнього fetch. Він не запобігає всім проблемам, але ловить найпоширенішу.
Cherry-pick бере конкретний коміт з однієї гілки та застосовує його до іншої. Не мердж. Не rebase. Просто один коміт, чисто застосований.
Найпоширеніший сценарій: я виправив баг на своїй feature-гілці, але виправлення також потрібно в main або release-гілці прямо зараз. Я не хочу мерджити всю свою feature-гілку. Я хочу лише це одне виправлення.
# Знайти хеш коміту виправлення
git log --oneline feature/user-auth
# a1b2c3d Fix null pointer in session validation
# Переключитися на main і cherry-pick
git checkout main
git cherry-pick a1b2c3dГотово. Виправлення на main як новий коміт з тими ж змінами.
Іноді ви хочете застосувати зміни, але не комітити їх ще. Можливо, ви хочете об'єднати кілька cherry-pick в один коміт або трохи модифікувати зміни:
git cherry-pick --no-commit a1b2c3dЗміни стейджені, але не закомічені. Ви можете їх модифікувати, додати більше змін, потім комітити, коли готові.
Потрібно кілька послідовних комітів? Використовуйте синтаксис діапазону:
git cherry-pick a1b2c3d..f6g7h8iЦе cherry-pick все після a1b2c3d до та включаючи f6g7h8i. Зверніть увагу, що сам a1b2c3d виключений. Якщо хочете його включити:
git cherry-pick a1b2c3d^..f6g7h8iКонфлікти cherry-pick працюють як конфлікти мерджу. Коли один виникає:
# Git скаже вам, що є конфлікт
# Виправте конфліктні файли, потім:
git add .
git cherry-pick --continueАбо якщо ви передумали:
git cherry-pick --abortОдне застереження: cherry-picked коміти створюють нові хеші комітів. Якщо ви пізніше мерджите оригінальну гілку, Git зазвичай достатньо розумний, щоб обробити дублювання. Але якщо ви агресивно cherry-pick між гілками, які врешті зімерджуються, можете побачити неочікувані конфлікти. Використовуйте хірургічно, а не як стратегію мерджу.
Щось зламалось. Ви знаєте, що воно працювало два тижні тому. Відтоді було 200 комітів. Який зламав?
Ви можете перевіряти кожен коміт вручну. Або можете використати git bisect, який використовує бінарний пошук для знаходження точного коміту-порушника за log2(n) кроків. Для 200 комітів це близько 7-8 перевірок замість 200.
# Почати bisect
git bisect start
# Позначити поточний коміт як поганий (баг існує тут)
git bisect bad
# Позначити відомий добрий коміт (баг тут не існував)
git bisect good v2.1.0Git переключає на коміт посередині між добрим і поганим. Протестуйте його. Потім:
# Якщо баг існує на цьому коміті:
git bisect bad
# Якщо баг не існує на цьому коміті:
git bisect goodGit звужує діапазон вдвічі кожен раз. Після 7-8 кроків він повідомляє:
a1b2c3d4e5f6g7h is the first bad commit
commit a1b2c3d4e5f6g7h
Author: Some Developer <dev@example.com>
Date: Tue Feb 18 14:23:01 2026 +0300
Refactor session handling to use async middlewareТепер ви знаєте точно, який коміт вніс баг. Коли закінчите:
git bisect resetЦе поверне вас туди, де ви почали.
Якщо у вас є тест, що може виявити баг, ви можете автоматизувати весь процес:
git bisect start
git bisect bad HEAD
git bisect good v2.1.0
git bisect run npm test -- --grep "session validation"Git автоматично переключатиме коміти, запускатиме тест і позначатиме їх як добрі або погані на основі коду виходу. Нуль означає добрий, не-нуль означає поганий. Відійдіть, поверніться, і він скаже вам точний коміт.
Ви можете використовувати будь-який скрипт:
git bisect run ./test-regression.shДе test-regression.sh це:
#!/bin/bash
npm run build 2>/dev/null || exit 125 # 125 означає "пропустити цей коміт"
npm test -- --grep "session" || exit 1 # 1 означає "поганий"
exit 0 # 0 означає "добрий"Код виходу 125 особливий — він каже bisect пропустити цей коміт (корисно, якщо коміт не компілюється). Це одна з тих можливостей, що здається нішевою, поки вона вам не знадобиться, і тоді вона зберігає вам цілий день.
Ось як це виглядає на практиці:
$ git bisect start
$ git bisect bad HEAD
$ git bisect good abc1234
Bisecting: 97 revisions left to test after this (roughly 7 steps)
[def5678...] Commit message here
$ npm test -- --grep "login flow"
# Тести падають
$ git bisect bad
Bisecting: 48 revisions left to test after this (roughly 6 steps)
[ghi9012...] Another commit message
$ npm test -- --grep "login flow"
# Тести проходять
$ git bisect good
Bisecting: 24 revisions left to test after this (roughly 5 steps)
...
# Після ~7 ітерацій:
abc1234def5678ghi is the first bad commitСім кроків, щоб знайти голку в стозі з 200 комітів.
Це найменш використовувана можливість Git. Я впевнений, що більшість розробників не знає про її існування.
Проблема: ви глибоко в feature-гілці. Файли змінені повсюди. Тоді хтось каже «можеш швиденько глянути цей продакшен-баг?» У вас три варіанти:
Або варіант 4: worktrees.
Worktree — це друга (або третя, або четверта) робоча директорія, пов'язана з тим самим репозиторієм. Кожен worktree має свою переключену гілку, свої робочі файли, свій індекс. Але вони ділять ті самі .git-дані, тож ви не дублюєте весь репозиторій.
# Ви на feature/user-auth, глибоко в роботі
# Потрібно виправити баг на main:
git worktree add ../hotfix-session mainЦе створює нову директорію ../hotfix-session з переключеним main. Ваша поточна директорія залишається точно такою, якою була. Нічого стешено, нічого комітнуто, нічого порушено.
cd ../hotfix-session
# Виправити баг
git add .
git commit -m "Fix null pointer in session validation"
git push origin main
cd ../my-project
# Продовжити роботу над своєю фічею, ніби нічого не трапилосьgit worktree add ../hotfix-nav -b hotfix/nav-crash mainЦе створює worktree І створює нову гілку hotfix/nav-crash на основі main.
# Перелічити всі worktrees
git worktree list
# /home/dev/my-project abc1234 [feature/user-auth]
# /home/dev/hotfix-session def5678 [main]
# Видалити worktree, коли закінчили
git worktree remove ../hotfix-session
# Якщо директорія вже видалена:
git worktree pruneСтеш підходить для швидких переключень контексту. Але worktrees кращі для будь-чого, що займає більше п'яти хвилин:
Зазвичай я тримаю два-три активних worktrees: мою основну feature-гілку, worktree main для швидких перевірок, і іноді worktree для ревю, де я перевіряю чийсь PR.
Ви не можете мати одну й ту ж гілку переключену в двох worktrees. Це зроблено навмисно — це запобігає конфліктним змінам однієї гілки в двох місцях. Якщо спробуєте, Git відмовить.
Ви зробили hard reset і втратили коміти. Видалили гілку. Зробили rebase і все пішло жахливо не так. Ви думаєте, що ваша робота зникла.
Ні. Git майже ніколи насправді нічого не видаляє. Reflog — ваша страхувальна сітка.
Кожного разу, коли HEAD переміщується — кожен коміт, checkout, rebase, reset, мердж — Git записує це в reflog. Це лог кожного місця, де був ваш HEAD, по порядку.
git reflogВивід:
a1b2c3d (HEAD -> main) HEAD@{0}: reset: moving to HEAD~3
f4e5d6c HEAD@{1}: commit: Add payment processing
b7a8c9d HEAD@{2}: commit: Update user dashboard
e0f1g2h HEAD@{3}: commit: Fix auth token refresh
i3j4k5l HEAD@{4}: checkout: moving from feature/payments to mainКожен запис має індекс (HEAD@{0}, HEAD@{1} тощо) і опис того, що відбулося.
Ви випадково виконали git reset --hard HEAD~3 і втратили три коміти. Вони прямо тут, у reflog:
# Подивіться, що ви втратили
git reflog
# Коміт перед скиданням — це HEAD@{1}
git reset --hard f4e5d6cВсі три коміти повернулися. Кризу відвернуто.
Ви видалили гілку з незмердженою роботою:
git branch -D feature/experimental
# Ой, там було два тижні роботиКоміти все ще існують. Знайдіть їх:
git reflog | grep "feature/experimental"
# Або просто перегляньте reflog на предмет останнього коміту на тій гілці
# Знайшли. Відтворити гілку на тому коміті:
git branch feature/experimental a1b2c3dГілка повернулася з усіма своїми комітами.
Ви зробили rebase і все пішло не так. Конфлікти всюди, неправильні коміти, хаос:
# Reflog показує, де ви були до rebase
git reflog
# a1b2c3d HEAD@{0}: rebase (finish): ...
# ...
# f4e5d6c HEAD@{5}: rebase (start): checkout main
# b7a8c9d HEAD@{6}: commit: Your last good commit
# Повернутися до стану перед rebase
git reset --hard b7a8c9dВи повернулися точно туди, де були до початку rebase. Ніби його ніколи не було.
За замовчуванням Git зберігає записи reflog 30 днів (90 днів для досяжних комітів). Після цього вони можуть бути зібрані збирачем сміття. Отже, у вас є місяць, щоб усвідомити помилку. На практиці цього більш ніж достатньо.
Ви можете перевірити термін дії:
git config gc.reflogExpire
# за замовчуванням: 90.days.ago (для досяжних)
git config gc.reflogExpireUnreachable
# за замовчуванням: 30.days.ago (для недосяжних)Якщо ви параноїк, збільшіть:
git config --global gc.reflogExpireUnreachable "180.days.ago"Перед будь-якою деструктивною операцією — hard reset, force push, видалення гілки — я спочатку виконую git log --oneline -10. Я подумки фіксую поточний HEAD. Це займає дві секунди і вже не раз врятувало мене від паніки, якої не потрібно було.
git stash#Більшість людей використовують стеш так:
git stash
# робимо щось
git stash popЦе працює, але це еквівалент кидання всього в коробку з написом «барахло». Коли у вас три стеші, ви поняття не маєте, який — який.
git stash push -m "WIP: user auth form validation"Тепер при переліку стешів:
git stash list
# stash@{0}: On feature/auth: WIP: user auth form validation
# stash@{1}: On main: Quick fix attempt for nav bug
# stash@{2}: On feature/payments: Experiment with Stripe webhooksВи бачите точно, що містить кожен стеш.
За замовчуванням git stash стешить лише відстежувані файли. Нові файли, які ви ще не додали, залишаються:
# Стешити все, включаючи нові файли
git stash push --include-untracked -m "WIP: new auth components"
# Або навіть включити ігноровані файли (рідко потрібно)
git stash push --all -m "Full workspace snapshot"Я використовую --include-untracked майже кожного разу. Залишання нових файлів при переключенні гілок спричиняє плутанину.
Це те, про що більшість людей не знає. Ви можете стешити конкретні файли:
# Стешити лише конкретні файли
git stash push -m "Just the auth changes" src/auth/ src/middleware.tsАбо використати patch-режим для стешування конкретних ханків всередині файлів:
git stash push --patch -m "Partial: only the validation logic"Git пройде через кожну зміну інтерактивно і запитає, чи хочете ви її стешити. y для так, n для ні, s для розділення ханку на менші частини.
# Pop: застосувати і видалити зі списку стешів
git stash pop stash@{2}
# Apply: застосувати, але залишити у списку стешів
git stash apply stash@{2}Я використовую apply, коли не впевнений, чи стеш застосується чисто. Якщо є конфлікт, стеш зберігається. З pop, якщо є конфлікт, стеш все одно залишається в списку (багато людей цього не знають), але я віддаю перевагу явному наміру apply.
# Подивитися, які файли змінились у стеші
git stash show stash@{0}
# Подивитися повний diff
git stash show -p stash@{0}Якщо ваш стеш виріс у щось більш суттєве:
git stash branch feature/auth-validation stash@{0}Це створює нову гілку від коміту, де ви спочатку стешили, застосовує стеш і видаляє його. Чисто.
Є три мейнстрімних стратегії гілкування. Кожна має контекст, де вона блищить, і контексти, де спричиняє біль.
Класика. main, develop, feature/*, release/*, hotfix/*. Створена Vincent Driessen у 2010 році.
# Feature-гілка
git checkout -b feature/user-auth develop
# ... робота ...
git checkout develop
git merge --no-ff feature/user-auth
# Release-гілка
git checkout -b release/2.1.0 develop
# ... фінальні виправлення ...
git checkout main
git merge --no-ff release/2.1.0
git tag -a v2.1.0 -m "Release 2.1.0"
git checkout develop
git merge --no-ff release/2.1.0
# Hotfix
git checkout -b hotfix/session-fix main
# ... виправлення ...
git checkout main
git merge --no-ff hotfix/session-fix
git checkout develop
git merge --no-ff hotfix/session-fixКоли працює: Мобільні застосунки, десктопне ПЗ, все з іменованими версійними релізами та одночасною підтримкою кількох версій. Якщо ви випускаєте v2.1 і v3.0 і потрібно патчити обидва, Gitflow це обробляє.
Коли не працює: Веб-застосунки з безперервним деплоєм. Якщо ви деплоїте в продакшен 5 разів на день, церемонія release-гілок і develop-гілок — чистий оверхед. Більшість веб-команд, що приймають Gitflow, закінчують з develop-гілкою, яка вічно зламана, і release-гілками, які ніхто не розуміє.
Просто. У вас є main. Ви створюєте feature-гілки. Ви відкриваєте PR. Ви мерджите в main. Ви деплоїте main.
git checkout -b feature/user-auth main
# ... робота ...
git push origin feature/user-auth
# Відкрити PR, отримати ревю, змерджити
# main завжди готовий до деплоюКоли працює: Малі та середні команди, що випускають веб-застосунки. Безперервний деплой. Якщо main завжди деплоїться, це все, що вам потрібно. Саме це використовує цей сайт.
Коли не працює: Коли потрібно підтримувати кілька release-версій, або коли є довгий цикл QA перед деплоєм. GitHub Flow припускає, що main швидко потрапляє в продакшен.
Усі комітять у main («trunk») напряму або через дуже короткоживучі гілки (менше дня). Жодних довготривалих feature-гілок.
# Короткоживуча гілка (мерджиться того ж дня)
git checkout -b fix/auth-token main
# ... маленька, сфокусована зміна ...
git push origin fix/auth-token
# PR ревю'ється та мерджиться протягом годин, не днівКоли працює: Високопродуктивні команди з хорошим CI/CD, комплексними тест-сюїтами та прапорами функцій. Google, Meta та більшість великих технологічних компаній використовують trunk-based development. Це змушує робити маленькі, інкрементальні зміни та усуває пекло мерджів.
Коли не працює: Команди без хорошого тестового покриття або CI. Якщо мердж у trunk означає деплой непротестованого коду, ви будете постійно ламати продакшен. Вам також потрібні прапори функцій для будь-чого, що займає більше дня:
# Прапор функції в коді
if (featureFlags.isEnabled('new-checkout-flow')) {
renderNewCheckout();
} else {
renderLegacyCheckout();
}Для більшості веб-команд розробки: починайте з GitHub Flow. Це просто, це працює, і не потребує інструментарію окрім того, що GitHub/GitLab вже надає.
Якщо ваша команда виросте за 15-20 інженерів і ви деплоїте кілька разів на день, зверніть увагу на trunk-based development з прапорами функцій. Інвестиції в інфраструктуру прапорів функцій окупаються зменшенням конфліктів мерджу та швидшою ітерацією.
Якщо ви випускаєте версійне ПЗ (мобільні застосунки, CLI-інструменти, бібліотеки): Gitflow або спрощена версія. Вам дійсно потрібні ці release-гілки.
Не вибирайте стратегію, тому що якийсь блог-пост сказав, що це найкраща. Виберіть ту, що відповідає тому, як ви реально випускаєте.
Git hooks — це скрипти, що запускаються автоматично в певних точках воркфлоу Git. Вони локальні для вашої машини (не пушаться на ремоут), що означає, що вам потрібен спосіб ділитися ними з командою.
pre-commit — Запускається перед кожним комітом. Використовуйте для лінтингу та форматування:
#!/bin/bash
# .git/hooks/pre-commit
# Запустити ESLint лише на стейджених файлах
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(js|ts|tsx)$')
if [ -n "$STAGED_FILES" ]; then
echo "Running ESLint on staged files..."
npx eslint $STAGED_FILES --quiet
if [ $? -ne 0 ]; then
echo "ESLint failed. Fix errors before committing."
exit 1
fi
fi
# Запустити Prettier на стейджених файлах
if [ -n "$STAGED_FILES" ]; then
echo "Running Prettier..."
npx prettier --check $STAGED_FILES
if [ $? -ne 0 ]; then
echo "Prettier check failed. Run 'npx prettier --write' first."
exit 1
fi
ficommit-msg — Валідує формат повідомлення коміту. Ідеально для впровадження conventional commits:
#!/bin/bash
# .git/hooks/commit-msg
COMMIT_MSG=$(cat "$1")
PATTERN="^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .{1,72}"
if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
echo "Invalid commit message format."
echo "Expected: type(scope): description"
echo "Example: feat(auth): add session refresh endpoint"
echo ""
echo "Valid types: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert"
exit 1
fipre-push — Запускається перед пушем. Використовуйте для тестів:
#!/bin/bash
# .git/hooks/pre-push
echo "Running tests before push..."
npm test
if [ $? -ne 0 ]; then
echo "Tests failed. Push aborted."
exit 1
fiНативні хуки живуть у .git/hooks/. Проблема: директорія .git не відстежується Git, тому ви не можете ділитися хуками через репозиторій. Кожен має налаштовувати їх вручну.
Husky вирішує це. Він зберігає конфігурації хуків у репозиторії та налаштовує .git/hooks автоматично при npm install:
npx husky initЦе створює директорію .husky/. Додавайте хуки як файли:
# .husky/pre-commit
npx lint-stagedУ поєднанні з lint-staged ви отримуєте швидкі, цілеспрямовані pre-commit перевірки:
{
"lint-staged": {
"*.{js,ts,tsx}": ["eslint --fix", "prettier --write"],
"*.css": ["prettier --write"],
"*.json": ["prettier --write"]
}
}Це запускає ESLint і Prettier лише на файлах, які ви фактично комітите. Не на всій кодовій базі. Швидко.
Іноді потрібно комітити без запуску хуків. Термінові hotfix-и, work-in-progress коміти на вашій власній гілці:
git commit --no-verify -m "WIP: debugging production issue"Використовуйте це помірковано. Якщо ви регулярно пропускаєте хуки, ваші хуки, ймовірно, надто повільні або надто суворі.
Мій .gitconfig еволюціонував роками. Це аліаси, що вижили — ті, якими я реально користуюсь щодня, а не ті, що я додав, бо вони виглядали розумно.
Стандартний git log багатослівний. Це дає вам чистий, кольоровий, графовий вигляд:
git config --global alias.lg "log --oneline --graph --all --decorate"Використання:
git lg
# * a1b2c3d (HEAD -> main) Fix session validation
# | * d4e5f6g (feature/payments) Add Stripe integration
# | * h7i8j9k Update payment models
# |/
# * l0m1n2o Merge PR #42
# * p3q4r5s Add user dashboardЯ запускаю це 20 разів на день. Це найшвидший спосіб зрозуміти стан вашого репозиторію.
Зберегти зміни, просто скасувати коміт:
git config --global alias.undo "reset HEAD~1 --mixed"Використання:
git undo
# Коміт зник, але всі зміни все ще у вашій робочій директоріїЯ використовую це, коли комічу занадто рано, забуваю файл або хочу реструктурувати зміни.
git config --global alias.unstage "reset HEAD --"Використання:
git unstage src/auth/session.ts
# Файл знятий зі стейджу, але зміни збереженіБо ви забудете, що налаштували:
git config --global alias.aliases "config --get-regexp ^alias\\."# Показати, що ви збираєтесь комітити
git config --global alias.staged "diff --staged"
# Короткий статус
git config --global alias.st "status -sb"
# Amend без зміни повідомлення
git config --global alias.amend "commit --amend --no-edit"
# Показати останній коміт
git config --global alias.last "log -1 HEAD --stat"
# Pull з rebase замість мерджу
git config --global alias.up "pull --rebase --autostash"
# Видалити гілки, що змерджені в main
git config --global alias.cleanup "!git branch --merged main | grep -v '^[ *]*main$' | xargs git branch -d"Аліас up особливо хороший. pull --rebase тримає вашу історію лінійною замість створення мердж-комітів при кожному pull. --autostash автоматично стешить і відновлює ваші зміни, якщо у вас є брудні файли. Ось яким pull мав бути за замовчуванням.
Аліас cleanup видаляє локальні гілки, що змерджені в main. З часом ви накопичуєте десятки застарілих гілок. Запускайте це щотижня.
Це не аліаси чи просунуті можливості. Це просто команди, які я постійно виконую, і про які багато розробників, здається, не знає.
git log --oneline --graph --allЦе показує кожну гілку, кожен мердж, всю топологію вашого репозиторію в компактному вигляді. Це перше, що я запускаю, коли підтягую зміни. Вона відповідає на запитання «що зараз відбувається в цьому репозиторії?»
git diff --stagedЦе показує, що збирається бути комітнутим. Не те, що змінилось у вашій робочій директорії — те, що фактично стейджено. Я завжди запускаю це перед комітом. Завжди. Це ловить випадкові включення, debug-інструкції, console.log, яких не повинно бути.
# Подивитися нестейджені зміни
git diff
# Подивитися стейджені зміни
git diff --staged
# Подивитися обидва
git diff HEADgit show a1b2c3dПоказує повний diff окремого коміту. Корисно при перегляді історії, розумінні того, що коміт фактично змінив.
# Показати лише файли, що змінились
git show --stat a1b2c3d
# Показати конкретний файл на конкретному коміті
git show a1b2c3d:src/auth/session.tsОстаннє неймовірно корисне. Ви можете переглянути будь-який файл у будь-якій точці історії, не переключаючи коміт.
git blame -L 42,60 src/auth/session.tsПоказує, хто останнім модифікував рядки 42-60. Корисніше, ніж blame всього файлу, що зазвичай перевантажує.
# Показати повідомлення коміту теж, не лише хеш
git blame -L 42,60 --show-name src/auth/session.ts
# Ігнорувати зміни пробілів (дуже корисно)
git blame -w -L 42,60 src/auth/session.ts
# Показати коміт перед blamed (копати глибше)
git log --follow -p -- src/auth/session.tsПрапорець -w важливий. Без нього blame приписуватиме рядки тому, хто останнім переформатував файл, а це рідко та людина, яку ви шукаєте.
# Знайти, коли функція була додана або видалена
git log -S "validateSession" --oneline
# Знайти, коли з'явився regex-патерн
git log -G "session.*timeout" --oneline-S («кирка») знаходить коміти, де кількість входжень рядка змінилась. -G знаходить коміти, де diff відповідає regex. Обидва потужні для археології — з'ясування, коли щось було введено або видалено.
# Що змінилось між двома гілками
git diff main..feature/auth
# Що змінилось на цій гілці з моменту відгалуження від main
git diff main...feature/auth
# Перелічити лише змінені файли
git diff main...feature/auth --name-only
# Статистичний вигляд (файли + вставки/видалення)
git diff main...feature/auth --statДві крапки проти трьох крапок має значення. Дві крапки показують різницю між кінцями обох гілок. Три крапки показують, що змінилось на правій стороні з моменту відгалуження від лівої. Три крапки — це зазвичай те, що ви хочете при ревю feature-гілки.
# Подивитися, що було б видалено (пробний запуск)
git clean -n
# Видалити невідстежувані файли
git clean -f
# Видалити невідстежувані файли та директорії
git clean -fd
# Видалити невідстежувані та ігноровані файли (ядерний варіант)
git clean -fdxЗавжди запускайте з -n спочатку. git clean -fdx видалить ваші node_modules, .env, артефакти збірки — все, що не відстежується Git. Корисно для справді свіжого старту, але деструктивно.
# Отримати версію файлу з main-гілки без переключення гілок
git restore --source main -- src/config/database.tsАбо з конкретного коміту:
git restore --source a1b2c3d -- src/config/database.tsЦе чистіше, ніж старий синтаксис git checkout main -- path/to/file, і не впливає на HEAD.
Ось як виглядає типовий день з цими інструментами:
# Ранок: перевірити, що відбувається
git lg
git fetch --all
# Почати фічу
git checkout -b feature/session-refresh main
# Працювати, комітити інкрементально
git add -p # Стейджити конкретні ханки, не цілі файли
git commit -m "Add token refresh endpoint"
git commit -m "Add refresh token rotation"
git commit -m "Fix: handle expired refresh tokens"
git commit -m "Add integration tests"
# Перервано: потрібно виправити продакшен-баг
git worktree add ../hotfix main
cd ../hotfix
# ... виправити, комітнути, запушити, PR змерджено ...
cd ../my-project
git worktree remove ../hotfix
# Назад до роботи над фічею
git commit -m "Fix edge case in token validation"
# Готовий до PR: очистити історію
git rebase -i main
# Об'єднати fix-коміти, переформулювати для ясності
# Запушити та відкрити PR
git push -u origin feature/session-refresh
# Щось зламалось на стейджингу? Знайти який коміт:
git bisect start
git bisect bad HEAD
git bisect good main
git bisect run npm test
# Ой, я скинув не те
git reflog
git reset --hard HEAD@{2}Кожна з цих команд займає секунди. Разом вони економлять години. Не гіпотетичні години — реальні години, щотижня, які я б інакше витратив на розплутування Git-месів, ручний пошук багів або втрату роботи через переключення контексту.
Git — це інструмент, що винагороджує глибину. Основи проведуть вас через день. Але команди в цій статті — це те, що розділяє «я використовую Git» від «Git реально робить мене швидшим». Вивчайте їх інкрементально. Виберіть одну нову техніку цього тижня та використовуйте її, поки вона не стане м'язовою пам'яттю. Потім виберіть іншу.
Ваше майбутнє я, що дивиться на продакшен-баг о 23:00, подякує вам за знання git bisect.