15%

Сэкономьте 15% на всех хостинговых услугах

Проверьте свои навыки и получите скидку на любой тарифный план

Используйте код:

Skills
Начать
14.10.2024

Git Контроль Версий: Полный Технический Справочник для Разработчиков

Git — это распределённая система контроля версий (DVCS), которая записывает снимки файлового дерева проекта с течением времени, позволяя любому количеству участников работать параллельно, не перезаписывая изменения друг друга. Каждый разработчик хранит полную копию репозитория — включая всю историю коммитов — на своём локальном компьютере, что исключает единую точку отказа и обеспечивает полноценную работу в офлайн-режиме.

Созданный Линусом Торвальдсом в апреле 2005 года для замены BitKeeper в разработке ядра Linux, Git был спроектирован с нуля на основе трёх обязательных требований: скорость, целостность данных и поддержка нелинейных распределённых рабочих процессов. Эти принципы по-прежнему определяют то, что принципиально отличает Git от предшественников, и объясняют, почему он остаётся доминирующей VCS уже более двух десятилетий.

Чем Git отличается от централизованных систем контроля версий

Понимание архитектуры Git требует прямого сравнения с централизованными системами, такими как Subversion (SVN) или CVS, где единственный авторитетный сервер хранит канонический репозиторий, а разработчики получают поверхностные рабочие копии.

ПараметрGit (распределённый)SVN (централизованный)
Модель репозиторияПолный клон на каждом узлеТонкая рабочая копия, история хранится на сервере
Работа офлайнПолный commit, branch, diff, logТолько чтение; коммиты требуют сервера
Стоимость ветвленияПочти нулевая (манипуляция указателями)Дорогостоящее копирование директорий
Единая точка отказаОтсутствует — любой клон может восстановитьСбой сервера останавливает все коммиты
Стратегия слиянияТрёхстороннее слияние + rebaseТолько трёхстороннее слияние
Целостность историиХеширование содержимого SHA-1/SHA-256Последовательные номера ревизий
Зависимость от сетиТолько для push/pull/fetchПочти для каждой операции
Частичное извлечениеНе поддерживается нативноПоддерживается (sparse checkout)
Порог вхожденияБолее крутая начальная криваяМягче для ветеранов SVN
Распространённость (2024)~95% профессиональных командУстаревшие корпоративные среды

Распределённая модель означает, что даже если хостинговая платформа, такая как GitHub, испытывает сбой, локальный клон каждого разработчика является полной авторитетной резервной копией всей истории проекта.

Основная архитектура: что на самом деле хранит Git

Git не хранит диффы. Он хранит снимки. Каждый коммит указывает на объект дерева, представляющий полное состояние каждого отслеживаемого файла в данный момент. Если файл не изменился между двумя коммитами, Git хранит указатель на предыдущий blob, а не дублирует его — именно так Git достигает одновременно полноты и эффективности хранения.

Четыре фундаментальных типа объектов в хранилище объектов Git (.git/objects/):

  • Blob — необработанное содержимое файла, адресуемое по SHA-хешу
  • Tree — список директории, сопоставляющий имена файлов с хешами blob или поддеревьев
  • Commit — указатель на дерево, ноль или более родительских коммитов, метаданные автора и сообщение
  • Tag — аннотированный указатель на конкретный коммит, используемый для маркеров релизов

Каждый объект неизменяем и адресуется по содержимому. Изменение одного байта в любом файле порождает совершенно другой SHA-хеш, который каскадно распространяется вверх по объектам дерева и коммитов. Именно поэтому история Git криптографически защищена от подделки — невозможно незаметно изменить прошлый коммит, не изменив хеши всех последующих коммитов.

Область подготовки (также называемая индексом, хранится в .git/index) — это бинарный файл, содержащий предлагаемый следующий коммит. Эта трёхзонная модель — рабочая директория, индекс, репозиторий — является наиболее непонятой архитектурной особенностью Git и источником большинства затруднений у новичков.

Установка и настройка Git

