Назад: Шаг 11-20 ..
Вперед: Шаг 31-40
21. Подробнее о структуре
Цели: Добавить еще один файл в наш репозиторий
21.01 Добавление index.html
Давайте добавим файл index.html в наш репозиторий. Следующий файл отлично подойдет для этой цели.
ФАЙЛ: HTML
<html>
<body>
<iframe src="lib/hello.html" width="200" height="200" />
</body>
</html>
Добавьте файл и сделайте коммит.
ВЫПОЛНИТЕ:
git add index.html
git commit -m "Added index.html."
Теперь при открытии index.html, вы должны увидеть кусок страницы hello в маленьком окошке.
22. Git внутри: Каталог .git
Цели: Узнать о структуре каталога .git
22.01 Каталог .git
Настало время провести небольшое исследование. Для начала, из корневого каталога вашего проекта…
ВЫПОЛНИТЕ:
РЕЗУЛЬТАТ:
$ ls -C .git
COMMIT_EDITMSG MERGE_RR config hooks info objects rr-cache
HEAD ORIG_HEAD description index logs refs
Это магический каталог, в котором хранятся все «материалы» git. Давайте заглянем в каталог объектов.
22.02 База данных объектов
ВЫПОЛНИТЕ:
РЕЗУЛЬТАТ:
$ ls -C .git/objects
09 24 28 45 59 6a 77 80 8c 97 af c4 e7 info
11 27 43 56 69 6b 78 84 91 9c b5 e4 fa pack
Вы должны увидеть кучу каталогов, имена которых состоят из 2 символов. Имена каталогов являются первыми двумя буквами хэша sha1 объекта, хранящегося в git.
22.03 Углубляемся в базу данных объектов
ВЫПОЛНИТЕ:
РЕЗУЛЬТАТ:
$ ls -C .git/objects/09
6b74c56bfc6b40e754fc0725b8c70b2038b91e 9fb6f9d3a104feb32fcac22354c4d0e8a182c1
Смотрим в один из каталогов с именем из 2 букв. Вы увидите файлы с именами из 38 символов. Это файлы, содержащие объекты, хранящиеся в git. Они сжаты и закодированы, поэтому просмотр их содержимого нам мало чем поможет. Рассмотрим далее каталог .git внимательно
22.04 Config File
ВЫПОЛНИТЕ:
РЕЗУЛЬТАТ:
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
[user]
name = Alexander Shvets
email = alex@githowto.com
Это файл конфигурации, создающийся для каждого конкретного проекта. Записи в этом файле будут перезаписывать записи в файле .gitconfig вашего главного каталога, по крайней мере в рамках этого проекта.
22.05 Ветки и теги
ВЫПОЛНИТЕ:
ls .git/refs
ls .git/refs/heads
ls .git/refs/tags
cat .git/refs/tags/v1
РЕЗУЛЬТАТ:
$ ls .git/refs
heads
tags
$ ls .git/refs/heads
master
$ ls .git/refs/tags
v1
v1-beta
$ cat .git/refs/tags/v1
fa3c1411aa09441695a9e645d4371e8d749da1dc
Вы должны узнавать файлы в подкаталоге тегов. Каждый файл соответствует тегу, ранее созданному с помощью команды git tag. Его содержание – это всего лишь хэш коммита, привязанный к тегу.
Каталог heads практически аналогичен, но используется для веток, а не тегов. На данный момент у нас есть только одна ветка, так что все, что вы увидите в этом каталоге – это ветка master.
22.06 Файл HEAD
ВЫПОЛНИТЕ:
РЕЗУЛЬТАТ:
$ cat .git/HEAD
ref: refs/heads/master
Файл HEAD содержит ссылку на текущую ветку, в данный момент это должна быть ветка master.
23. Git внутри: Работа непосредственно с объектами git
Цели:
- Исследовать структуру базы данных объектов
- Научиться использовать SHA1 хэши для поиска содержимого в репозитории
Давайте исследуем объекты git с помощью некоторых инструментов.
23.01 Поиск последнего коммита
Выполните:
Эта команда должна показать последний коммит в репозиторий. SHA1 хэш в вашей системе, вероятно, отличается от моего, но вы увидите что-то наподобие этого.
РЕЗУЛЬТАТ:
$ git hist --max-count=1
* 8029c07 2011-03-09 | Added index.html. (HEAD, master) [Alexander Shvets]
23.02 Вывод последнего коммита
С помощью SHA1 хэша из коммита, указанного выше…
Выполните:
git cat-file -t <hash>
git cat-file -p <hash>
Вот что выходит у меня…
$ git cat-file -t 8029c07
commit
$ git cat-file -p 8029c07
tree 096b74c56bfc6b40e754fc0725b8c70b2038b91e
parent 567948ac55daa723807c0c16e34c76797efbcbed
author Alexander Shvets <alex@githowto.com> 1299684476 -0500
committer Alexander Shvets <alex@githowto.com> 1299684476 -0500
Added index.html.
Примечание: Если вы задали алиасы «type» и «dump», как описано в уроке об алиасах, можете вводить команды
git type
и
git dump
вместо длинных команд (которые я никогда не запоминаю).
Это вывод объекта коммита, который находится во главе ветки master.
23.03 Поиск дерева
Мы можем вывести дерево каталогов, ссылка на который идет в коммите. Это должно быть описание файлов (верхнего уровня) в нашем проекте (для конкретного коммита). Используйте SHA1 хэш из строки «дерева», из списка выше.
Выполните:
git cat-file -p <treehash>
Вот как выглядит мое дерево…
Результат:
$ git cat-file -p 096b74c
100644 blob 28e0e9d6ea7e25f35ec64a43f569b550e8386f90 index.html
040000 tree e46f374f5b36c6f02fb3e9e922b79044f754d795 lib
Да, я вижу index.html и каталог lib.
23.04 Вывод каталога lib
Выполните:
git cat-file -p <libhash>
Результат:
$ git cat-file -p e46f374
100644 blob c45f26b6fdc7db6ba779fc4c385d9d24fc12cf72 hello.html
Существует файл
hello.html
.
23.05 Вывод файла hello.html
Выполните:
git cat-file -p <hellohash>
Результат:
$ git cat-file -p c45f26b
<!-- Author: Alexander Shvets (alex@githowto.com) -->
<html>
<head>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
А вот и он. Мы вывели объекты коммитов, объекты деревьев и объекты блобов непосредственно из репозитория git. Это все, что есть – блобы, деревья и коммиты.
23.06 Исследуйте самостоятельно
Исследуйте git репозиторий вручную самостоятельно. Смотрите, удастся ли вам найти оригинальный файл hello.html с самого первого коммита вручную по ссылкам SHA1 хэша в последнем коммите.
24. Создание ветки
Цели: Научиться создавать локальную ветку в репозитории
Пора сделать наш hello world более выразительным. Так как это может занять некоторое время, лучше переместить эти изменения в отдельную ветку, чтобы изолировать их от изменений в ветке master.
24.01 Создайте ветку
Давайте назовем нашу новую ветку «style».
Выполните:
git checkout -b style
git status
Примечание:
git checkout -b имяветки
является шорткатом для
git branch имяветки
за которым идет
git checkout имяветки
.
Обратите внимание, что команда
git status
сообщает о том, что вы находитесь в ветке
style.
24.02 Добавьте файл стилей style.css
Выполните:
ФАЙЛ: lib/style.css
24.03 Измените основную страницу
Обновите файл hello.html, чтобы использовать стили style.css.
ФАЙЛ: lib/hello.html
<!-- Author: Alexander Shvets (alex@githowto.com) -->
<html>
<head>
<link type="text/css" rel="stylesheet" media="all" href="style.css" />
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
Выполните:
git add lib/hello.html
git commit -m "Hello uses style.css"
24.04 Измените index.html
Обновите файл index.html, чтобы он тоже использовал style.css
ФАЙЛ: index.html
<html>
<head>
<link type="text/css" rel="stylesheet" media="all" href="lib/style.css" />
</head>
<body>
<iframe src="lib/hello.html" width="200" height="200" />
</body>
</html>
Выполните:
git add index.html
git commit -m "Updated index.html"
24.05 Далее
Теперь у нас есть новая ветка под названием style с 3 новыми коммитами. Далее мы узнаем, как осуществлять навигацию и переключаться между ветками.
25. Навигация по веткам
Цели: Научиться перемещаться между ветками репозитория
Теперь в вашем проекте есть две ветки:
Выполните:
Результат:
$ git hist --all
* 07a2a46 2011-03-09 | Updated index.html (HEAD, style) [Alexander Shvets]
* 649d26c 2011-03-09 | Hello uses style.css [Alexander Shvets]
* 1f3cbd2 2011-03-09 | Added css stylesheet [Alexander Shvets]
* 8029c07 2011-03-09 | Added index.html. (master) [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [Alexander Shvets]
* fa3c141 2011-03-09 | Added HTML header (v1) [Alexander Shvets]
* 8c32287 2011-03-09 | Added standard HTML page tags (v1-beta) [Alexander Shvets]
* 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets]
* 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
25.01 Переключение на ветку Master
Просто используйте команду
git checkout для переключения между ветками.
Выполните:
git checkout master
cat lib/hello.html
Результат:
$ git checkout master
Switched to branch 'master'
$ cat lib/hello.html
<!-- Author: Alexander Shvets (alex@githowto.com) -->
<html>
<head>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
Сейчас мы находимся на ветке Master. Это заметно по тому, что файл hello.html не использует стили style.css.
25.02 Вернемся к ветке «style».
Выполните:
git checkout style
cat lib/hello.html
Результат:
$ git checkout style
Switched to branch 'style'
$ cat lib/hello.html
<!-- Author: Alexander Shvets (alex@githowto.com) -->
<html>
<head>
<link type="text/css" rel="stylesheet" media="all" href="style.css" />
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
Содержимое
lib/hello.html
подтверждает, что мы вернулись в ветку
style
26. Изменения в ветке master
Цели: Научиться работать с несколькими ветками с различными (и, возможно, конфликтующими) изменениями.
Пока вы меняли ветку «style», кто-то решил обновить ветку master. Они добавили README.
26.01 Создайте файл README в ветке master
Выполните:
Файл README:
This is the Hello World example from the git tutorial.
26.02 Сделайте коммит изменений README в ветку master
Выполните:
git add README
git commit -m "Added README"
27. Просмотр отличающихся веток
Цели: научиться просматривать отличающиеся ветки в репозитории.
27.01 Просмотрите текущие ветки
Теперь у нас в репозитории есть две отличающиеся ветки. Используйте следующую лог-команду для просмотра веток и их отличий.
Выполните:
Результат:
$ git hist --all
* 6c0f848 2011-03-09 | Added README (HEAD, master) [Alexander Shvets]
| * 07a2a46 2011-03-09 | Updated index.html (style) [Alexander Shvets]
| * 649d26c 2011-03-09 | Hello uses style.css [Alexander Shvets]
| * 1f3cbd2 2011-03-09 | Added css stylesheet [Alexander Shvets]
|/
* 8029c07 2011-03-09 | Added index.html. [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [Alexander Shvets]
* fa3c141 2011-03-09 | Added HTML header (v1) [Alexander Shvets]
* 8c32287 2011-03-09 | Added standard HTML page tags (v1-beta) [Alexander Shvets]
* 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets]
* 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
Это наша первая возможность увидеть в действии --graph в git hist. Добавление опции --graph в git log вызывает построение дерева коммитов с помощью простых ASCII символов. Мы видим обе ветки (style и master), и то, что ветка master является текущей HEAD. Общим предшественником обеих веток является коммит «Added index.html».
Метка --all гарантированно означает, что мы видим все ветки. По умолчанию показывается только текущая ветка.
28. Слияние (merge)
Цели: Научиться сливать две отличающиеся ветки для переноса изменений обратно в одну ветку.
28.01 Слияние веток
Слияние переносит изменения из двух веток в одну. Давайте вернемся к ветке style и сольем master с style.
Выполните:
git checkout style
git merge master
git hist --all
Результат:
$ git checkout style
Switched to branch 'style'
$ git merge master
Merge made by recursive.
README | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 README
$ git hist --all
* 5813a3f 2011-03-09 | Merge branch 'master' into style (HEAD, style) [Alexander Shvets]
|\
| * 6c0f848 2011-03-09 | Added README (master) [Alexander Shvets]
* | 07a2a46 2011-03-09 | Updated index.html [Alexander Shvets]
* | 649d26c 2011-03-09 | Hello uses style.css [Alexander Shvets]
* | 1f3cbd2 2011-03-09 | Added css stylesheet [Alexander Shvets]
|/
* 8029c07 2011-03-09 | Added index.html. [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [Alexander Shvets]
* fa3c141 2011-03-09 | Added HTML header (v1) [Alexander Shvets]
* 8c32287 2011-03-09 | Added standard HTML page tags (v1-beta) [Alexander Shvets]
* 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets]
* 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
Путем периодического слияния ветки master с веткой style вы можете переносить из master любые изменения и поддерживать совместимость изменений style с изменениями в основной ветке.
Однако, это делает графики коммитов действительно уродливыми. Позже мы рассмотрим возможность перебазирования, как альтернативы слиянию.
28.02 Далее
Но что если изменения в ветке master конфликтуют с изменениями в style?
29. Создание конфликта
Цели: Создание конфликтующих изменений в ветке master.
29.01 Вернитесь в master и создайте конфликт
Вернитесь в ветку master и внесите следующие изменения:
ФАЙЛ: lib/hello.html
<!-- Author: Alexander Shvets (alex@githowto.com) -->
<html>
<head>
<!-- no style -->
</head>
<body>
<h1>Hello, World! Life is great!</h1>
</body>
</html>
Выполните:
git add lib/hello.html
git commit -m 'Life is great!'

