GIT: Головы и теги


Головы

В .git/refs/heads лежат файлы-”головы”; в обиходе их называют ”ветками“.

Имя файла — название ветки.

Содержимое файла — хэш коммита, на который указывает ветка; этот коммит называется ”верхушкой” ветки (tip of the branch).

Вот и всё (Если ограничиваться локальным репозиторием, без сервера).


Теги

В .git/refs/tags лежат файлы-”теги” (”метки”).

Имя файла — название тега. Содержимое файла — хэш помеченного (тегированного) коммита.

Например, принято помечать значимые состояния репозитория: “именно такой код был в репозитории, когда вышел релиз 2.0.0”.


.git/HEAD (или просто HEAD) — это файл, в котором указан “головной коммит” — то, какое состояние репозитория выбрано сейчас.

Там находится либо название ветки — тогда головной коммит является просто верхушкой ветки — либо хэш коммита — тогда говорят, что голова оторванная (“detached”).

HEAD не может указывать на тег, только на ветку или коммит. Почему? На следующем слайде.


Двигающие головной коммит операции

Как мы знаем, git commit не только создаёт новый коммит, но и делает его головным.

На самом деле, если HEAD указывает на ветку, сам HEAD не меняется, а меняется содержимое ветки.

То же справедливо про git reset, git cherry-pick, git rebase -i и прочие операции, меняющие головной коммит.

Если бы HEAD мог указывать на тег, то эти операции меняли бы содержимое тега, а хочется, чтобы оно было замороженным.


Адресация коммитов

Многие операции в git требуют как аргумент какой-то коммит. В таких случаях можно подавать следующие вещи:

  • Название ветки;
  • Название тега;
  • Хэш коммита;
  • Префикс хэша коммита, если по этому пре фиксу нет коллизий;
  • Всё перечисленное выше, к чему справа дописано крышек ^ — это состояние на коммитов ранее.

Команды для голов

  • git branch: манипулирует ветками: создаёт, удаляет, переименовывает, перечисляет ветки.
  • git tag: делает то же с тегами.
  • git checkout BRANCH: устанавливает ГОЛОВУ на BRANCH и обновляет файлы в index и в рабочем дереве.
  • git checkout COMMIT: отрывает ГОЛОВУ, помещает её на COMMIT и обновляет файлы в index и в рабочем дереве.
  • git reset --soft COMMIT: переписывает ГОЛОВУ на COMMIT. Это всё равно что записать КОММИТ в .git/refs/heads/текущая ветка.
  • git reset --mixed COMMIT: переписывает ГОЛОВУ на COMMIT, а также меняет index на содержимое COMMIT.
  • git reset --hard COMMIT: переписывает ГОЛОВУ на COMMIT, а также меняет index и рабочее дерево на содержимое COMMIT.