Перед выполнением каких-либо команд проверьте установку и настройте свою идентификацию. Git встраивает информацию об авторе в каждый объект коммита, а неправильно настроенная идентификация — одна из наиболее распространённых причин запутанной истории коммитов в общих репозиториях.

# Verify installation
git --version

# Set global identity (stored in ~/.gitconfig)
git config --global user.name "Your Name"
git config --global user.email "you@example.com"

# Set default branch name to 'main' (modern convention)
git config --global init.defaultBranch main

# Set preferred editor for commit messages
git config --global core.editor "vim"

# Enable colored output
git config --global color.ui auto

# Verify configuration
git config --list

Конфигурация имеет уровни: --system (все пользователи, /etc/gitconfig), --global (текущий пользователь, ~/.gitconfig) и --local (репозиторий, .git/config). Более конкретные области переопределяют более широкие.

Основные команды Git: полный справочник

Инициализация и клонирование

git init создаёт новый репозиторий, записывая директорию .git/ в текущую папку. Коммиты при этом не создаются — репозиторий начинается пустым.

git init
git init my-project        # Initialize into a new subdirectory
git init --bare repo.git   # Bare repository (no working tree, used for servers)

Голый репозиторий содержит только хранилище объектов и refs — без рабочей директории. Это правильный формат для удалённого репозитория, в который выполняют push несколько разработчиков. Если вы самостоятельно размещаете Git на сервере VPS Hosting, всегда инициализируйте общие репозитории как голые.

git clone создаёт полную локальную копию удалённого репозитория, включая все ветки, теги и историю.

git clone https://github.com/user/repo.git
git clone git@github.com:user/repo.git          # SSH transport (preferred for auth)
git clone --depth 1 https://github.com/user/repo.git  # Shallow clone (latest commit only)
git clone --branch develop https://github.com/user/repo.git  # Clone specific branch

Поверхностные клоны (--depth) полезны для CI/CD-конвейеров, где нужно только последнее состояние, а не полная история. Они значительно сокращают время клонирования больших репозиториев, но препятствуют некоторым операциям, зависящим от истории, например git bisect.

Проверка состояния

git status — наиболее часто выполняемая команда в любом рабочем процессе. Она показывает трёхзонное состояние вашего репозитория.

git status
git status -s    # Short format: two-column status codes
git status -sb   # Short format with branch info

git diff сравнивает содержимое между зонами или коммитами.

git diff                    # Working directory vs. index (unstaged changes)
git diff --staged           # Index vs. last commit (what will be committed)
git diff HEAD               # Working directory vs. last commit (all changes)
git diff main..feature      # Compare tips of two branches
git diff abc123..def456     # Compare two specific commits
git diff --stat             # Show changed files and line counts only

git log обходит граф коммитов. Его параметры фильтрации — одни из наиболее мощных и недооценённых возможностей Git.

git log
git log --oneline --graph --decorate --all   # Visual branch graph
git log -p                                   # Show patch (diff) for each commit
git log --author="Jane"                      # Filter by author
git log --since="2 weeks ago"               # Filter by date
git log --grep="fix:"                        # Filter by commit message pattern
git log -- path/to/file                      # History of a specific file
git log --follow -- path/to/file             # Follow renames

Комбинация --graph --oneline --decorate --all настолько универсально полезна, что большинство инженеров создают для неё псевдоним:

git config --global alias.lg "log --oneline --graph --decorate --all"

Подготовка и коммит

git add filename.py          # Stage a specific file
git add src/                 # Stage an entire directory
git add .                    # Stage all changes in current directory
git add -p                   # Interactive patch staging (stage hunks, not whole files)
git add -u                   # Stage modifications and deletions, but not new files

Интерактивная подготовка (git add -p) — одна из наиболее мощных и недооценённых возможностей Git. Она позволяет просматривать и выборочно подготавливать отдельные фрагменты внутри файла, обеспечивая точные атомарные коммиты даже когда рабочая директория содержит несколько несвязанных изменений.

git commit -m "feat: add OAuth2 token refresh logic"
git commit --amend           # Modify the most recent commit (message or content)
git commit --amend --no-edit # Amend content without changing the message
git commit -v                # Open editor showing full diff of staged changes