Внимание: используйте для этого коммита одинарные кавычки, дабы избежать проблем с символом !. В bash он считается служебным.
29.02 Просмотр веток
Выполните:
Результат:
$ git hist --all
* 454ec68 2011-03-09 | Life is great! (HEAD, master) [Alexander Shvets]
| * 5813a3f 2011-03-09 | Merge branch 'master' into style (style) [Alexander Shvets]
| |\
| |/
|/|
* | 6c0f848 2011-03-09 | Added README [Alexander Shvets]
| * 07a2a46 2011-03-09 | Updated index.html [Alexander Shvets]
| * 649d26c 2011-03-09 | Hello uses style.css [Alexander Shvets]
| * 1f3cbd2 2011-03-09 | Added css stylesheet [Alexander Shvets]
|/
* 8029c07 2011-03-09 | Added index.html. [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [Alexander Shvets]
* fa3c141 2011-03-09 | Added HTML header (v1) [Alexander Shvets]
* 8c32287 2011-03-09 | Added standard HTML page tags (v1-beta) [Alexander Shvets]
* 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets]
* 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
После коммита «Added README» ветка master была объединена с веткой style, но в настоящее время в master есть дополнительный коммит, который не был слит с style.
29.03 Далее
Последнее изменение в master конфликтует с некоторыми изменениями в style. В следующем шаге мы решим этот конфликт.
30. Разрешение конфликтов
Цели: Научиться разрешать конфликты во время слияния
30.01 Слияние master с веткой style
Теперь вернемся к ветке style и попытаемся объединить ее с новой веткой master.
Выполните:
git checkout style
git merge master
Результат:
$ git checkout style
Switched to branch 'style'
$ git merge master
Auto-merging lib/hello.html
CONFLICT (content): Merge conflict in lib/hello.html
Automatic merge failed; fix conflicts and then commit the result.
Если вы откроете lib/hello.html, вы увидите:
ФАЙЛ: lib/hello.html
<!-- Author: Alexander Shvets (alex@githowto.com) -->
<html>
<head>
<<<<<<< HEAD
<link type="text/css" rel="stylesheet" media="all" href="style.css" />
=======
<!-- no style -->
>>>>>>> master
</head>
<body>
<h1>Hello,World! Life is great!</h1>
</body>
</html>
Первый раздел - версия во главе текущей ветки (style). Второй раздел - версия ветки master.
30.02 Решение конфликта
Вам необходимо вручную разрешить конфликт. Внесите изменения в lib/hello.html для достижения следующего результата.
ФАЙЛ: lib/hello.html
<!-- Author: Alexander Shvets (alex@githowto.com) -->
<html>
<head>
<link type="text/css" rel="stylesheet" media="all" href="style.css" />
</head>
<body>
<h1>Hello, World! Life is great!</h1>
</body>
</html>
30.03 Сделайте коммит решения конфликта
Выполните:
git add lib/hello.html
git commit -m "Merged master fixed conflict."
Результат:
$ git add lib/hello.html
$ git commit -m "Merged master fixed conflict."
Recorded resolution for 'lib/hello.html'.
[style 645c4e6] Merged master fixed conflict.
30.04 Расширенные возможности слияния
Git не предоставляет никаких графических инструментов слияния, но будет с удовольствием работать с любыми сторонними инструментами слияния, которые вы хотите использовать ([[http://stackoverflow.com/questions/137102/whats-the-best-visual-merge-tool-for-git][обсуждение таких инструментов на
StackOverflow?]).