Файл: Система управления версиями git и российский сервис хранения исходного кода gitflic.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 06.12.2023

Просмотров: 215

Скачиваний: 7

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

49
$ git ls-files --stage
100644 09478d7f26086b969ea8edac54bc98d0c1c9e750 0 Dir1/File3.txt
100644 d4a854445e5dab327199bdeca32f16878c874e05 0 File1.txt
100644 36d9b23df2cdcd91759d69a291d04beddab2b091 0 File2.txt
Хеш-значения в индексе для файлов File1.txt, File3.txt изменились и теперь они не совпадают со значениями, хранящимися в последнем ком- мите. Git понимает, что файлы File2.txt, File3.txt подготовлены для добавле- ния в новый коммит.
Выполнение коммита:
/c/Learn_git
(Main_branch)
$ git commit -m 'Test commit 2'
[Main_branch d58ea97] Test commit 2 2 files changed, 2 insertions(+), 2 deletions(-)
В файле .git/HEAD хранится запись: ref: refs/heads/Main_branch
В файле refs/heads/Main_branch хранится запись: d58ea9721672b176fdeda4a6550030a43f982d61
Это имя объекта, соответствующего новому коммиту.
Содержание нового коммита:
/c/Learn_git
(Main_branch)
$ git cat-file -p d58ea9721672b176fdeda4a6550030a43f982d61 tree a7325622d8c15306bc4f2c3b8825d7ffeaec0d1c parent 00edc80c522d4b79c517c7f377e99a3249e7b24b author Git_Book 1658515697 +0300 committer Git_Book 1658515697 +0300
Test commit 2
В отличие от предыдущего (первого) коммита, добавлена строчка с признаком parent. В этой строке находится имя объекта, содержащего предыдущий коммит. Начиная со второго коммита в ветке, строчка parent будет присутствовать во всех коммитах, что даёт возможность переме- щаться от одного коммита к другому в обратном хронологическом порядке и, при необходимости, восстановить рабочую директорию для прошлого коммита.
Чтение содержимого объектов «дерево» текущего коммита.
/c/Learn_git
(Main_branch)
$ git cat-file -p a7325622d8c15306bc4f2c3b8825d7ffeaec0d1c
040000 tree 44fdafa264bef7c64378a1d070a034bf57d02979 Dir1 100644 blob d4a854445e5dab327199bdeca32f16878c874e05 File1.txt
100644 blob 36d9b23df2cdcd91759d69a291d04beddab2b091 File2.txt
/c/Learn_git
(Main_branch)
$ git cat-file -p 44fdafa264bef7c64378a1d070a034bf57d02979 100644 blob 09478d7f26086b969ea8edac54bc98d0c1c9e750 File3.txt
Графическое представление дерева рабочей директории для второго

50 коммита представлено на рисунке 2.4. Сравнив деревья рисунков 2.3 и 2.4, видим, что для файлов File1.txt, File3.txt созданы новые blob-объекты. Для
File2.txt используется blob-объект из прошлого коммита, что позволяет эко- номить место на диске.
Рисунок 2.4 – Дерево рабочей директории (второй коммит)
1   2   3   4   5   6   7   8   9   ...   12

2.11. Технология использования веток
Работа над проектом разработки программного продукта может стро- иться по-разному. Как бы работа не строилась, предполагаем, что для сохра- нения истории создания кода используется Git. Самый простой вариант по- строения репозитория – это репозиторий с одной веткой. Как говорилось ранее, ветка – это последовательность коммитов. Репозиторий, содержащий одну ветку, изображён на рисунке 2.5.

51
Рисунок 2.5 – Репозиторий с одной веткой
На рисунке показаны 5 коммитов главной ветки (ГВ) ГВ1, ГВ2, ГВ3,
ГВ4, ГВ5. Коммиты ссылаются друг на друга в обратном хронологическом порядке. В файле HEAD находится имя файла из директории .git/refs/head, в котором записано хеш-значение последнего в ветке объекта «коммит».
При таком построении репозитория, для управления состоянием рабо- чей директории, возможно выполнить следующие действия:
1. Переместить указатель HEAD на любой из коммитов. При таком перемещении Git автоматически восстановит в рабочей директории состоя- ние файлов, каким оно было на момент коммита, к которому переместился указатель HEAD. Указатель HEAD в любой момент можно вернуть к по- следнему коммиту, и Git восстановит соответствующее состояние рабочей директории.
2. Удалить часть коммитов, идущих подряд в обратном хронологи- ческом порядке. Git восстановит состояние рабочей директории, каким оно было до выполнения удалённых коммитов.
3. Посмотреть историю изменения файлов рабочей директории.
4. Сравнить версии файлов из различных коммитов.
Репозиторий с одной веткой возникает крайне редко в ситуации, когда проект выполняет один программист. Среди программистов существует не- гласное правило, согласно которому в главную ветку помещается только проверенный код, не содержащий грубых ошибок. Именно грубых, так как ни один программист не будет утверждать, что в его коде нет ни одной ошибки. Тестирование кода перед размещением в главной ветке происходит в боковых ветках. На рисунке 2.6 показан репозиторий с боковой веткой, когда HEAD указывает на боковую ветку. На рисунке 2.7 показан репозито- рий с боковой веткой, когда HEAD указывает на главную ветку.