Критическое правило: никогда не изменяйте коммиты, которые уже были отправлены в общий удалённый репозиторий. Изменение перезаписывает хеш коммита, вынуждая коллег выполнять rebase или сброс своих локальных веток.

Push и Pull

git push origin main
git push origin feature/auth     # Push a specific branch
git push -u origin feature/auth  # Push and set upstream tracking
git push --force-with-lease      # Safer force push (fails if remote has new commits)
git push origin --delete old-branch  # Delete a remote branch
git push --tags                  # Push all local tags

Предпочитайте --force-with-lease вместо --force, когда необходимо перезаписать удалённую историю. Это проверяет, что никто другой не выполнял push с момента вашего последнего fetch, предотвращая случайную потерю данных.

git pull origin main
git pull --rebase origin main    # Fetch and rebase instead of merge
git pull --ff-only               # Only fast-forward; abort if a merge commit would be created

git fetch загружает удалённые изменения, не затрагивая вашу рабочую директорию или текущую ветку. Это безопасный способ проверить изменения из upstream перед их интеграцией.

git fetch origin
git fetch --all          # Fetch from all remotes
git fetch --prune        # Remove remote-tracking branches that no longer exist upstream

Ветвление и слияние: основной рабочий процесс

Модель ветвления Git — её наиболее архитектурно значимая особенность. Ветка — это просто именованный указатель (файл размером 41 байт в .git/refs/heads/) на хеш коммита. Создание ветки происходит мгновенно независимо от размера репозитория.

Управление ветками

git branch                        # List local branches
git branch -a                     # List all branches (local and remote-tracking)
git branch -v                     # List branches with last commit info
git branch feature/user-auth      # Create a new branch
git branch -d feature/user-auth   # Delete merged branch
git branch -D feature/user-auth   # Force delete (even if unmerged)
git branch -m old-name new-name   # Rename a branch

Переключение веток

Современный Git (2.23+) разделяет функции git checkout на две специализированные команды:

git switch main                   # Switch to existing branch
git switch -c feature/payments    # Create and switch in one step
git restore filename.py           # Discard working directory changes to a file
git restore --staged filename.py  # Unstage a file (remove from index)

git checkout по-прежнему работает для всего этого, но git switch и git restore имеют более чёткую и однозначную семантику и должны предпочитаться в современных рабочих процессах.

Стратегии слияния

git merge feature/user-auth           # Standard merge (creates merge commit if needed)
git merge --no-ff feature/user-auth   # Always create merge commit (preserves branch topology)
git merge --squash feature/user-auth  # Squash all branch commits into one staged change
git merge --abort                     # Abort an in-progress conflicted merge

Слияние с перемоткой вперёд (fast-forward) происходит, когда целевая ветка не расходилась с исходной — Git просто перемещает указатель вперёд. Коммит слияния при этом не создаётся. --no-ff принудительно создаёт коммит слияния даже в этом случае, что сохраняет визуальную историю веток функций в git log --graph.

Слияние со сжатием (squash merge) объединяет все коммиты из ветки функции в одно подготовленное изменение, которое затем фиксируется вручную. Это создаёт чистую линейную историю в main, но отбрасывает детальную историю коммитов ветки функции.

Rebase

git rebase воспроизводит коммиты из одной ветки поверх другой, перезаписывая их хеши для создания линейной истории.

git rebase main                  # Rebase current branch onto main
git rebase -i HEAD~5             # Interactive rebase: edit last 5 commits
git rebase --onto main server client  # Transplant client branch onto main, excluding server
git rebase --abort               # Abort a rebase in progress
git rebase --continue            # Continue after resolving a conflict

Интерактивный rebase (-i) — профессиональный инструмент для поддержания чистоты коммитов. Он позволяет переупорядочивать, сжимать, редактировать, удалять или разделять коммиты перед их публикацией. Типичный сценарий использования: очистка запутанной ветки функции перед открытием pull request.

