
- •Введение
- •Об управлении версиями
- •Локальные системы управления версиями
- •Централизованные системы управления версиями
- •Распределённые системы контроля версий
- •Краткая история Git
- •Основы Git
- •Слепки вместо патчей
- •Почти все операции — локальные
- •Git следит за целостностью данных
- •Чаще всего данные в Git только добавляются
- •Три состояния
- •Установка Git
- •Установка из исходников
- •Установка в Linux
- •Установка на Mac
- •Установка в Windows
- •Первоначальная настройка Git
- •Имя пользователя
- •Выбор редактора
- •Утилита сравнения
- •Проверка настроек
- •Как получить помощь?
- •Итоги
- •Основы Git
- •Создание репозитория Git
- •Создание репозитория в существующем каталоге
- •Клонирование существующего репозитория
- •Запись изменений в репозиторий
- •Определение состояния файлов
- •Отслеживание новых файлов
- •Индексация измененных файлов
- •Игнорирование файлов
- •Просмотр индексированных и неиндексированных изменений
- •Фиксация изменений
- •Игнорирование индексации
- •Удаление файлов
- •Перемещение файлов
- •Просмотр истории коммитов
- •Ограничение вывода команды log
- •Использование графического интерфейса для визуализации истории
- •Отмена изменений
- •Изменение последнего коммита
- •Отмена индексации файла
- •Отмена изменений файла
- •Работа с удалёнными репозиторями
- •Отображение удалённых репозиториев
- •Добавление удалённых репозиториев
- •Fetch и Pull
- •Push
- •Инспекция удалённого репозитория
- •Удаление и переименование удалённых репозиториев
- •Работа с метками
- •Просмотр меток
- •Создание меток
- •Аннотированные метки
- •Подписанные метки
- •Легковесные метки
- •Верификация меток
- •Выставление меток позже
- •Обмен метками
- •Полезные советы
- •Автоматическое дополнение
- •Псевдонимы в Git
- •Итоги
- •Ветвление в Git
- •Что такое ветка?
- •Основы ветвления и слияния
- •Основы ветвления
- •Основы слияния
- •Основы конфликтов при слиянии
- •Управление ветками
- •Приемы работы с ветками
- •Долгоживущие ветки
- •Тематические ветки
- •Удалённые ветки
- •Отправка изменений
- •Отслеживание веток
- •Удаление веток на удалённом сервере
- •Перемещение
- •Основы перемещения
- •Более интересные перемещения
- •Возможные риски перемещения
- •Итоги
- •Git на сервере
- •Протоколы
- •Локальный протокол
- •Преимущества
- •Недостатки
- •Протокол SSH
- •Достоинства
- •Недостатки
- •Git-протокол
- •Достоинства
- •Недостатки
- •Протокол HTTP/S
- •Достоинства
- •Недостатки
- •Установка Git на сервер
- •Размещение «голого» репозитория на сервере
- •Малые установки
- •SSH доступ
- •Создание открытого SSH-ключа
- •Настраиваем сервер
- •Открытый доступ
- •GitWeb
- •Gitosis
- •Gitolite
- •Установка
- •Изменение параметров установки
- •Конфигурационный файл и правила контроля доступа
- •Продвинутый контроль доступа с запрещающими правилами
- •Ограничение push-ей на основе изменённых файлов
- •Персональные ветки
- •«Шаблонные» репозитории
- •Другие функции
- •Git-демон
- •Git-хостинг
- •GitHub
- •Настройка учётной записи
- •Создание нового репозитория
- •Импорт из Subversion
- •Добавление участников
- •Ваш проект
- •Ответвления проектов
- •Заключение о GitHub
- •Итоги
- •Распределённый Git
- •Распределённые рабочие процессы
- •Централизованный рабочий процесс
- •Рабочий процесс с менеджером по интеграции
- •Рабочий процесс с диктатором и его помощниками
- •Содействие проекту
- •Рекомендации по созданию коммитов
- •Отдельная маленькая команда
- •Отдельная команда с менеджером
- •Небольшой открытый проект
- •Большой открытый проект
- •Итоги
- •Сопровождение проекта
- •Работа с тематическими ветками
- •Применение патчей, отправленных по почте
- •Применение патчей с помощью команды apply
- •Применение патчей с помощью команды am
- •Проверка удалённых веток
- •Определение вносимых изменений
- •Интегрирование чужих наработок
- •Процессы слияния
- •Рабочие процессы с крупными слияниями
- •Рабочие процессы с перемещениями и отбором лучшего
- •Отметка релизов
- •Генерация номера сборки
- •Подготовка релиза
- •Команда shortlog
- •Итоги
- •Инструменты Git
- •Выбор ревизии
- •Одиночные ревизии
- •Сокращенный SHA
- •Небольшое замечание о SHA-1
- •Ссылки на ветки
- •RefLog-сокращения
- •Ссылки на предков
- •Диапазон коммитов
- •Две точки
- •Множество вершин
- •Три точки
- •Интерактивное индексирование
- •Добавление и удаление файлов из индекса
- •Индексирование по частям
- •Прятанье
- •Прятанье своих трудов
- •Откат применения спрятанных изменений
- •Создание ветки из спрятанных изменений
- •Перезапись истории
- •Изменение последнего коммита
- •Изменение сообщений нескольких коммитов
- •Переупорядочение коммитов
- •Уплотнение коммитов
- •Разбиение коммита
- •Крайнее средство: filter-branch
- •Удаление файла изо всех коммитов
- •Сделать подкаталог новым корнем
- •Отладка с помощью Git
- •Аннотация файла
- •Бинарный поиск
- •Подмодули
- •Начало использования подмодулей
- •Клонирование проекта с подмодулями
- •Суперпроекты
- •Проблемы с подмодулями
- •Слияние поддеревьев
- •Итоги
- •Настройка Git
- •Конфигурирование Git
- •Основные настройки клиента
- •core.editor
- •commit.template
- •core.pager
- •user.signingkey
- •core.excludesfile
- •help.autocorrect
- •Цвета в Git
- •color.ui
- •color.*
- •Внешние утилиты merge и diff
- •Форматирование и пробельные символы
- •core.autocrlf
- •core.whitespace
- •Настройка сервера
- •receive.fsckObjects
- •receive.denyNonFastForwards
- •receive.denyDeletes
- •Git-атрибуты
- •Бинарные файлы
- •Определение бинарных файлов
- •Получение дельты для бинарных файлов
- •Документы MS Word
- •Текстовые файлы в формате OpenDocument
- •Изображения
- •Развёртывание ключа
- •Экспорт репозитория
- •export-ignore
- •export-subst
- •Стратегии слияния
- •Перехватчики в Git
- •Установка перехватчика
- •Перехватчики на стороне клиента
- •Перехватчики для работы с коммитами
- •Другие клиентские перехватчики
- •Перехватчики на стороне сервера
- •update
- •Пример навязывания политики с помощью Git
- •Перехватчик на стороне сервера
- •Установка особого формата сообщений коммитов
- •Настройка системы контроля доступа для пользователей
- •Перехватчики на стороне клиента
- •Итоги
- •Git и Subversion
- •Настройка
- •Приступим к работе
- •Коммит в Subversion
- •Получение новых изменений
- •Проблемы с ветвлением в Git
- •Ветвление в Subversion
- •Создание новой ветки в SVN
- •Переключение активных веток
- •Команды Subversion
- •Просмотр истории в стиле SVN
- •SVN-Аннотации
- •Игнорирование того, что игнорирует Subversion
- •Заключение по Git-Svn
- •Миграция на Git
- •Импортирование
- •Subversion
- •Perforce
- •Собственная утилита для импорта
- •Итоги
- •Git изнутри
- •Сантехника и фарфор
- •Объекты в Git
- •Объекты-деревья
- •Объекты-коммиты
- •Хранение объектов
- •Ссылки в Git
- •HEAD
- •Метки
- •Ссылки на удалённые ветки
- •Pack-файлы
- •Спецификации ссылок
- •Спецификации ссылок для команды push
- •Удаление ссылок
- •Протоколы передачи
- •Тупой протокол
- •Умный протокол
- •Загрузка данных
- •Скачивание данных
- •Обслуживание и восстановление данных
- •Обслуживание
- •Восстановление данных
- •Удаление объектов
- •Итоги