52
Рисунок 2.6 – Репозиторий с двумя ветками
(HEAD указывает на боковую ветку)
Рисунок 2.7 – Репозиторий с двумя ветками
(HEAD указывает на главную ветку)
В репозитории может быть неограниченное количество веток, однако стараются сохранять такое количество веток, при котором не теряется обозримость репозитория. При построении репозитория по схеме с несколь- кими ветками, для управления состоянием рабочей директории возможно выполнять все действия, которые доступны для репозитория с одной веткой, и в дополнение ряд других действий:
1. Переключение с одной ветки на другую. При этом Git обеспечивает состояние рабочей директории, соответствующее последнему коммиту ветки.
2. Сохранение состояния рабочей директории из одной ветки в ком- мите для другой ветки. Необходимость такого сохранения возникает, когда работа над кодом в боковой ветке завершена, и необходимо перенести ре-


53 зультат в главную ветку. При этом боковая ветка сохраняется, и в дальней- шем возможно продолжить вносить изменения в код этой ветки.
3. Слияние последних коммитов двух веток. Выполняется, когда окончательный результат складывается из двух коммитов. В этом случае продолжить работу с боковой веткой нельзя.
4. Удаление ветки. Когда задача решена или стало понятно, что был выбран ошибочный путь решения задачи, боковая ветка удаляется без вреда для остальных веток проекта.
Проект, над которым работают несколько программистов, обяза- тельно содержит боковые ветки (их минимальное количество равно количе- ству программистов).
Таким образом, технология использования веток включает следую- щие действия:
1. Создание ветки.
2. Удаление ветки.
3. Переключение между ветками.
4. Слияние веток.
В следующих разделах будет подробно рассмотрено каждое из этих действий.
2.12. Создание ветки
Для создания ветки используется команда git branch.
Формат команды git branch:
git branch <ключ> <имя ветки>
Одно из возможных значений ключа: -m. При использовании команды git branch с ключом -m произойдёт переименование текущей ветки.
Команду git branch можно использовать без ключа, в этом случае бу- дет выполнено создание новой ветки.
При выполнении команды git branch без ключа происходят следую- щие действия:
1. В директории .git/refs/heads создаётся файл, имя которого совпа- дает с именем новой ветки, указанным в команде git branch.
2. В созданный файл записывается хеш-значение текущего коммита,

54 того, на который указывает HEAD через соответствующий файл в директо- рии .git/refs/heads.
На рисунке 2.8 показана ситуация, которая возникнет при добавлении ветки New_branch в репозиторий, главная ветка которого называется
Main_branch. Если продолжить делать коммиты, то они будут добавляться в главную ветку, после коммита ГВ3. Для добавления коммитов в новую ветку на неё необходимо переключиться. Для переключения между ветками предназначена команда git checkout.
Формат команды git checkout:
git checkout <ключ> <имя ветки>
Рисунок 2.8 – Создание новой ветки
Одним из возможных ключей является -b. Использование команды git checkout с ключом -b эквивалентно последовательности команд git branch и git checkout. Произойдёт создание новой ветки и переключение на неё.
После выполнения команды git checkout в файл HEAD будет записано имя файла из директории .git/refs/heads, совпадающее с именем ветки, на которую произошло переключение. Если выполнить несколько коммитов, то ситуация будет выглядеть, как показано на рисунке 2.9.


55
Рисунок 2.9 – Добавление коммитов в новую ветку
Для просмотра веток, существующих в репозитории, используется команда git branch с ключами -a или -r или без ключей.
Использование ключа -a или команды git branch без ключей приведёт к выводу полного списка веток.
Использование ключа -r приведёт к выводу списка веток из удалённого репозитория (об удалённых репоиториях речь пойдёт в одном из следующих разделов).
Так выглядит список веток из примера:
$ git branch -a
*
Main_branch
New_branch
Текущая ветка в списке отмечена звёздочкой.
При переключении на другую ветку происходит не только изменение содержимого файла HEAD, но и изменение состояния рабочей директории.
Проще всего представить себе перестройку рабочей директории следующим образом. Назовём последний коммит в текущей ветке «источником», а последний коммит в ветке, на которую происходит переход, «приёмником».
Все файлы, имена которых присутствуют одновременно в «источнике» и
«приёмнике», удаляются из рабочей директории. После этого в рабочую директорию записываются файлы, восстановленные из blob-объектов
«приёмника».