СтратегияИсторияСценарий использованияРиск
Merge (по умолчанию)Нелинейная, сохраняет веткиДолгоживущие ветки функцийЗашумлённый `git log`
Merge `–no-ff`Нелинейная, явные коммиты слиянияПринудительная топология ветокАналогично предыдущему
Merge `–squash`Линейная, один коммит на функциюЧистая основная веткаТеряется детальная история
RebaseЛинейная, без коммитов слиянияЛичные ветки, очистка перед PRПерезаписывает хеши; опасно на общих ветках
Cherry-pickВыборочная, линейнаяБэкпортирование исправленийДублирование коммитов между ветками

Золотое правило rebase: никогда не выполняйте rebase коммитов, существующих в публичной общей ветке. Rebase перезаписывает хеши коммитов. Если коллега основал свою работу на этих коммитах, его история разойдётся, и ему придётся болезненно согласовывать её вручную.

Разрешение конфликтов слияния

Конфликты возникают, когда две ветки изменяют одну и ту же область одного и того же файла. Git отмечает конфликт в файле стандартными маркерами конфликта:

<<<<<<< HEAD
const timeout = 30000;
=======
const timeout = 60000;
>>>>>>> feature/increase-timeout

Рабочий процесс разрешения:

# After a conflicted merge or rebase
git status                    # Identify conflicted files (marked as "both modified")
# Edit each conflicted file, remove markers, keep correct content
git add resolved-file.js      # Mark as resolved
git commit                    # Complete the merge (message is pre-populated)

Для сложных конфликтов инструмент трёхстороннего слияния обеспечивает более наглядное представление:

git mergetool                 # Launch configured merge tool (vimdiff, meld, etc.)
git config --global merge.tool vimdiff

Отмена изменений: матрица решений

Выбор неправильной команды отмены — один из наиболее распространённых способов потерять работу или повредить общую историю. Правильный выбор зависит от двух переменных: где находится изменение и было ли оно отправлено.

СценарийКомандаПерезаписывает историюБезопасно в общей ветке
Убрать файл из подготовки`git restore –staged file`НетДа
Отменить изменения в рабочей директории`git restore file`НетДа
Отменить последний коммит, сохранить изменения подготовленными`git reset –soft HEAD~1`ДаНет
Отменить последний коммит, сохранить изменения неподготовленными`git reset HEAD~1`ДаНет
Отменить последний коммит, удалить все изменения`git reset –hard HEAD~1`ДаНет
Безопасно отменить отправленный коммит`git revert <hash>`НетДа
Удалить файл из всей истории`git filter-repo`ДаНет
git reset --soft HEAD~1      # Undo commit, keep changes in index
git reset HEAD~1             # Undo commit, keep changes in working dir
git reset --hard HEAD~1      # Undo commit, discard all changes permanently

git revert abc1234           # Create new commit that inverts abc1234
git revert HEAD~3..HEAD      # Revert last 3 commits (creates 3 revert commits)
git revert -n HEAD~3..HEAD   # Stage the reversals without committing (batch revert)

git reset --hard необратим с помощью обычных команд Git. Если вы случайно выполнили его, единственный путь к восстановлению — git reflog, который записывает каждую позицию, на которую указывал HEAD, приблизительно в течение 90 дней.

git reflog                   # Show HEAD movement history with hashes
git checkout -b recovery abc1234  # Recover by creating a branch at the lost commit

Продвинутые команды для производственных рабочих процессов

git stash

git stash сохраняет текущее состояние рабочей директории и индекса в стек, предоставляя чистое рабочее дерево для переключения контекста.

git stash                        # Stash tracked changes
git stash -u                     # Include untracked files
git stash push -m "WIP: auth refactor"  # Stash with a descriptive name
git stash list                   # List all stash entries
git stash pop                    # Apply most recent stash and remove it from stack
git stash apply stash@{2}        # Apply specific stash without removing it
git stash drop stash@{2}         # Delete a specific stash entry
git stash branch feature/wip     # Create a new branch from a stash

git cherry-pick

git cherry-pick abc1234                    # Apply a single commit to current branch
git cherry-pick abc1234 def5678            # Apply multiple commits
git cherry-pick abc1234 --no-commit        # Apply changes without committing
git cherry-pick main~3..main              # Apply a range of commits