Scott Chacon Pro Git |
Раздел 7.2 Git-атрибуты |
$ git config --system receive.denyDeletes true
Этим вы запретите удаление веток и меток с помощью команды push для всех сразу — ни один из пользователей не сможет этого сделать. Чтобы удалить ветку на сервере, вам придётся удалить файлы ссылок с сервера вручную. Также есть и другие более интересные способы добиться этого, но уже для отдельных пользователей с помощью ACL (списков контроля доступа),
как мы увидим в конце этой главы.
7.2 Git-атрибуты
Некоторые настройки могут быть заданы для отдельных путей, и тогда Git будет применять их только для некоторых подкаталогов или набора файлов. Такие настройки специфичные по отношению к путям называются атрибутами и задаются либо в файле .gitattributes в
одном из каталогов проекта (обычно в корне) или в файле .git/info/attributes, если вы не хотите, чтобы файл с атрибутами попал в коммит вместе с остальными файлами проекта.
Использование атрибутов позволяет, например, задать разные стратегии слияния для отдельных файлов или каталогов проекта, или объяснить Git’у, как сравнивать нетекстовые файлы, или сделать так, чтобы Git пропускал данные через фильтр перед тем, как выгрузить или записать данные в репозиторий. В этом разделе мы рассмотрим некоторые из доступных в Git’е атрибутов
и рассмотрим несколько практических примеров их использования.
7.2.1 Бинарные файлы
Есть один клёвый трюк, для которого можно использовать атрибуты — можно указать
Git’у, какие файлы являются бинарными (в случае если по-другому определить это не получается),
и дать ему специальные инструкции о том, как с этими файлами работать. Например, некоторые текстовые файлы могут быть машинными — генерируемыми программой — для них нет смысла вычислять дельты, в то время как для некоторых бинарных файлов получение дельт может быть полезным. Дальше мы увидим, как сказать Git’у, какие файлы какие.
Определение бинарных файлов Некоторые файлы выглядят как текстовые, но по существу должны рассматриваться как бинарные данные. Например, проекты Xcode на Mac’ах содержат файл, оканчивающийся на .pbxproj, который по сути является набором JSON-данных (текстовый формат данных для javascript), записываемым IDE, в котором сохраняются ваши настройки сборки и прочее. Хоть технически это и текстовый файл, потому что содержит только ASCII-
символы, но нет смысла рассматривать его как таковой, потому что на самом деле это легковесная база данных — вы не сможете слить её содержимое, если два человека внесут в неё изменение,
получение дельт тоже, как правило, ничем вам не поможет. Этот файл предназначается для обработки программой. По сути, лучше рассматривать этот файл как бинарный.
Чтобы заставить Git обращаться со всеми pbxproj файлами как с бинарными, добавьте следующую строку в файл .gitattributes:
*.pbxproj -crlf -diff
195

