-
1. Вступ
- 1.1 Про систему контролю версій
- 1.2 Коротка історія Git
- 1.3 Основи Git
- 1.4 Git, зазвичай, тільки додає дані
- 1.5 Три стани
- 1.6 Командний рядок
- 1.7 Інсталяція Git
- 1.8 Початкове налаштування Git
- 1.9 Отримання допомоги
- 1.10 Підсумок
-
2. Основи Git
- 2.1 Створення Git-репозиторія
- 2.2 Запис змін до репозиторія
- 2.3 Перегляд історії комітів
- 2.4 Скасування речей
- 2.5 Взаємодія з віддаленими сховищами
- 2.6 Теґування
- 2.7 Псевдоніми Git
- 2.8 Підсумок
-
3. Галуження в git
- 3.1 Гілки у кількох словах
- 3.2 Основи галуження та зливання
- 3.3 Управління гілками
- 3.4 Процеси роботи з гілками
- 3.5 Віддалені гілки
- 3.6 Перебазовування
- 3.7 Підсумок
-
4. Git на сервері
- 4.1 Протоколи
- 4.2 Отримання Git на сервері
- 4.3 Генерація вашого публічного ключа SSH
- 4.4 Налаштування Серверу
- 4.5 Демон Git
- 4.6 Розумний HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Варіанти стороннього хостингу
- 4.10 Підсумок
-
5. Розподілений Git
-
6. GitHub
-
7. Інструменти Git
- 7.1 Вибір ревізій
- 7.2 Інтерактивне індексування
- 7.3 Ховання та чищення
- 7.4 Підписання праці
- 7.5 Пошук
- 7.6 Переписування історії
- 7.7 Усвідомлення скидання (reset)
- 7.8 Складне злиття
- 7.9 Rerere
- 7.10 Зневадження з Git
- 7.11 Підмодулі
- 7.12 Пакування
- 7.13 Заміна
- 7.14 Збереження посвідчення (credential)
- 7.15 Підсумок
-
8. Налаштування Git
-
9. Git and Other Systems
- 9.1 Git як клієнт
- 9.2 Міграція на Git
- 9.3 Підсумок
-
10. Git зсередини
- 10.1 Кухонні та парадні команди
- 10.2 Об’єкти Git
- 10.3 Посилання Git
- 10.4 Файли пакунки
- 10.5 Специфікація посилань (refspec)
- 10.6 Протоколи передачі
- 10.7 Супроводження та відновлення даних
- 10.8 Змінні середовища
- 10.9 Підсумок
-
A1. Додаток A: Git в інших середовищах
- A1.1 Графічні інтерфейси
- A1.2 Git у Visual Studio
- A1.3 Git в Eclipse
- A1.4 Git у Bash
- A1.5 Git у Zsh
- A1.6 Git у Powershell
- A1.7 Підсумок
-
A2. Додаток B: Вбудовування Git у ваші застосунки
- A2.1 Git з командного рядка
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
-
A3. Додаток C: Команди Git
- A3.1 Налаштування та конфігурація
- A3.2 Отримання та створення проектів
- A3.3 Базове збереження відбитків
- A3.4 Галуження та зливання
- A3.5 Поширення й оновлення проектів
- A3.6 Огляд та порівняння
- A3.7 Зневаджування
- A3.8 Латання (patching)
- A3.9 Електронна пошта
- A3.10 Зовнішні системи
- A3.11 Адміністрування
- A3.12 Кухонні команди
10.3 Git зсередини - Посилання Git
Посилання Git
Якщо вам цікаво подивитися на історію сховища, що досяжна з певного коміту, скажімо, 1a410e
, ви можете виконати щось на кшталт git log 1a410e
, щоб переглянути цю історію, проте вам усе одно доведеться памʼятати, що 1a410e
— це коміт, що є початковою точкою для цієї історії.
Натомість легше було б, якби у вас був файл, що зберігає це значення SHA-1 під простою назвою, щоб ви могли використовувати просту назву замість значення SHA-1.
У Git ці прості назви відомі як “посилання” (reference або ref). Ви можете знайти файли, які містять ці значення SHA-1 у директорії .git/refs
.
У поточному проекті, ця директорія не містить файлів, проте вона містить просту структуру:
$ find .git/refs
.git/refs
.git/refs/heads
.git/refs/tags
$ find .git/refs -type f
Щоб створити нове посилання, яке допоможе вам пам’ятати, де знаходиться ваш останній коміт, ви технічно можете зробити щось настільки просте:
$ echo 1a410efbd13591db07496601ebc7a059dd55cfe9 > .git/refs/heads/master
Тепер, ви можете використати щойно створене посилання замість значення SHA-1 у командах Git:
$ git log --pretty=oneline master
1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
cac0cab538b970a37ea1e769cbbde608743bc96d second commit
fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
Ми не заохочуємо вас редагувати файли посилань напряму.
Натомість, Git надає для цього безпечнішу команду git update-ref
, якщо ви бажаєте оновити посилання:
$ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9
В основі, це і є гілкою в Git: простий вказівник чи посилання на верхівку лінії роботи. Щоб створити гілку з другого коміту, ви можете зробити наступне:
$ git update-ref refs/heads/test cac0ca
Ваша гілка буде містити лише роботу з цього коміту й попередню:
$ git log --pretty=oneline test
cac0cab538b970a37ea1e769cbbde608743bc96d second commit
fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
Тепер, ваша база даних Git концептуально виглядає так:
![Об’єкти директорії Git](png/data-model-4.png)
Коли ви виконуєте такі команди як git branch <назва гілки>
, Git по суті виконує команду update-ref
, щоб додати SHA-1 останнього коміту поточної гілки до якого забажаєте нового посилання.
HEAD
Тепер питання в тому, як Git дізнається SHA-1 останнього коміту, коли ви виконуєте git branch <назва гілки>
?
Відповідь у файлі HEAD.
Файл HEAD — це символічне посилання на поточну гілку. Під символічним посиланням, ми маємо на увазі, що, на відміну від звичайного посилання, воно зазвичай не містить значення SHA-1, а натомість вказівник на інше посилання. Якщо ви подивитесь на цей файл, то зазвичай побачите щось таке:
$ cat .git/HEAD
ref: refs/heads/master
Якщо виконати git checkout test
, Git оновлює цей файл наступним чином:
$ cat .git/HEAD
ref: refs/heads/test
Коли ви виконуєте git commit
, він створює об’єкт коміту, якому встановлює батьківській коміт у те значення SHA-1, на яке вказує посилання, на яке вказує HEAD.
Ви також можете вручну редагувати цей файл, проте знову таки, існує безпечніша команда: git symbolic-ref
.
Ви можете зчитати значення HEAD за допомогою цієї команди:
$ git symbolic-ref HEAD
refs/heads/master
Ви також можете встановити значення HEAD за допомогою тієї ж команди:
$ git symbolic-ref HEAD refs/heads/test
$ cat .git/HEAD
ref: refs/heads/test
Ви не можете встановлювати символічні посилання поза стилем refs:
$ git symbolic-ref HEAD test
fatal: Refusing to point HEAD outside of refs/
Теґи
Ми щойно завершили обговорення трьох основних типів об’єктів Git (блоби, дерева та коміти), проте існує четвертий. Об’єкт теґ дуже схожий на об’єкт коміт — він містить автора теґу, дату, повідомлення та вказівник. Головна різниця в тому, що об’єкт теґ вказує на коміт, а не на дерево. Це схоже на посилання гілки, проте воно ніколи не переміщується — завжди вказує на один коміт, проте надає йому зрозуміліше ім’я.
Як вже обговорено в Основи Git, існують два головних типи теґів: анотовані та легкі. Ви можете створити легкий теґ, якщо виконаєте щось таке:
$ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d
Це і є легкий теґ — посилання, яке ніколи не змінюється.
Анотований тег, втім, складніший.
Якщо ви створите анотований теґ, Git створить об’єкт теґ, а потім запише посилання, яке вказує на нього, а не на сам коміт.
Ви можете побачити це, якщо створите анотований теґ (за допомогою опції -a
):
$ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 -m 'test tag'
Ось значення SHA-1 створеного об’єкта:
$ cat .git/refs/tags/v1.1
9585191f37f7b0fb9444f35a9bf50de191beadc2
Тепер, виконайте git cat-file -p
для цього значення SHA-1:
$ git cat-file -p 9585191f37f7b0fb9444f35a9bf50de191beadc2
object 1a410efbd13591db07496601ebc7a059dd55cfe9
type commit
tag v1.1
tagger Scott Chacon <schacon@gmail.com> Sat May 23 16:48:58 2009 -0700
test tag
Завважте, що елемент object вказує на значення SHA-1 коміту, який ви позначили теґом. Також зверніть увагу, що це не обов’язково має бути коміт; ви можете створити теґ для будь-якого об’єкта Git. Наприклад, у вихідному коді Git, супроводжувач додав свій публічний ключ GPG як блоб та створив для нього теґ. Ви можете відобразити публічний ключ, якщо виконаєте наступне після клонування Git репозиторія:
$ git cat-file blob junio-gpg-pub
Репозиторій ядра Linux також має об’єкт теґ, який вказує не на коміт — перший створений теґ вказує на початкове дерево імпорту вихідного коду.
Віддалені посилання
Третій тип посилань, які вам зустрінуться — це віддалені посилання.
Якщо ви додасте віддалене сховище та надішлете до нього зміни, Git збереже значення, яке ви востаннє надсилали, для кожної гілки в директорії refs/remotes
.
Наприклад, ви можете додати віддалене сховище під назвою origin
та надіслати до нього свій master
:
$ git remote add origin git@github.com:schacon/simplegit-progit.git
$ git push origin master
Counting objects: 11, done.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 716 bytes, done.
Total 7 (delta 2), reused 4 (delta 1)
To git@github.com:schacon/simplegit-progit.git
a11bef0..ca82a6d master -> master
Потім, ви можете бачити, якою була гілка master
віддаленого сховища origin
, коли ви востаннє взаємодіяли зі сервером, перевіривши файл refs/remotes/origin/master
:
$ cat .git/refs/remotes/origin/master
ca82a6dff817ec66f44342007202690a93763949
Віддалені посилання відрізняються від гілок (посилань refs/heads
) головним чином тим, що вважаються доступними лише для читання.
Ви можете переключитись на нього, проте Git не переключить туди HEAD, отже ви ніколи його не обновите за допомогою команди commit
.
Git вважає їх закладками на останній відомий стан того, де були ці гілки на цих серверах.