Cherry-pick — стандартный механизм для бэкпортирования исправлений ошибок в ветки обслуживания. Если вы исправляете критическую уязвимость безопасности в main, вы выполняете cherry-pick этого коммита в v2.1-stable и v2.0-stable без слияния несвязанных функций.

git bisect

git bisect выполняет бинарный поиск по истории коммитов для нахождения точного коммита, в котором была введена ошибка. Это один из наиболее мощных и малоизвестных инструментов отладки Git.

git bisect start
git bisect bad                   # Mark current commit as broken
git bisect good v2.3.0           # Mark a known-good commit or tag
# Git checks out the midpoint commit automatically
# Test your code, then:
git bisect good                  # If this commit is fine
git bisect bad                   # If this commit is broken
# Repeat until Git identifies the first bad commit
git bisect reset                 # Return to original HEAD when done

В репозитории с 1 000 коммитами между хорошей и плохой точками git bisect находит виновника не более чем за 10 шагов.

git tag

Теги отмечают конкретные коммиты как значимые — как правило, версии релизов.

git tag v1.4.2                          # Lightweight tag (just a pointer)
git tag -a v1.4.2 -m "Release 1.4.2"   # Annotated tag (recommended; stores metadata)
git tag -a v1.4.2 abc1234              # Tag a specific past commit
git push origin v1.4.2                 # Push a specific tag
git push origin --tags                 # Push all tags
git tag -d v1.4.2                      # Delete local tag
git push origin --delete v1.4.2        # Delete remote tag

Всегда используйте аннотированные теги для релизов. Они хранят имя, email, дату и сообщение создателя тега, а также могут быть подписаны с помощью GPG. Лёгкие теги подходят только для временных локальных закладок.

git worktree

git worktree позволяет одновременно извлекать несколько рабочих директорий из одного репозитория — каждую на отдельной ветке. Это устраняет необходимость в stash или коммите незавершённой работы при переключении на hotfix.

git worktree add ../hotfix-branch hotfix/critical-auth-bug
git worktree list
git worktree remove ../hotfix-branch

Это особенно ценно на Dedicated Server, работающем с CI/CD-конвейером, где нескольким задачам сборки требуется одновременный доступ к разным веткам одного репозитория без взаимных помех.

Рабочие процессы Git для команд

Правильная стратегия ветвления зависит от частоты выпусков и размера команды. Существуют три доминирующие модели:

Рабочий процесс с ветками функций

Каждая функция или исправление живёт в собственной ветке. Разработчики открывают pull request для слияния в main. Простой и эффективный подход для большинства команд.

Gitflow

Определяет долгоживущие ветки main и develop, а также краткосрочные ветки feature/, release/ и hotfix/ со строгими правилами слияния. Подходит для программного обеспечения с явными версионированными релизами (библиотеки, упакованные приложения).

Разработка на основе trunk

Разработчики коммитят напрямую в main (или используют очень краткосрочные ветки, сливаемые в течение дня). В значительной мере опирается на флаги функций для скрытия незавершённой работы. Предпочтительна для высокоскоростных команд, практикующих непрерывное развёртывание.

Рабочий процессЧастота выпусковРазмер командыСложность CI/CD
Feature BranchГибкаяЛюбойНизкая
GitflowПлановые релизыСредний–КрупныйСредняя
Trunk-BasedНепрерывное развёртываниеЛюбойВысокая

Хостинг репозиториев Git: самостоятельный хостинг vs. управляемые платформы

Для команд, которым требуется суверенитет данных, соответствие нормативным требованиям или частная инфраструктура, самостоятельный хостинг Git-сервера является жизнеспособным и зачастую необходимым выбором. Варианты включают Gitea (лёгкий, на основе Go), GitLab CE (полная DevOps-платформа) и Forgejo (форк Gitea с управлением сообщества).

Минимальный самостоятельно размещённый экземпляр Gitea комфортно работает на плане VPS Hosting с 2 vCPU и 2 GB RAM. Для более крупных команд или GitLab CE с CI-раннерами практический минимум составляет 4–8 GB RAM.

