Конфигурация и инициализация
Глобальная и локальная конфигурация
Git хранит конфигурацию на трёх уровнях: system (/etc/gitconfig), global (~/.gitconfig для пользователя) и local (.git/config для репозитория). Нижние уровни переопределяют верхние. Всегда устанавливайте user.name и user.email перед коммитом, иначе коммиты будут использовать бесполезную идентичность по умолчанию. Установка init.defaultBranch в main избегает устаревшего значения master и соответствует современным соглашениям.
# set user identity (required for commits)
git config --global user.name "Alice Lee"
git config --global user.email "[email protected]"
# set default editor and branch name
git config --global core.editor "code --wait"
git config --global init.defaultBranch main
# view all settings and their origin
git config --list --show-origin
# edit config files directly
git config --global --edit # ~/.gitconfig
git config --edit # repo .git/configСоздание и клонирование репозиториев
git init создаёт пустой репозиторий, добавляя скрытую директорию .git, хранящую все данные версий. git clone копирует удалённый репозиторий, включая полную историю. Используйте --depth 1 для поверхностного клона, когда нужен только последний снимок (например, CI-сборки) — это значительно уменьшает размер загрузки. --single-branch избегает получения несвязанных веток.
# create a new repo from scratch in current dir
mkdir my-app && cd my-app
git init
# clone a remote repository
git clone https://github.com/user/repo.git
# clone into a specific folder name
git clone https://github.com/user/repo.git my-folder
# clone a single branch (saves bandwidth)
git clone -b dev --single-branch https://github.com/user/repo.git
# shallow clone: only the latest commit
git clone --depth 1 https://github.com/user/repo.gitАлиасы и ярлыки
Алиасы позволяют определять более короткие имена для часто используемых команд или последовательностей команд. Они хранятся в секции [alias] вашего gitconfig. Алиас, начинающийся с !, выполняется как команда оболочки, обеспечивая сложные рабочие процессы. Алиас lg выше создаёт компактный визуальный граф истории, крайне полезный для понимания структуры веток.
# create shortcuts for common commands
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.lg "log --oneline --graph --all"
# now use them
git co main
git lg
# alias that runs an external command (starts with !)
git config --global alias.unstage "reset HEAD --"
git unstage file.txtСправка и документация
Git поставляется с исчерпывающей встроенной документацией. git help <command> открывает man-страницу в пейджер е. Флаг -h даёт быструю одноэкранную сводку опций. Руководства (git help -g) включают учебник, глоссарий терминов и справочник повседневного рабочего процесса — отлично для новичков, изучающих терминологию.
# open the full manual for a command
git help commit
git commit --help
# show a concise synopsis
git commit -h
# list all git commands
git help -a
# list all guides (tutorial, glossary, etc.)
git help -g
git help glossaryШаблоны .gitignore
.gitignore указывает Git, какие файлы исключить из контроля версий — необходимо для артефактов сборки, зависимостей и секретов. Шаблоны используют glob-синтаксис; завершающий слеш соответствует директориям. Префикс ! инвертирует шаблон, принуждая файл отслеживаться. Сам .gitignore следует коммитить, чтобы команда разделяла правила игнорирования. Уже отслеживаемые файлы не затрагиваются новыми шаблонами игнорирования — сначала удалите их через git rm --cached.
# .gitignore file — patterns for files to skip
node_modules/
*.log
.env
.env.local
dist/
build/
# but track this specific file even if it matches
!important.log
# ignore all .txt files in build/ but not subdirs
build/*.txt
# ignore everything in a folder except one file
secrets/*
!secrets/template.envИндексирование и коммиты
Статус и индексирование
Git использует двухшаговую модель: изменения попадают в область индексирования (index) перед коммитом. git status показывает, что изменено, индексировано и не отслеживается. git add -p позволяет индексировать отдельные части патча — бесценно для разбиения беспорядочного рабочего дерева на сфокусированные, логичные коммиты. Используйте git restore --staged (современная команда) для отмены индексирования без потери правок.
# see current state of working tree
git status
git status -s # short format
git status -sb # short + branch info
# stage changes
git add file.txt # one file
git add src/ # a directory
git add . # all changes in repo
git add -p # stage interactively by hunk
# unstage a file (keep changes in working dir)
git restore --staged file.txt
git reset HEAD file.txt # older syntaxКоммит изменений
Коммит фиксирует снимок индексированных изменений. Пишите сообщения в повелительном наклонении ('add feature', а не 'added feature'). Флаг -a индексирует только уже отслеживаемые файлы — новые файлы всё равно требуют git add. --amend переписывает последний коммит; используйте для исправления опечатки или добавления забытого файла, но никогда не правьте коммиты, уже отправленные в общую ветку.
# commit staged changes with a message
git commit -m "feat: add login form"
# multi-line commit message
git commit -m "feat: add login form" -m "Closes #42"
# stage tracked files AND commit in one step
git commit -am "fix: correct typo"
# amend the previous commit (keep message)
git commit --amend --no-edit
# amend and edit the message
git commit --amend -m "feat: add login form (v2)"Соглашения о сообщениях коммитов
Conventional Commits — широко распространённая спецификация для структурированных сообщений коммитов. Префикс типа (feat, fix, docs и т. д.) включает автоматическую генерацию changelog и семантическое версионирование. Маркер ! указывает на ломающее изменение. Пустая строка отделяет тему (<=50 символов) от тела, и ещё одна пустая строка отделяет футеры вроде 'Closes #123', которые автоматически закрывают issues на GitHub.
# Conventional Commits format
feat: add user registration endpoint
fix: resolve crash on empty cart
docs: update API reference
style: format login component
refactor: extract validation logic
test: add unit tests for parser
chore: upgrade dependencies
# with scope and breaking change marker
feat(api): add pagination to list endpoint
fix!: change default port (BREAKING CHANGE)
# with body and footer
feat: add dark mode
Implement theme toggle using CSS variables.
Closes #128Просмотр истории с log
git log — основной инструмент для исследования истории. --oneline --graph --all — наиболее полезная комбинация для понимания структуры веток с одного взгляда. Можно фильтровать по автору, диапазону дат или содержимому сообщения через --grep. --stat показывает, какие файлы изменились и сколько строк, а --patch показывает полный diff каждого коммита.
# full history with details
git log
git log --oneline # one line per commit
git log --oneline --graph --all # visual branch graph
git log -n 5 # last 5 commits
# filter by author, date, or message
git log --author="Alice"
git log --since="2 weeks ago"
git log --grep="fix"
# show files changed in each commit
git log --stat
git log --patch # full diffsDiff и Show
git diff сравнивает снимки — без аргументов показывает неиндексированные изменения относительно index. --staged сравнивает index с HEAD. git show отображает метаданные и патч одного коммита. Синтаксис HEAD:path позволяет просматривать содержимое любого файла на любом коммите без checkout — удобно для восстановления старых версий или изучения истории.
# compare working tree, index, and commits
git diff # unstaged changes
git diff --staged # staged but uncommitted
git diff HEAD # all changes vs last commit
git diff main feature # compare two branches
git diff abc1234 def5678 # compare two commits
# inspect a single commit
git show HEAD # latest commit diff + metadata
git show abc1234
git show HEAD:file.txt # view a file at a given commitВетвление и слияние
Создание и переключение веток
Ветки в Git — лёгкие указатели на коммит — создание почти мгновенно. git switch (Git 2.23+) — современная, безопасная альтернатива checkout для смены веток, оставляющая checkout для восстановления файлов. -d отказывается удалять несмещённую ветку (защищая работу); -D форсирует удаление. Всегда удаляйте ветки после слияния для чистоты списка веток.
# list branches
git branch # local branches
git branch -a # local + remote
git branch -vv # with tracking info
# create and switch
git branch feature # create only
git checkout feature # switch to it
git checkout -b feature # create + switch (classic)
git switch -c feature # create + switch (modern)
# delete branches
git branch -d feature # safe delete (merged only)
git branch -D feature # force deleteСлияние веток
Fast-forward слияние просто сдвигает указатель ветки вперёд, когда цель не имеет новых коммитов — создавая линейную историю. --no-ff форсирует merge-коммит, сохраняя факт существования ветки (полезно для отслеживания фич). --squash объединяет все коммиты ветки в одно индексированное изменение, которое вы затем коммитите один раз — отлично для очистки шумной истории фичи перед интеграцией в main.
# merge feature into main
git checkout main
git merge feature
# fast-forward merge (default when possible)
# main just moves forward to feature's commit
# create a merge commit (preserves branch history)
git merge --no-ff feature -m "Merge feature branch"
# squash all feature commits into one
git merge --squash feature
git commit -m "feat: add feature (squashed)"
# abort a merge with conflicts
git merge --abortРазрешение конфликтов слияния
Конфликты возникают, когда одни и те же строки изменены по-разному в двух ветках. Git вставляет маркеры конфликта (<<<<<<<, =======, >>>>>>>), показывающие обе стороны. Разрешите, отредактировав файл до желаемого финального состояния, затем git add для отметки разрешённым. Коммит для завершения слияния. git mergetool запускает визуальный diff-инструмент. Если растеряны, git merge --abort возвращает в предмержевое состояние.
# a conflict produces markers in the file
# <<<<<<< HEAD
# my changes (current branch)
# =======
# their changes (incoming branch)
# >>>>>>> feature
# edit the file to resolve, then:
git add resolved-file.txt
git commit # finalize the merge
# use a merge tool
git mergetool
# see which files conflict
git status
# abandon the merge
git merge --abortRebase
Rebase воспроизводит коммиты вашей ветки поверх другой ветки, создавая линейную историю без merge-коммитов. Интерактивный rebase (-i) — мощный инструмент: squash объединяет коммиты, reword редактирует сообщения, drop удаляет коммиты, edit приостанавливает для изменения коммита. НИКОГДА не делайте rebase коммитов, уже отправленных и общих — это переписывает историю и ломает репозитории товарищей. Используйте rebase только на собственных локальных ветках.
# rebase feature onto main (replay feature commits)
git checkout feature
git rebase main
# interactive rebase — rewrite last 5 commits
git rebase -i HEAD~5
# options: pick, reword, squash, fixup, drop, edit
# continue, skip, or abort during a rebase
git rebase --continue
git rebase --skip
git rebase --abort
# rebase while pulling
git pull --rebase origin mainCherry-pick и reflog
Cherry-pick применяет отдельный коммит из другой ветки на текущую — полезно для обратного порта багфикса без слияния всей ветки. Reflog — локальный журнал каждого движения HEAD (коммиты, checkout, reset), хранящийся ~90 дней. Это ваша страховка: даже после разрушительного reset можно найти старый хеш коммита в reflog и восстановить его. Данные reflog только локальные и никогда не отправляются.
# apply a specific commit onto current branch
git cherry-pick abc1234
git cherry-pick abc1234 def5678 # multiple commits
git cherry-pick abc1234..def5678 # range (exclusive start)
# reflog: record of where HEAD has been
git reflog
git reflog show feature
# recover a 'lost' commit
git reset --hard HEAD@{2}
# view a branch's history of moves
git reflog show mainУдалённые репозитории
Управление remote'ами
Remote — именованная ссылка на другой репозиторий, обычно origin для вашего fork и upstream для исходного проекта. git remote -v показывает URL fetch и push. Fork'и на GitHub используют remote upstream для синхронизации с оригиналом: fetch из upstream, merge или rebase, затем push в origin. set-url удобен для переключения между HTTPS и SSH аутентификацией.
# list configured remotes
git remote -v
git remote show origin
# add a remote
git remote add origin https://github.com/user/repo.git
# add an upstream remote (for forks)
git remote add upstream https://github.com/original/repo.git
# rename or remove
git remote rename origin upstream
git remote remove origin
# change a remote URL (e.g. HTTPS to SSH)
git remote set-url origin [email protected]:user/repo.gitFetch, Pull и Push
fetch скачивает удалённые данные, но не трогает рабочее дерево — безопасно для проверки перед слиянием. pull = fetch + merge (или rebase с --rebase). Первый push новой ветки требует -u для настройки отслеживания, чтобы будущие git push/pull работали без аргументов. --force-with-lease — безопасная альтернатива --force: перезаписывает remote только если никто другой не отправил изменения, предотвращая случайное затирание работы товарищей.
# download remote changes without merging
git fetch origin
git fetch --all --prune # all remotes, drop deleted branches
# fetch + merge in one step
git pull
git pull --rebase # rebase instead of merge
# push local commits to remote
git push origin main
git push -u origin feature # push + set upstream tracking
git push # subsequent pushes (uses tracking)
# force push (rewrites remote history — DANGER)
git push --force-with-lease # safer than --forceОтслеживание и синхронизация веток
Отслеживающие ветки связывают локальную ветку с удалённой, чтобы git pull и git push знали, куда fetch/push без указания. -u (сокращение от --set-upstream-to) устанавливает это при первом push. Когда товарищи удаляют удалённые ветки, ваши локальные remote-tracking refs устаревают — git remote prune origin очищает их. git fetch --prune делает это автоматически при fetch.
# set upstream for current branch
git branch -u origin/main
git branch --set-upstream-to=origin/main
# create a local branch tracking a remote one
git checkout -b feature origin/feature
git switch feature # auto-detects tracking branch
# delete a remote branch
git push origin --delete feature
# list all remote-tracking branches
git branch -r
git remote prune origin # remove stale remote refsРабочий процесс Pull Requests
Стандартный GitHub-поток: создайте ветку фичи, отправьте, откройте Pull Request для ревью и удалите ветку после слияния. Для fork'ов remote upstream позволяет тянуть изменения из исходного репозитория. Регулярная синхронизация main вашего fork с upstream предотвращает большие, болезненные слияния позже. Многие команды включают 'auto-delete branch on merge' для чистоты списка веток.
# typical feature workflow
git checkout -b feature/login
# ... make changes, commit ...
git push -u origin feature/login
# create PR on GitHub, then after merge:
git checkout main
git pull origin main
git branch -d feature/login
# sync a fork with its upstream
git fetch upstream
git checkout main
git merge upstream/main
git push origin mainBare-репозитории и зеркала
Bare-репозиторий не имеет рабочего дерева — хранит только данные .git. Bare-репозитории используются на серверах (как self-hosted Git) как центральный remote, в который несколько людей push и pull. --mirror клонирует всё, включая remote-tracking refs, и используется для резервных копий или миграции репозитория между хостами. --all отправляет все ветки; --tags отправляет все теги.
# create a bare repo (no working tree) — for servers
git init --bare project.git
# mirror clone (full copy including all refs)
git clone --mirror https://github.com/user/repo.git
# push all branches and tags
git push --all
git push --tags
# push a specific branch to a specific remote
git push origin local-name:remote-nameОтмена изменений
Reset: Soft, Mixed, Hard
reset перемещает указатель текущей ветки. --soft сохраняет изменения индексированными (отменяется только коммит) — идеально для перекоммита. --mixed (по умолчанию) убирает из индекса, но сохраняет изменения рабочего дерева. --hard навсегда отбрасывает всё — единственное восстановление через reflog. Никогда не используйте --hard на отправленных коммитах, так как это переписывает общую историю и вызывает расхождение.
# reset moves HEAD and optionally the index/worktree
git reset --soft HEAD~1 # undo commit, keep staged
git reset --mixed HEAD~1 # undo commit + unstage (DEFAULT)
git reset --hard HEAD~1 # undo commit + discard changes
# reset to a specific commit
git reset --hard abc1234
# reset a single file to HEAD
git reset HEAD file.txt # unstage
git checkout -- file.txt # discard working changesRevert (безопасная отмена)
В отлич ие от reset (который переписывает историю), revert добавляет новый коммит, инвертирующий целевой — безопасно для общих веток, так как история сохранена. Это правильный способ отменить уже отправленное изменение. Reverting merge-коммита требует -m 1 для указания, какую родительскую линию сохранить (1 = ветка, в которую слили).
# revert creates a NEW commit that undoes another
git revert abc1234
git revert HEAD # undo last commit
# revert a range
git revert HEAD~3..HEAD
# revert without committing (stage the inverse)
git revert --no-commit abc1234
# revert a merge commit
git revert -m 1 abc1234 # -m 1 = keep main branch parentRestore и Clean
git restore (Git 2.23+) — современная, сфокусированная команда для операций с рабочим деревом, разделяющая задачи с checkout. --staged убирает из индекса, не трогая рабочие изменения. git clean удаляет неотслеживаемые файлы — всегда запускайте с -n (dry run) для предпросмотра удаляемого. -x агрессивен: также удаляет gitignored файлы, что полезно для чистой сборки, но может стереть секреты или выходные данные сборки.
# discard unstaged changes in a file
git restore file.txt
git checkout -- file.txt # older syntax
# unstage a file (keep working changes)
git restore --staged file.txt
# restore a file from a specific commit
git restore --source=abc1234 file.txt
# remove untracked files
git clean -n # dry run (preview)
git clean -fd # remove untracked files + dirs
git clean -fdx # also remove ignored filesAmend и Fixup
--amend переписывает последний коммит — удобно для исправления опечатки или добавления забытого файла, но никогда не правьте отправленные коммиты. Рабочий процесс fixup элегантен: создавайте fixup-комми ты по мере обнаружения мелких проблем, затем git rebase -i --autosquash автоматически переупорядочивает и сжимает их в целевые коммиты. Это сохраняет историю чистой, позволяя коммитить мелкие исправления инкрементально.
# amend the last commit (message + content)
git add forgotten-file.txt
git commit --amend --no-edit
# change only the commit message
git commit --amend -m "better message"
# create a fixup commit (for later autosquash)
git commit --fixup=abc1234
# squash fixups during interactive rebase
git rebase -i --autosquash abc1234~1Восстановление через reflog
Reflog — ваша страховка. Он записывает каждый коммит, checkout, reset и rebase — даже операции, «уничтожающие» коммиты. Записи сохраняются ~90 дней. Если случайно reset --hard или удалили ветку, найдите хеш осиротевшего коммита в reflog и reset к нему или создайте новую ветку, указывающую на него. Reflog только локальный, поэтому это работает даже офлайн.
# reflog records every HEAD movement
git reflog
# abc1234 HEAD@{0}: reset: moving to abc1234
# def5678 HEAD@{1}: commit: feat: add x
# ghi9012 HEAD@{2}: checkout: moving to feature
# recover a 'lost' commit
git reset --hard def5678
# recover a deleted branch
git branch recovered-feature def5678
# reflog for a specific branch
git reflog show featureStashing и рабочие процессы
Stashing изменений
Stash откладывает незакоммиченные изменения, позволяя переключать ветки или тянуть обновления с чистым деревом. apply сохраняет stash в списке (полезно, если хотите применить к нескольким веткам); pop пр именяет и удаляет. Stash'и — стек LIFO, на который ссылаются stash@{N}. Используйте clear с осторожностью — навсегда отбрасывает все stash'и.
# save uncommitted changes (reverts working tree to HEAD)
git stash
git stash push -m "wip: login form" # with a message
# list, show, apply
git stash list
git stash show -p stash@{0} # show diff
git stash apply # apply latest, keep stash
git stash pop # apply latest, drop stash
# apply a specific stash
git stash apply stash@{2}
# drop a stash
git stash drop stash@{0}
git stash clear # drop ALL stashesЧастичный и выборочный stash
Эти флаги дают тонкий контроль над тем, что попадает в stash. --keep-index полезен, когда вы индексировали логический коммит, но хотите протестировать только эти изменения — спрячьте остальное, запустите тесты, затем pop. -u включает неотслеживаемые файлы (иначе они остаются в рабочем дереве). -p позволяет выбирать конкретные части, зеркалируя git add -p.
# stash only staged changes
git stash --staged
# stash only unstaged changes (keep staged)
git stash --keep-index
# stash interactively by hunk
git stash -p
# stash including untracked files
git stash -u
git stash --include-untracked
# stash everything (even ignored)
git stash -aStash-ветки и create
git stash branch создаёт новую ветку на родительском коммите stash'а и применяет stash там — идеально, когда stash больше не применяется чисто к текущей ветке из-за конфликтов. Также можно экспортировать stash как файл патча через show -p для архивации или sharing. Stash'и локальны и никогда не отправляются, поэтому не должны использоваться для длительного хранения.
# create a branch from a stash (great for conflicts)
git stash branch feature/wip stash@{0}
# create a commit from a stash without applying
git stash store -m "saved wip" stash@{0}
# apply a stash to a different branch
git checkout other-branch
git stash apply stash@{0}
# inspect stash contents
git stash show stash@{0} --stat
git stash show -p stash@{0} > patch.diffМодели рабочего процесса Git
GitHub Flow — простейший: одна ветка main, ветки фич с PR, развёртывание при слиянии — идеально для непрерывного развёртывания. Git Flow (модель Vincent Driessen) добавляет ветки develop, release и hotfix для структурированного управления релизами — подходит для версионных продуктов. Trunk-Based Development использует очень короткоживущие ветки и предпочитается высокопроизводительными DevOps-командами для максимальной скорости интеграции.
# GitHub Flow (simple, popular)
# main is always deployable; feature branches + PRs
git checkout -b feature/x
git push -u origin feature/x
# open PR, review, merge to main, deploy
# Git Flow (structured, with release branches)
# main: production releases
# develop: integration branch
# feature/*: features off develop
# release/*: release prep
# hotfix/*: urgent fixes off main
# Trunk-Based Development
# short-lived branches (1-2 days), frequent rebase on mainSubmodules
Submodules встраивают один Git-репозиторий в другой — полезно для разделения библиотеки между проектами, сохраняя её версионируемой независимо. Родительский репозиторий хранит указатель на конкретный коммит submodule. Клоны не получают содержимое submodule по умолчанию; --recurse-submodules делает это за один шаг. Submodules могут быть капризными; для более простого управления зависимостями рассмотрите Git subtrees или пакетный менеджер.
# add another repo as a submodule
git submodule add https://github.com/user/lib.git libs/lib
# clone a repo with its submodules
git clone --recurse-submodules https://github.com/user/repo.git
# initialize submodules in an existing clone
git submodule update --init --recursive
# update submodules to their latest remote commit
git submodule update --remote
# record a submodule pointer change
git add libs/lib
git commit -m "chore: bump lib submodule"Инспекция и отладка
Blame и annotate
git blame (также называемый annotate) показывает коммит и автора для каждой строки файла — необходимо для понимания, почему код выглядит так. -L ограничивает диапазоном строк, полезно для больших файлов. -w игнорирует чистые изменения пробелов, а -C обнаруживает код, перемещённый или скопированный из другого файла, давая более точную историю происхождения строк.
# show who last changed each line
git blame file.txt
git blame -L 10,20 file.txt # only lines 10-20
git blame -e file.txt # show author email
git blame -w file.txt # ignore whitespace changes
git blame -C file.txt # detect moved lines across files
# GUI annotation in some editors
git gui blame file.txtBisect (бинарный поиск багов)
bisect выполняет бинарный поиск по истории для точного определения коммита, внедрившего баг. Вы помечаете известный-хороший и известный-плохой коммит; Git checkout'ит середину, вы тестируете, затем помечаете good или bad, уменьшая диапазон вдвое каждый раз. Со скриптом весь процесс полностью автоматизирован — огромная экономия времени для регрессий в больших историях.
# find the commit that introduced a bug
git bisect start
git bisect bad # current commit is broken
git bisect good v1.0.0 # v1.0.0 was working
# Git checks out a midpoint; test it, then:
git bisect good # or git bisect bad
# automate with a script that exits non-zero on bug
git bisect start HEAD v1.0.0 -- npm test
# finish and return to original branch
git bisect reset
# view the bisect log
git bisect logПоиск кода и истории
git grep ищет по отслеживаемым файлам в рабочем дереве — быстрее, чем grep -r, так как использует index. Опция -S 'pickaxe' находит коммиты, добавившие или удалившие конкретную строку, бесценно для отслеживания, когда функция или баг были внедрены. -G похож, но соответствует regex где угодно в diff. Сочетая с фильтрами --author и --since, можно точно определить любое изменение в истории.
# search working tree for a string
git grep "TODO"
git grep -n "TODO" -- "*.js"
git grep -i "error" src/
# search across all commits (history)
git log -S "functionName" --oneline # pickaxe: when added/removed
git log -G "functionName.*\(" --oneline # regex match in diffs
# search commit messages
git log --grep="fix.*login" --oneline
git log --author="Alice" --since="1 week ago"FSCK и висячие объекты
git fsck (file system check) проверяет целостность базы объектов и может найти висячие коммиты — полезно для восстановления, когда reflog недостаточен. git gc реорганизует и сжимает объекты для экономии места на диске; --prune=now немедленно удаляет недостижимые объекты. Git периодически auto-gc, но ручной запуск может сжать большой репозиторий. --aggressive пересчитывает дельты для максимального сжатия.
# check repository integrity
git fsck --full
git fsck --unreachable
# find dangling (unreachable) commits & blobs
git fsck --lost-found
# garbage collect and prune old objects
git gc
git gc --prune=now
git gc --aggressive
# count objects and disk usage
git count-objects -vArchive и Bundle
git archive экспо ртирует чистый снимок коммита без директории .git — идеально для распространения релизов или отправки исходного кода тому, кому не нужна история. git bundle упаковывает репозиторий (или диапазон коммитов) в один файл, который можно clone или fetch — идеально для передачи репозиториев через изолированные сети или по email, когда нельзя использовать удалённый сервер.
# export a snapshot as a tar/zip (no .git history)
git archive --format=zip --output=app.zip HEAD
git archive --format=tar HEAD | gzip > app.tar.gz
git archive -o release.zip v1.0.0
# bundle a repo (with history) into a single file
git bundle create repo.bundle --all
git bundle create patch.bundle main..feature
# clone from a bundle (offline transfer)
git clone repo.bundle new-repo
git fetch patch.bundle featureПродвинутые техники
Hooks
Hooks — скрипты, автоматически запускающиеся в определённых точках. Клиентские hooks (pre-commit, commit-msg, pre-push) обеспечивают локальную политику вроде линтинга или тестов. Серверные hooks (pre-receive, post-receive) запускаются на remote и могут обеспечивать защиту веток или запускать CI/CD. Директория .git/hooks содержит образцы скриптов с суффиксом .sample — переименуйте для активации. Инструменты вроде Husky или pre-commit framework управляют hooks в самом репозитории для согласованности команды.
# client-side hooks live in .git/hooks/
# pre-commit runs before a commit is created
# commit-msg validates the commit message
# pre-push runs before pushing to remote
# sample pre-commit hook (.git/hooks/pre-commit)
#!/bin/sh
npm run lint || exit 1
npm test || exit 1
# server-side hooks (on the remote)
# pre-receive, update, post-receive
# make a hook executable
chmod +x .git/hooks/pre-commitWorktrees
Worktrees позволяют иметь несколько рабочих директорий для одного репозитория, каждая на своей ветке — без клонирования. Это бесценно, когда нужно работать над hotfix, сохраняя рабочее дерево ветки фичи, или запускать долгую сборку на одной ветке, редактируя другую. Все worktrees разделяют одну базу объектов .git, поэтому использование диска минимально.
# create a second working tree of the same repo
git worktree add ../app-feature feature/x
# list worktrees
git worktree list
# create a worktree with a new branch
git worktree add -b hotfix/y ../app-hotfix main
# remove a worktree
git worktree remove ../app-feature
# prune stale worktree metadata
git worktree pruneФильтрация и переписывание истории
Переписывание истории необходимо, когда секреты или большие файлы были закоммичены. git filter-repo — современная, быстрая замена git filter-branch. BFG Repo-Cleaner — дружелюбная альтернатива для удаления больших файлов или шаблонов паролей. После переписывания нужно force-push и уведомить всех коллабораторов о повторном clone — старые коммиты остаются в их reflog до истечения. Всегда немедленно ротируйте любые утёкшие секреты.
# remove a file from ALL of history (sensitive data)
git filter-repo --path secrets.env --invert-paths
# (install git-filter-repo; the old filter-branch is deprecated)
# rewrite author info across all commits
git filter-repo --mailmap mailmap.txt
# split a subdirectory into its own repo
git filter-repo --subdirectory-filter libs/lib
# the simpler BFG Repo-Cleaner (Java tool)
bfg --delete-files *.env
bfg --replace-text passwords.txtSparse Checkout и Partial Clone
Partial clone (--filter) получает коммиты и деревья, но скачивает blobs (содержимое файлов) лениво по мере обращения — значительно ускоряя clone огромных репозиториев. Sparse checkout ограничивает рабочее дерево конкретными директориями, поэтому вы видите только части, над которыми работаете. Вместе они делают огромные monorepo управляемыми: clone быстрый, а рабочее дерево остаётся маленьким.