Глава 23 · Часть I · Git и GitHub с нуля

Ветка, HEAD и origin/main: как Git понимает, где мы находимся

Сначала отделим текущую локальную ветку от локального знания о GitHub. Тогда switch, fetch, pull и push перестанут быть набором магических команд.

SafeSort · Часть 1 из 6Git и GitHub

Перед первой рабочей веткой соберём одну цельную модель: где лежит изменение, на какой коммит указывает текущая ветка и что именно Git обновляет при fetch, pull и push.

Working treeфайлы на диске — то,что видит текстовыйредакторgit addкопирует текущеесодержимое в stagingarea / индексgit commitсоздаёт новый коммитв локальном графеgit pushпредлагает GitHubобновить удалённуюветку
Файл остаётся в working tree: git add не перемещает его, а фиксирует выбранное содержимое в индексе

git add не переносит файл в другое место. Рабочий файл остаётся на диске и может снова измениться. Команда помещает в индекс снимок его текущего содержимого, который станет частью следующего коммита.

Коммиты образуют граф

Каждый коммит знает родительский коммит. Поэтому история похожа не на папку с версиями, а на граф. Веткой называют подвижное имя, указывающее на один коммит. HEAD обычно указывает на выбранную ветку. Новый коммит получает текущий коммит родителем и передвигает эту ветку вперёд.

~/safesort $ git log --oneline --graph --decorate --all
* c31a4d2 (HEAD -> feature/scanner) Add directory scanner
* 82b19aa Add scanner test
* 4f10c77 (main, origin/main) Initial project structure
HEAD указывает на выбранную feature/scanner; main и origin/main пока остались на предыдущем коммите
ИмяГде живётЧто означает
mainлокальный репозиторийваша локальная ветка
origin/mainлокальный репозиторийпоследнее известное Git состояние удалённой main
main на GitHubудалённый репозиторийреальная ветка на сервере GitHub

origin/main не показывает состояние GitHub в реальном времени. Это локальная remote-tracking ссылка, которая меняется, когда Git получает сведения с сервера, например после git fetch.

git fetchскачивает новыекоммиты и обновляетorigin/main; рабочие…git pullсначала fetch, затеминтеграция полученнойветки в текущуюgit pushотправляет локальныекоммиты и проситобновить ветку на…
fetch обновляет знание о remote; pull добавляет интеграцию; push движется в обратную сторону
~/safesort $ git status
On branch main
Your branch is up to date with 'origin/main'.
~/safesort $ git branch -vv
* main 4f10c77 [origin/main] Initial project structure
~/safesort $ git fetch origin
~/safesort $ git log --oneline --graph --decorate --all
КомандаЧто показывает
git statusкакие файлы изменены, какие уже в staging, какие Git вообще не отслеживает
git diffпострочные изменения в рабочем дереве, ещё не добавленные в staging
git diff --stagedпострочные изменения, уже добавленные в staging — то, что попадёт в коммит
git branch -vvлокальные ветки, текущую ветку и их upstream-связи
git log --oneline --graph --decorate --allграф коммитов и положения ссылок

Коротко

  • Веткой называют подвижную ссылку на коммит; HEAD обычно указывает на текущую выбранную ветку.
  • main, origin/main и main на GitHub обозначают три различимых состояния, а не три написания одного объекта.
  • fetch обновляет remote-tracking ссылки; pull добавляет интеграцию; push обновляет удалённую ветку.
Официальная документация
Git Branching — Branches in a Nutshell
git-fetch
git-pull
git-push