При самостоятельном хостинге защитите свой Git-сервер с помощью:

  • Аутентификации по SSH-ключу (полностью отключите аутентификацию по паролю)
  • HTTPS с действительным сертификатом — SSL Certificates необходимы для защиты учётных данных при передаче
  • Правил брандмауэра, ограничивающих доступ к Git-порту (22 или пользовательский SSH-порт, 443 для HTTPS)
  • Регулярных автоматических резервных копий директорий голого репозитория .git
  • Секретов webhook для интеграций CI/CD

Для команд, использующих конвейеры развёртывания на основе Git и управляющих веб-инфраструктурой, сочетание самостоятельно размещённого Git-сервера с VPS with cPanel даёт интегрированные хуки развёртывания наряду с привычными инструментами управления хостингом.

Git-хуки: автоматизация контроля качества

Git-хуки — это скрипты, которые автоматически выполняются в определённых точках жизненного цикла Git. Они находятся в .git/hooks/ и по умолчанию не фиксируются в репозитории (используйте такой инструмент, как pre-commit или husky, для их совместного использования).

Ключевые хуки для производственных рабочих процессов:

ХукТриггерТипичное использование
`pre-commit`Перед созданием коммитаЗапуск линтеров, форматтеров, тестов
`commit-msg`После написания сообщения коммитаСоблюдение формата conventional commit
`pre-push`Перед push на удалённый серверЗапуск полного набора тестов
`post-receive`После получения push удалённым серверомЗапуск развёртывания, отправка уведомлений
`pre-rebase`Перед началом rebaseПредотвращение rebase общих веток
# Example pre-commit hook: reject commits with debug print statements
#!/bin/bash
if git diff --cached | grep -E '^+.*(console.log|debugger|print("DEBUG)'; then
  echo "ERROR: Debug statement detected. Remove before committing."
  exit 1
fi

Хук post-receive на голом серверном репозитории — основа простого развёртывания на основе Git: push на сервер, хук извлекает новый HEAD в корень веб-сервера, выполняет шаги сборки и перезапускает сервисы — без необходимости во внешней CI-платформе.

.gitignore: поддержание чистоты репозиториев

Файл .gitignore указывает Git, какие файлы и шаблоны оставлять неотслеживаемыми. Он должен быть зафиксирован в репозитории и тщательно поддерживаться.

# Dependencies
node_modules/
vendor/

# Build artifacts
dist/
build/
*.o
*.pyc
__pycache__/

# Environment and secrets — NEVER commit these
.env
.env.local
*.pem
*.key
config/secrets.yml

# IDE files
.idea/
.vscode/
*.swp

# OS files
.DS_Store
Thumbs.db

Критическая ловушка: если файл уже отслеживался до добавления в .gitignore, Git продолжит его отслеживать. Необходимо явно прекратить его отслеживание:

git rm --cached path/to/sensitive-file
git commit -m "chore: stop tracking secrets file"

Никогда не фиксируйте учётные данные, API-ключи или приватные ключи в репозитории — даже в приватном. Используйте переменные окружения, менеджеры секретов (HashiCorp Vault, AWS Secrets Manager) или файлы .env, добавленные в .gitignore.

Настройка производительности для больших репозиториев

Стандартный Git деградирует на репозиториях с миллионами файлов или гигабайтами бинарных ресурсов. Стратегии смягчения:

  • Git LFS (Large File Storage): заменяет большие бинарные файлы файлами-указателями в репозитории и хранит фактическое содержимое на отдельном LFS-сервере. Необходим для репозиториев, содержащих медиафайлы, веса ML-моделей или скомпилированные бинарные файлы.
  • Частичное клонирование: git clone --filter=blob:none загружает коммиты и деревья, но получает blob-объекты по требованию. Значительно уменьшает начальный размер клона для больших монорепозиториев.
  • Sparse checkout: git sparse-checkout set path/to/subdir извлекает только подмножество рабочего дерева. Полезно в монорепозиториях, где разработчик работает только в одной директории сервиса.
  • Файл commit-graph: git commit-graph write --reachable предварительно вычисляет граф коммитов, ускоряя такие операции, как git log --graph и запросы достижимости в больших историях.
  • git maintenance start: планирует фоновые задачи обслуживания (упаковка свободных объектов, обновление commit-graph, предварительная загрузка fetch) для поддержания быстрой работы репозитория со временем.