Глава 7 Настройка Git |
Scott Chacon Pro Git |
Теперь Git не будет пытаться конвертировать CRLF-концы строк или исправлять проблемы с ними. Также он не будет пытаться получить дельту для изменений в этом файле при запуске git show или git diff в вашем проекте. Начиная с версии 1.6 в Git есть макрос, который означает то же, что и -crlf -diff:
*.pbxproj binary
Получение дельты для бинарных файлов В Git версии 1.6.x функциональность атрибутов может быть использована для эффективного получения дельт для бинарных файлов. Чтобы сделать это, нужно объяснить Git’у, как сконвертировать ваши бинарные данные в текстовый формат, для которого можно выполнить сравнение с помощью обычного diff.
Документы MS Word Так как эта довольно клёвая функция не особо широко известна, мы рассмотрим несколько примеров её использования. Для начала мы используем этот подход,
чтобы решить одну из самых раздражающих проблем известных человечеству: версионный контроль документов Word. Всем известно, что Word это самый ужасающий из всех существующих редакторов, но, как ни странно, все им пользуются. Если вы хотите поместить документы Word
под версионный контроль, вы можете запихнуть их в Git-репозиторий и время от времени делать коммиты. Но что в этом хорошего? Если вы запустите git diff как обычно, то увидите только что-то наподобие этого:
$ git diff
diff --git a/chapter1.doc b/chapter1.doc
index 88839c4..4afcb7c 100644
Binary files a/chapter1.doc and b/chapter1.doc differ
У вас не получится сравнить две версии между собой, только если вы не выгрузите их обе и просмотрите их вручную, так? Оказывается, можно сделать это достаточно успешно,
используя атрибуты Git. Поместите следующую строку в свой файл .gitattributes:
*.doc diff=word
Она говорит Git’у, что все файлы, соответствующие указанному шаблону (.doc) должны использовать фильтр «word» при попытке посмотреть дельту с изменениями. Что такое фильтр
«word»? Нам нужно его изготовить. Сейчас мы настроим Git на использование программы strings для конвертирования документов Word в читаемые текстовые файлы, которые Git
затем правильно сравнит:
$ git config diff.word.textconv strings
Этой командой в свой .git/config вы добавите следующую секцию:
196

