Слияние
Начнем с самого распространенного рабочего процесса интеграции изменений: слияния. Перед объединением изменений Ada с Satoshi должен сначала обновить свой локальный указатель на ветку, поскольку в данный момент она устарела. Как только и синхронизируются, Satoshi сможет включить все изменения в свою тематическую ветку.
Процесс слияния:
После всех изменений в Satoshi может продолжить разработку ветки и на заключительном этапе объединить ее с .
Ниже представлен окончательный результат слияния. Как видно, история разработки сохраняет все свои этапы — добавляется только коммит слияния .
Общее
Git — система контроля версий (файлов). Что-то вроде возможности сохраняться в компьютерных играх (в Git эквивалент игрового сохранения — коммит)
Важно: добавление файлов к «сохранению» двухступенчатое: сначала добавляем файл в индекс (), потом «сохраняем» ()
Любой файл в директории существующего репозитория может находиться или не находиться под версионным контролем (отслеживаемые и неотслеживаемые).
Отслеживаемые файлы могут быть в 3-х состояниях: неизменённые, изменённые, проиндексированные (готовые к коммиту).
Ключ к пониманию
Ключ к пониманию концепции git — знание о «трех деревьях»:
- Рабочая директория — файловая система проекта (те файлы, с которыми вы работаете).
- Индекс — список отслеживаемых git-ом файлов и директорий, промежуточное хранилище изменений (редактирование, удаление отслеживаемых файлов).
- Директория — все данные контроля версий этого проекта (вся история разработки: коммиты, ветки, теги и пр.).
Коммит — «сохранение» (хранит набор изменений, сделанный в рабочей директории с момента предыдущего коммита). Коммит неизменен, его нельзя отредактировать.
У всех коммитов (кроме самого первого) есть один или более родительских коммитов, поскольку коммиты хранят изменения от предыдущих состояний.
Простейший цикл работ
- Редактирование, добавление, удаление файлов (собственно, работа).
- Индексация/добавление файлов в индекс (указание для git какие изменения нужно будет закоммитить).
- Коммит (фиксация изменений).
- Возврат к шагу 1 или отход ко сну.
Указатели
- — указатель на текущий коммит или на текущую ветку (то есть, в любом случае, на коммит). Указывает на родителя коммита, который будет создан следующим.
- — указатель на коммит, с которого вы только что переместили (командой , например).
- Ветка (, etc.) — указатель на коммит. При добавлении коммита, указатель ветки перемещается с родительского коммита на новый.
- Теги — простые указатели на коммиты. Не перемещаются.
Перед началом работы нужно выполнить некоторые настройки:
Если вы в Windows:
Длинный вывод в консоли: Vim
Если нужно что-то написать, нажмите i — это переход в режим вставки текста. Если нужно сохранить изменения, перейдите в командный режим и наберите :w.
# Нажатия кнопок ESC — переход в командный режим i — переход в режим редактирования текста ZQ (зажат Shift, поочередное нажатие) — выход без сохранения ZZ (зажат Shift, поочередное нажатие) — сохранить и выйти ```bash # Нажатия кнопок ESC — переход в командный режим i — переход в режим редактирования текста ZQ (зажат Shift, поочередное нажатие) — выход без сохранения ZZ (зажат Shift, поочередное нажатие) — сохранить и выйти # Ввод в командном режиме :q! — выйти без сохранения :wq — сохранить файл и выйти :w filename.txt — сохранить файл как filename.txt
Полезные практики
Это некоторые практики, собранные из моего опыта, статей и других руководств. Если у вас есть предложение (или вы не согласны с некоторым) не стесняйтесь открыть пулреквест и внести свой вклад.
Используйте повелительное наклонение
Но зачем использовать повелительное наклонение?
Сообщение коммита описывает, что конкретно делают зафиксированные изменения, его конечный результат, а не что было сделано.
Примеры:
Начинайте сообщение коммита с заглавной буквы
Смысл этой рекомендации простой: в соответствии с правилами грамматики первое слово предложения начинается с заглавной буквы.
Использование этой практики может варьироваться от человека к человеку, от команды к команде или даже от языка к языку.
Заглавная или нет, важно придерживаться единого стандарта и следовать ему
Старайтесь описывать изменения так, чтобы указывать на исходный код
Это полезно во многих случаях (пр. несколько коммитов, различные изменения и рефакторинг), чтобы помочь проверяющим понять о чём думал автор коммита.
Тема и описание сообщения разделены пустой строкой.
Дополнительные пустые строки считаются частью описания.
Такие символы как , и ` улучшают общую читаемость.
Сохраняйте согласованность языка
Для владельцев проектов: Выберите язык и пишите все сообщения коммитов используя этот язык. В идеале, он должен совпадать с комментариями в коде, стандартным переводом (для переведенных проектов), и т.д.
Для участников проекта: Пишите сообщения коммитов на том языке, который используется в истории коммитов.
Прочие команды и необходимые возможности
Хэш — уникальная идентификация объектов
В git для идентификации любых объектов используется уникальный (то есть с
огромной вероятностью уникальный) хэш из 40 символов, который определяется
хэшируюшей функцией на основе содержимого объекта. Объекты — это все: коммиты,
файлы, тэги, деревья. Поскольку хэш уникален для содержимого, например, файла,
то и сравнивать такие файлы очень легко — достаточно просто сравнить две строки
в сорок символов.
Больше всего нас интересует тот факт, что хэши идентифицируют коммиты. В этом
смысле хэш — продвинутый аналог ревизий Subversion. Несколько примеров
использования хэшей в качестве способа адресации.
Ищет разницу текущего состояния проекта и коммита за номером… сами видите,
каким:
То же самое, но оставляем только шесть первых символов. Git поймет, о каком
коммите идет речь, если не существует другого коммита с таким началом хэша:
Иногда хватает и четырех символов:
Читает лог с коммита по коммит:
Разумеется, человеку пользоваться хэшами не так удобно, как машине, именно
поэтому были введены другие объекты — тэги.
git tag — тэги как способ пометить уникальный коммит
Тэг (tag) — это объект, связанный с коммитом; хранящий ссылку на сам коммит,
имя автора, собственное имя и некоторый комментарий. Кроме того, разработчик
может оставлять на таких тегах собственную цифровую подпись.
Кроме этого в git представленные так называемые «легковесные тэги» (lightweight
tags), состоящие только из имени и ссылки на коммит. Такие тэги, как правило,
используются для упрощения навигации по дереву истории; создать их очень легко.
Создаёт «легковесный» тэг, связанный с последним коммитом; если тэг уже есть,
то еще один создан не будет:
Помечает определенный коммит:
Удаляет тег:
Перечисляет тэги:
Создаёт тэг для последнего коммита, заменяет существующий, если таковой уже был:
После создания тэга его имя можно использовать вместо хэша в любых командах
вроде git diff, git log и так далее:
Обычные тэги имеет смысл использовать для приложения к коммиту какой-либо
информации, вроде номера версии и комментария к нему. Иными словами, если в
комментарии к коммиту пишешь «исправил такой-то баг», то в комментарии к тэгу по
имени «v1.0» будет что-то вроде «стабильная версия, готовая к использованию».
Создаёт обычный тэг для последнего коммита; будет вызван текстовый редактор для
составления комментария:
Создаёт обычный тэг, сразу указав в качестве аргумента комментарий:
Команды перечисления, удаления, перезаписи для обычных тэгов не отличаются от
команд для «легковесных» тэгов.
Относительная адресация
Вместо ревизий и тэгов в качестве имени коммита можно опираться на еще один
механизм — относительную адресацию. Например, можно обратиться прямо к предку
последнего коммита ветки master:
Если после «птички» поставить цифру, то можно адресоваться по нескольким предкам
коммитов слияния:
Ищет изменения по сравнению со вторым предком последнего коммита в master; HEAD
здесь — указатель на последний коммит активной ветки.
Аналогично, тильдой можно просто указывать, насколько глубоко в историю ветки
нужно погрузиться.
Что привнес «дедушка» нынешнего коммита:
То же самое:
Обозначения можно объединять, чтобы добраться до нужного коммита:
Файл .gitignore — объясняем git, какие файлы следует игнорировать
Иногда по директориям проекта встречаются файлы, которые не хочется постоянно
видеть в сводке git status. Например, вспомогательные файлы текстовых редакторов,
временные файлы и прочий мусор.
Заставить git status игнорировать определенные файлы можно, создав в корне или
глубже по дереву (если ограничения должны быть только в определенных директория)
файл .gitignore. В этих файлах можно описывать шаблоны игнорируемых файлов
определенного формата.
Пример содержимого такого файла:
Существуют и другие способы указания игнорируемых файлов, о которых можно узнать
из справки git help gitignore.
Серверные команды репозитория
Команда создания вспомогательных файлов для dumb-сервера в $GIT_DIR/info и
$GIT_OBJECT_DIRECTORY/info каталогах, чтобы помочь клиентам узнать, какие ссылки
и пакеты есть на сервере:
Проверяет сколько объектов будет потеряно и объём освобождаемого места при
перепаковке репозитория:
Переупаковывает локальный репозиторий:
FAQ
Как я должен писать сообщения коммитов на начальной стадии разработки?
Мы рекомендуем писать сообщения коммитов так, как будто вы уже выпустили продукт. Как правило, кто-то, например,
ваши коллеги, уже используют ваш код. И они хотят знать, что исправилось, что изменилось, какие нарушения обратной
совместимости появились и т.д.
Что мне делать, если коммит должен содержать больше одного типа?
Вернитесь назад и сделайте несколько коммитов, если это возможно. Часть из преимуществ использования Общепринятых Коммитов
это его способность побуждать делать более организованные коммиты и PR’ы.
Разве это не препятствует быстрому развитию и быстрой интеграции?
Это препятствует быстрому развитию в неорганизованном виде. Это помогает быстро двигаться в нескольких проектах
с несколькими участниками.
Как она связывается с правилами семантического управления версиями SemVer?
тип коммита должен быть отражен в -релизе. тип коммита должен быть отражен в -релизе.
Коммиты с в теле или подвале, не зависимо от типа, должны быть отражены в -релизе.
Что мне делать, если я случайно использовал не тот тип коммита?
Что если вы использовали тип, который имеет спецификацию, но это неправильный тип. Например, вместо
Когда вы использовали тип, не описанный спецификацией, например, вместо
Это не конец света, это просто обозначает, что коммит будет упущен при работе утилит, основанных на спецификации.
Нет! Если ваш рабочий процесс основа на использовании слияния (squash) Git, сопровождающий проекта может отчистить
историю всех предыдущих коммитов при их слияния, не добавляя рабочей нагрузки на случайные коммиты. Обычно,
рабочий процесс строится на том, что ваша система Git автоматически объединяет (squash) все предыдущие коммиты пред
перед pull-запросом и предоставляет форму сопровождающему проекта для ввода нового коммита.
Как использовать команду Git Merge?
Чтобы объединить изменения, полученные в предыдущем разделе, выполните следующую команду:
git merge
Если вы видите такой же результат, значит, вы успешно объединили изменения в своем локальном репозитории. На приведенном выше изображении третья строка показывает написанное Fast-forward (перемотка вперед). Это происходит потому, что это fast-forward merge (быстрое слияние), выполняемое git. Давайте посмотрим, что это такое.
Fast-Forward Merge
Fast-Forward Merge (быстрое слияние) в Git означает, что существует линейный путь от ветви, который отклоняется от ветви, к которой вы сливаетесь. Линейный путь означает, что не было никаких коммитов к главной ветви с тех пор, как ветвь объекта перешла в точку слияния.
На приведенном выше рисунке показано, что ветвь была отклонена, сделала три коммита, и за это время в главной ветви не было коммитов (зеленые точки). После трех коммитов я объединю ветвь функции в главную ветвь, что приведет к быстрой перемотке вперед.
FAQ
Как я должен писать сообщения commit’ов на начальной стадии разработки?
Мы рекомендуем писать сообщения commit’ов так, как будто вы уже выпустили продукт. Как правило, кто-то, например,
ваши коллеги, уже используют ваш код. И они хотят знать, что исправилось, что изменилось, какие нарушения обратной
совместимости появились и т.д.
Что мне делать, если commit должен содержать больше одного типа?
Вернитесь назад и сделайте несколько commit’ов, если это возможно. Часть из преимуществ использования Conventional Commits — это его способность побуждать делать более организованные коммиты и PR’ы.
Разве это не препятствует быстрому развитию и быстрой интеграции?
Это препятствует быстрому развитию в неорганизованном виде. Это помогает быстро двигаться в нескольких проектах
с несколькими участниками.
Как это связано с правилами семантического управления версиями SemVer?
тип commit’а должен быть отражен в -релизе. тип commit’а должен быть отражен в -релизе.
Commit’ы с в теле или подвале, независимо от типа, должны быть отражены в -релизе.
Как я должен версионировать мои расширения к спецификации Conventional Commits, например, ?
Мы рекомендуем использовать SemVer для релизов ваших расширений к этой спецификации (и рекомендуем делать эти расширения!).
Что мне делать, если я случайно использовал не тот тип commit’а?
Что если вы использовали тип, который имеет спецификацию, но это неправильный тип. Например, вместо
Когда вы использовали тип, не описанный спецификацией, например, вместо
Это не конец света, это просто обозначает, что коммит будет упущен при работе утилит, основанных на спецификации.
Нет! Если ваш рабочий процесс основан на использовании слияния (squash) Git, сопровождающий проекта может очистить
историю всех предыдущих commit’ов при их слиянии, не добавляя рабочей нагрузки на случайные commit’ы. Обычно,
рабочий процесс строится на том, что ваша система Git автоматически объединяет (squash) все предыдущие commit’ы
перед pull-запросом и предоставляет форму сопровождающему проекта для ввода нового commit’а.
Главное
Как разработчики приложений с открытым исходным кодом, использующие слияние (squash) git’а в ветку должны писать
общепринятые сообщения коммитов.
Сообщения коммитов должны иметь следующую структуру:
Коммиты включают следующие элементы, чтоб сообщить пользователям вашей библиотеки, что ни в себе содержат:
fix: — коммит типа , который исправляет баги в вашем коде (он соотносится с
в правилах семантического управления версиями).
feat: — коммит type , который добавляет новую функциональность в ваш код (он соотносится с
в правилах семантического управления версиями).
BREAKING CHANGE: — коммит, который содержит текст в начале своего необязательного тела или подвала,
и несет в себе описание нарушений обратной совместимости в API (он соотносится с
в правилах семантического управления версиями).
BREAKING CHANGE может быть частью коммита любого типа.
Другие: коммиты, отличные от и так же разрешены, например,
commitlint-config-conventional
(основанный на )
рекомендует , , , , , и другие.
Мы так же рекомендуем для коммитов, которые улучшают текущую реализацию без добавления новой функциональности
или исправления ошибок
Обратите внимание, что данный тип коммитов не управляется данной спецификацией и не
имеет никакого соотношения в правилах семантического управления версиями (за исключением случае, если он не содержит в
себе BREAKING CHANGE).
Область (scope) может быть определена для любого типа коммита, чтоб описать контекст коммита. Она содержится в круглых
скобках, например, .
Вступление
В разработке программного обеспечения я заметил, что ошибки чаще всего распространяются между приложениями.
Модульное тестирование отлично подходит для тестирования взаимодействий, о которых знает разработчик с открытым исходным
кодом, но не затрагивает интересов тех, то использует вашу библиотеку.
Любой, кто обновился до новой версии патча зависимостей, только для того, чтобы увидеть, как его приложение начинает
вываливаться с 500 ошибкой, знает, насколько важна хорошая читаемая история изменений приложения
(и в идеале хорошо сохранившийся CHANGELOG).
Общепринятые Коммиты — это простое соглашение для написания сообщений коммитов. Оно определяет простой
набор правил для создания точной истории коммитов, а так же упрощает написание автоматических утилит поверх истории коммитов.
Данное соглашение совместимо с правилами семантического управления версиями SemVer, описывая
правила добавления новой функциональности, исправления багов и описания нарушения обратной совместимости в сообщениях коммитов.
Внедряя это соглашение, мы создаем общий язык, который упрощает отладку между проектами.
Общее
Git — система контроля версий (файлов). Что-то вроде возможности сохраняться в компьютерных играх (в Git эквивалент игрового сохранения — коммит)
Важно: добавление файлов к «сохранению» двухступенчатое: сначала добавляем файл в индекс (), потом «сохраняем» ()
Любой файл в директории существующего репозитория может находиться или не находиться под версионным контролем (отслеживаемые и неотслеживаемые).
Отслеживаемые файлы могут быть в 3-х состояниях: неизменённые, изменённые, проиндексированные (готовые к коммиту).
Ключ к пониманию
Ключ к пониманию концепции git — знание о «трех деревьях»:
- Рабочая директория — файловая система проекта (те файлы, с которыми вы работаете).
- Индекс — список отслеживаемых git-ом файлов и директорий, промежуточное хранилище изменений (редактирование, удаление отслеживаемых файлов).
- Директория — все данные контроля версий этого проекта (вся история разработки: коммиты, ветки, теги и пр.).
Коммит — «сохранение» (хранит набор изменений, сделанный в рабочей директории с момента предыдущего коммита). Коммит неизменен, его нельзя отредактировать.
У всех коммитов (кроме самого первого) есть один или более родительских коммитов, поскольку коммиты хранят изменения от предыдущих состояний.
Простейший цикл работ
- Редактирование, добавление, удаление файлов (собственно, работа).
- Индексация/добавление файлов в индекс (указание для git какие изменения нужно будет закоммитить).
- Коммит (фиксация изменений).
- Возврат к шагу 1 или отход ко сну.
Указатели
- — указатель на текущий коммит или на текущую ветку (то есть, в любом случае, на коммит). Указывает на родителя коммита, который будет создан следующим.
- — указатель на коммит, с которого вы только что переместили (командой , например).
- Ветка (, etc.) — указатель на коммит. При добавлении коммита, указатель ветки перемещается с родительского коммита на новый.
- Теги — простые указатели на коммиты. Не перемещаются.
Перед началом работы нужно выполнить некоторые настройки:
Если вы в Windows:
Длинный вывод в консоли: Vim
Если нужно что-то написать, нажмите i — это переход в режим вставки текста. Если нужно сохранить изменения, перейдите в командный режим и наберите :w.
# Нажатия кнопок ESC — переход в командный режим i — переход в режим редактирования текста ZQ (зажат Shift, поочередное нажатие) — выход без сохранения ZZ (зажат Shift, поочередное нажатие) — сохранить и выйти ```bash # Нажатия кнопок ESC — переход в командный режим i — переход в режим редактирования текста ZQ (зажат Shift, поочередное нажатие) — выход без сохранения ZZ (зажат Shift, поочередное нажатие) — сохранить и выйти # Ввод в командном режиме :q! — выйти без сохранения :wq — сохранить файл и выйти :w filename.txt — сохранить файл как filename.txt
Ограничение вывода
В дополнение к опциям форматирования вывода, команда принимает несколько опций для ограничения вывода – опций, с помощью которых можно увидеть определенное подмножество коммитов. Вы уже видели одну из таких опций – это опция , которая показывает только последние два коммита. В действительности вы можете использовать , где n – это любое натуральное число, представляющее собой n последних коммитов. На практике вы не будете часто использовать эту опцию, потому что Git по умолчанию использует постраничный вывод и вы будете видеть только одну страницу за раз.
Однако, опции для ограничения вывода по времени, такие как и , очень удобны. Например, следующая команда покажет список коммитов, сделанных за последние две недели:
Это команда работает с большим количеством форматов – вы можете указать определенную дату вида 2008-01-15 или же относительную дату, например 2 years 1 day 3 minutes ago.
Также вы можете фильтровать список коммитов по заданным параметрам. Опция дает возможность фильтровать по автору коммита, а опция искать по ключевым словам в сообщении коммита.
Примечание
Допускается указывать несколько параметров и для поиска, которые позволят найти коммиты, соответствующие любому указанному и любому указанному шаблону ; однако, применение опции заставит искать коммиты соответствующие всем указанным шаблонам .
Следующим действительно полезным фильтром является опция , которая принимает аргумент в виде строки и показывает только те коммиты, в которых изменение в коде повлекло за собой добавление или удаление этой строки. Например, если вы хотите найти последний коммит, который добавил или удалил вызов определенной функции, вы можете запустить команду:
Последней полезной опцией, которую принимает команда как фильтр, является путь. Если вы укажете каталог или имя файла, вы ограничите вывод только теми коммитами, в которых были изменения этих файлов. Эта опция всегда указывается последней после двойного тире (—), чтобы отделить пути от опций:
В таблице 3 вы можете увидеть эти и другие распространенные опции.
Опция | Описание |
---|---|
Показывает только последние n коммитов. | |
, | Показывает только те коммиты, которые были сделаны после указанной даты. |
, | Показывает только те коммиты, которые были сделаны до указанной даты. |
Показывает только те коммиты, в которых запись автор совпадает с указанной строкой. | |
Показывает только те коммиты, в которых запись коммитер совпадает с указанной строкой. | |
Показывает только коммиты, сообщение которых содержит указанную строку. | |
Показывает только коммиты, в которых изменение в коде повлекло за собой добавление или удаление указанной строки. |
Например, если вы хотите увидеть, в каких коммитах произошли изменения в тестовых файлах в исходном коде Git в октябре 2008 года, автором которых был Junio Hamano, и которые не были коммитами слияния, вы можете запустить следующую команду:
Из почти 40 000 коммитов в истории исходного кода Git, эта команда показывает только 6, которые соответствуют этим критериям.
Подсказка
Предотвращение отображения коммитов слияния
В зависимости от используемого порядка работы, история коммитов в вашем репозитории может содержать большое количество коммитов слияния, которые сами по себе не очень информативны. Чтобы исключить их из вывода команды используйте опцию .