Технический контрольный список ключевых выводов

Прежде чем считать настройку Git готовой к производству, проверьте каждый из следующих пунктов:

  • Идентификация настроена: user.name и user.email правильно установлены на соответствующем уровне конфигурации
  • Используются SSH-ключи: аутентификация по паролю к удалённым серверам заменена парами SSH-ключей или HTTPS на основе токенов
  • .gitignore зафиксирован: секреты, артефакты сборки и файлы ОС исключены до первого коммита
  • Ветка по умолчанию называется main: init.defaultBranch установлен глобально во избежание устаревшего именования master
  • Сообщения коммитов следуют соглашению: Conventional Commits (feat:, fix:, chore:) или согласованный командой формат, соблюдаемый через хук commit-msg
  • git revert для публичной истории: git reset --hard используется только для локальных, неотправленных коммитов
  • --force-with-lease вместо --force: предотвращает случайную перезапись push коллег
  • Аннотированные теги для релизов: git tag -a с сообщением, а не лёгкие теги
  • Хуки распространяются через pre-commit или husky: контроль качества соблюдается единообразно во всей команде
  • Git LFS настроен, если репозиторий содержит бинарные ресурсы размером более 1 MB
  • Голый репозиторий на сервере: самостоятельно размещённые удалённые серверы инициализированы с помощью git init --bare
  • Регулярный git fetch --prune: ветки удалённого отслеживания синхронизированы с фактическим состоянием удалённого сервера

Часто задаваемые вопросы

В чём разница между git fetch и git pull?

git fetch загружает коммиты, ветки и теги с удалённого сервера в локальные refs удалённого отслеживания (например, origin/main), не затрагивая рабочую директорию или текущую ветку. git pull — это git fetch, за которым немедленно следует git merge (или git rebase, если настроено). Используйте git fetch, когда хотите проверить изменения из upstream перед их интеграцией.

Когда следует использовать git rebase вместо git merge?

Используйте rebase для линеаризации локальной ветки функции перед открытием pull request, сохраняя читаемость истории проекта. Никогда не выполняйте rebase ветки, которую другие разработчики уже клонировали или на которой основали свою работу — перезапись опубликованных хешей коммитов вынуждает всех остальных вручную согласовывать расходящиеся истории.

Как навсегда удалить конфиденциальный файл, случайно зафиксированный в коммите?

Используйте git filter-repo (современная замена git filter-branch): git filter-repo --path secrets.env --invert-paths. Это перезаписывает всю историю репозитория, удаляя файл из каждого коммита. После перезаписи выполните принудительный push всех веток и тегов, затем немедленно смените скомпрометированные учётные данные — считайте их раскрытыми независимо от того, насколько быстро вы действуете.

Что такое состояние detached HEAD и как из него выйти?

Detached HEAD означает, что указатель HEAD ссылается непосредственно на конкретный хеш коммита, а не на имя ветки. Любые коммиты, которые вы делаете, не будут принадлежать ни одной ветке и станут недостижимыми после переключения. Для восстановления: git switch -c new-branch-name для присоединения коммитов к новой ветке или git switch main для их отмены.

Как Git обрабатывает бинарные файлы иначе, чем текстовые?

Git хранит бинарные файлы как непрозрачные blob-объекты — он не может вычислять значимые построчные диффы или выполнять автоматические слияния для них. Конфликты в бинарных файлах должны разрешаться путём выбора одной из версий целиком. Для репозиториев со значительными бинарными ресурсами настройте Git LFS для хранения бинарных файлов во внешнем хранилище, сохраняя сам репозиторий лёгким и быстрым.

15%

Сэкономьте 15% на всех хостинговых услугах

Проверьте свои навыки и получите скидку на любой тарифный план

Используйте код:

Skills
Начать