Scott Chacon Pro Git |
Раздел 7.2 Git-атрибуты |
[diff "word"]
textconv = strings
Замечание: Существуют разные виды .doc файлов. Некоторые из них могут использовать кодировку UTF-16 или могут быть написаны не в латинице, в таких файлах strings не найдёт ничего хорошего. Полезность strings может сильно варьироваться.
Теперь Git знает, что если ему надо найти дельту между двумя снимками состояния, и
какие-то их файлы заканчиваются на .doc, он должен прогнать эти файлы через фильтр «word»,
который определён как программа strings. Так вы фактически сделаете текстовые версии своих Word-файлов перед тем, как получить для них дельту.
Рассмотрим пример. Я поместил Главу 1 настоящей книги в Git, добавил немного текста в один параграф и сохранил документ. Затем я выполнил git diff, чтобы увидеть, что изменилось:
$ git diff
diff --git a/chapter1.doc b/chapter1.doc index c1c8a0a..b93c9e4 100644
--- a/chapter1.doc
+++ b/chapter1.doc
@@ -8,7 +8,8 @@ re going to cover Version Control Systems (VCS) and Git basics re going to cover how to get it and set it up for the first time if you don t already have it on your system.
In Chapter Two we will go over basic Git usage - how to use Git for the 80% -s going on, modify stuff and contribute changes. If the book spontaneously +s going on, modify stuff and contribute changes. If the book spontaneously +Let's see if this works.
Git коротко и ясно дал мне знать, что я добавил строку «Let’s see if this works», так оно и есть. Работает не идеально, так как добавляет немного лишнего в конце, но определённо работает. Если вы сможете найти или написать хорошо работающую программу для конвертации документов Word в обычный текст, то такое решение скорее всего будет невероятно эффективно.
Тем не менее, strings доступен на большинстве Mac и Linux-систем, так что он может быть хорошим первым вариантом для того, чтобы сделать подобное со многими бинарными форматами.
Текстовые файлы в формате OpenDocument Тот же подход, который мы использовали для файлов MS Word (*.doc), может быть использован и для текстовых файлов в формате OpenDocument, созданных в OpenOffice.org.
Добавим следующую строку в файл .gitattributes:
*.odt diff=odt
Теперь настроим фильтр odt в .git/config:
197

Глава 7 Настройка Git |
Scott Chacon Pro Git |
[diff "odt"]
binary = true
textconv = /usr/local/bin/odt-to-txt
Файлы в формате OpenDocument на самом деле являются запакованными zip’ом каталогами с множеством файлов (содержимое в XML-формате, таблицы стилей, изображения и т.д.).
Мы напишем сценарий для извлечения содержимого и вывода его в виде обычного текста.
Создайте файл /usr/local/bin/odt-to-txt (можете создать его в любом другом каталоге)
со следующим содержимым:
#! /usr/bin/env perl
#Сценарий для конвертации OpenDocument Text (.odt) в обычный текст.
#Автор: Philipp Kempgen
if (! defined($ARGV[0])) {
print STDERR "Не задано имя файла!\n";
print STDERR "Использование: $0 имя файла\n"; exit 1;
}
my $content = '';
open my $fh, '-|', 'unzip', '-qq', '-p', $ARGV[0], 'content.xml' or die $!;
{ |
|
|
local $/ = undef; # считываем файл целиком |
|
|
$content = <$fh>; |
|
|
} |
|
|
close $fh; |
|
|
$_ = $content; |
|
|
s/<text:span\b[^>]*>//g; |
# удаляем span'ы |
|
s/<text:h\b[^>]*>/\n\n***** /g; |
# заголовки |
|
s/<text:list-item\b[^>]*>\s*<text:p\b[^>]*>/\n |
-- /g; # элементы списков |
|
s/<text:list\b[^>]*>/\n\n/g; |
# списки |
|
s/<text:p\b[^>]*>/\n /g; |
# параграфы |
|
s/<[^>]+>//g; |
# удаляем все XML-теги |
|
s/\n{2,}/\n\n/g; |
# удаляем подряд идущие пустые строки |
|
s/\A\n+//; |
# удаляем пустые строки в начале |
|
print "\n", $_, "\n\n"; |
|
|
Сделайте его исполняемым
chmod +x /usr/local/bin/odt-to-txt
Теперь git diff сможет сказать вам, что изменилось в .odt файлах.
Изображения Ещё одна интересная проблема, которую можно решить таким способом, это сравнение файлов изображений. Один из способов сделать это — прогнать PNG-файлы через фильтр, извлекающий их EXIF-информацию — метаданные, которые дописываются в большинство
198