56
При переходе между ветками нужно иметь в виду следующее:
1. Все изменения, сделанные в текущей рабочей директории в отслеживаемых файлах и не включённые в коммит, буду потеряны.
2. Все неотслеживаемые файлы перейдут в «приёмник».
Эти особенности перехода между ветками могут стать источником серьёзных проблем. Для того чтобы избежать проблем, есть два пути:
− сделать коммит перед переходом на другую ветку;
− использовать команду stash того, чтобы «складировать» изменения во временном хранилище.
2.13. Команда git stash
Если выполненные изменения рано добавлять в коммит, и есть необ- ходимость переключиться на другую ветку для выполнения срочной ра- боты, чтобы не потерять изменения, их можно «складировать».
Для «складирования» изменений нужно выполнить команду:
git stash save или git stash. git stash save позволяет добавить коммента- рий к «складируемым» файлам.
При выполнении команды git stash происходит следующее:
− создаётся резервный коммит;
− резервный коммит сохраняется в изолированном хранилище, построенном по принципу стека;
− состояние рабочей директории восстанавливается из последнего коммита текущей ветки.
Для того чтобы добавить в резервный коммит неотслеживаемые файлы, необходимо использовать ключ -u (напимер, git stash save -u
‘Резервная копия 1’).
Посмотреть, что хранится на «складе», можно с помощью команды:
git stash list
Пример выполнения команды git stash list:
$ git stash list stash@{0}: On Main_branch: Склад для ветки Main_Branch stash@{1}: On New_Branch: Склад для ветки New_Branch


57
Каждый хранимый на «складе» временный коммит имеет номер stash@{число}. К временному коммиту можно обращаться либо с использова- нием правила стека («последний пришёл, первый ушёл), либо по номеру.
При извлечении временного коммита со «склада» происходит восста- новление рабочей директории в соответствии с описанием, хранящимся в этом коммите.
Команда:
git stash apply
извлекает со «склада» временный коммит с номером 0.
Можно указать номер того коммита, который необходимо извлечь:
git stash apply stash@{число}
Команда git stash pop выполняет те же действия, что и git stash apply, и удаляет временный коммит со «склада». Без указания номера команда git stash pop будет применена к временному коммиту с номером 0.
Команда git stash show показывает, какие изменения были сохранены во временном коммите c номером 0.
$ git stash show
File_1.txt | 3
++
-
1 file changed, 2 insertions(+), 1 deletion(-)
Детали изменения можно посмотреть при использовании ключа -p.
$ git stash show -p diff --git a/File_1.txt b/File_1.txt index 1da2014..2fb2027 100644
--- a/File_1.txt
+++ b/File_1.txt
@@ -1 +1,2 @@
-This is first file we will use for tests.
\ No newline at end of file
+This is first file we will use for tests.
+Changes for test stash.
\ No newline at end of file
Как и в других командах, относящихся к stash, можно указать номер временного коммита, который будет использован для просмотра изменений.
Команда git stash branch <имя новой ветки> создаёт новую ветку с указанным именем и переносит в неё содержимое временного коммита. Без указания номера для создания ветки будет использован временный коммит с номером 0.
Команда git stash drop удаляет временный коммит. Без указания но- мера будет удалён временный коммит с номером 0.

58
Команда git stash clear удаляет весь «склад».
2.14. Просмотр истории коммитов
История коммитов бывает полезна в следующих ситуациях:
− необходимо посмотреть историю коммитов, чтобы составить пред- ставление о том, как развивается проект;
− необходимо выяснить, кто внёс те или иные изменения;
− необходимо определить хеш-номер коммита, к которому нужно вернуться.
Для просмотра истории коммитов используется команда git log.
Формат команды git log:
git log <ключи> --<путь>
Возможные значения ключей:
-<число> или -n<число> – выводит последние коммиты в количестве, заданном числом;
--pretty = <значение> – значение задаёт формат вывода, может быть oneline, short, medium, full;
-p – показывает изменения, сделанные в текущем коммите;
--all – выводит историю всех коммитов для всех веток.
Правило, которым руководствуется Git при выводе истории, гласит:
«Переходить от одного предка к другому, пока они не закончатся».
Рассмотрим для примера репозиторий, граф которого изображён на рисунке 2.10.