Команди Git поділяються на два рівні:
- porcelain («порцеляна») - команди для людей:
commit,switch,merge,log. Їхній вивід і поведінка можуть змінюватися між версіями; - plumbing («сантехніка») - низькорівневі команди, з яких побудовано porcelain: читання й запис об'єктів, оновлення ref-ів. Їхній вивід стабільний - на них розраховані скрипти.
Коміт вручну - те, що робить git commit під капотом:
# 1. записати вміст файлу як blob
echo 'Hello' | git hash-object -w --stdin
# e965047ad7c57865823c7d992b1d046ea66edf78
# 2. додати blob в індекс під ім'ям
git update-index --add --cacheinfo 100644,e965047ad7c57865823c7d992b1d046ea66edf78,hello.txt
# 3. записати індекс як tree
git write-tree
# 7b3ce6f...
# 4. створити коміт з цим деревом і батьком
echo 'Add hello' | git commit-tree 7b3ce6f -p HEAD
# 4a1f2c9...
# 5. пересунути гілку на новий коміт
git update-ref refs/heads/main 4a1f2c9
Робочий каталог при цьому взагалі не використано: файл hello.txt на диску не з'являвся.
Основні plumbing-команди:
| Команда | Що робить |
|---|---|
hash-object |
обчислити хеш, з -w - записати blob |
cat-file |
прочитати об'єкт |
ls-tree, ls-files |
вміст дерева й індексу |
write-tree, commit-tree |
створити tree й коміт |
update-ref, symbolic-ref |
змінити ref безпечно, з записом у reflog |
rev-parse |
перетворити ім'я (гілка, HEAD~2) на хеш |
for-each-ref |
перелік ref-ів у заданому форматі |
merge-tree |
злиття без робочого каталогу |
Де це корисно на практиці:
- скрипти й CI:
git rev-parse --abbrev-ref HEAD,git for-each-ref --format='%(refname:short)' refs/heads/замість розбору виводуgit branch, який може змінитися; - операції без робочого каталогу: сервери Git (GitHub, GitLab) роблять злиття й коміти через
merge-treeіcommit-tree, не створюючи файлів на диску; - розуміння: знаючи plumbing, легко пояснити, що роблять
rebase,stash,cherry-pick, - вони лише комбінують ці кроки.
Порада для скриптів: використовуйте porcelain-команди з --porcelain-виводом (git status --porcelain=v2) або plumbing - і ніколи не розбирайте вивід, призначений для людей.