/tg/ Station 13 - Modules - Types

Добро пожаловать в руководство по ручному пакетному зеркалированию репозитория

Это руководство поможет вам забирать Pull Request'ы из TG и собирать их в один PR для последующего мержа сюда, в Nemesis.

ОБРАТИТЕ ВНИМАНИЕ: ВСЁ ЭТО ДОЛЖНО ДЕЛАТЬСЯ НА ФОРКЕ РЕПОЗИТОРИЯ NEMESIS. ЕСЛИ ВЫ КЛОНИРОВАЛИ РЕПОЗИТОРИЙ НАПРЯМУЮ, У ВАС НЕ ПОЛУЧИТСЯ ЭТО ПРОДЕЛАТЬ

Необходимое ПО

Git-Scm — нужен фактически для любых операций с Git. Поставляется с командной строкой, способной делать всё что угодно. Если предпочитаете GUI — берите Fork или связку из командной строки + Github Desktop (см. ниже). С Git идёт довольно простой минималистичный GUI «из коробки», но он здесь не рассматривается.

(Опционально)

Git-Fork — очень хороший GUI-клиент, его мы будем использовать во второй части туториала как более быстрый способ зеркалирования. У него удобный GUI, единственный минус — он платный (разовая покупка), тогда как командная строка бесплатная, просто медленнее.

Github Desktop — приличный GUI-клиент, хотя cherry-pick между разными репозиториями он толком не умеет. Придётся пользоваться им в связке с командной строкой, но с практикой это становится почти таким же быстрым, как Fork — честно говоря. Он очень полезен для визуализации работы с ветками, а также для проверки Pull Request'ов (легко переключаться на их ветки).

С чего начать

Начните с того, что откройте git bash и перейдите в директорию вашего репозитория.

  • (используйте cd name_of_folder для перехода, можно нажимать Tab для автодополнения, чтобы было быстрее). Когда вы окажетесь в нужном месте, это должно выглядеть примерно так: image Моя текущая ветка — Guide, поэтому там написано (Guide).

Оказавшись там, добавьте tgstation как remote, если у вас этого ещё нет на форке. Просто выполните команду:

git remote add tgstation https://github.com/tgstation/tgstation

Это добавит репозиторий TG как remote под именем tgstation. Этот шаг достаточно выполнить один раз.

Дальше нужно сделать fetch, чтобы фактически получить ссылки (refs). Просто выполните команду:

git fetch tgstation

Это просто подтянет актуальный набор refs, составляющих историю репозитория. Сами файлы он не скачает, но обновит историю — так чтобы вы могли делать cherry-pick свежайших коммитов из TG. Эту команду, как правило, нужно запускать перед каждым зеркалированием.

Командная строка

В этом разделе показано, как сделать всё через командную строку — для некоторых это самый быстрый и простой способ. Если вы предпочитаете GUI — переходите к следующему разделу.

Создание и переключение на ветку

Прежде чем что-либо делать дальше, как и при работе с любым PR, важно завести новую ветку! Команда ниже создаст новую ветку manual-mirror-1 и автоматически переключится на неё. Имя совершенно не имеет значения, можете назвать как угодно.

git checkout -b manual-mirror-1

Публикация этой ветки на ваш remote

Раз уж мы здесь — давайте сразу опубликуем ветку, чтобы она появилась и на remote. Сейчас это только локальная ветка, а чтобы открыть pull request, она должна быть на remote. Просто выполните:

git push -u origin HEAD

Поиск хеша коммита

Дальше нужно найти хеш(и) merge-коммита(ов) тех PR, которые вы хотите отзеркалить. Способов несколько, но вот простой, не требующий никакого дополнительного ПО:

В качестве примера используем этот Pull Request.

Прокрутите страницу вниз и найдите merge-коммит. Выглядит примерно так:

Скриншот

Cherry-pick одного коммита

  1. Просто кликните по сокращённой ссылке-хешу (в примере выше это 281dac4), и в адресной строке скопируйте полную версию хеша сразу после /commit/. В этом примере — 281dac4ed0e2976cdecb4777c93a19bc9b787db4.

  2. Чтобы забрать этот единственный коммит, при условии что предыдущие шаги выполнены, достаточно выполнить: git cherry-pick -m 1 281dac4ed0e2976cdecb4777c93a19bc9b787db4

Это для одного коммита. Для диапазона коммитов вам понадобится второй хеш. Повторите шаг 1, чтобы найти второй коммит (см. пример ниже).

Cherry-pick диапазона коммитов

Для примера найдём коммит автоматического changelog'а из того же PR. Очень рекомендуется его забирать — это сохранит имя автора из TG в changelog, вместо того чтобы там оказалось ваше. Если вы переносите больше одного PR за раз, вы обязаны включать Autochangelog'и.

Скриншот

Тут можно кликнуть по словам automatic changelog или по случайному хешу справа — сработает и то и другое. В этом примере хеш changelog'а такой: 66bc14224557ad041d4a146cf1bb079994740787.

Теперь, когда у вас есть и начальный, и конечный хеши, просто выполните следующую команду, чтобы забрать эти коммиты и всё, что между ними:

git cherry-pick A^..B, где A — начало диапазона, в нашем случае:

git cherry-pick -m 1 281dac4ed0e2976cdecb4777c93a19bc9b787db4^..66bc14224557ad041d4a146cf1bb079994740787

ВНИМАНИЕ: первым хешем в команде должен быть более старый коммит, иначе команда просто тихо провалится. Символ ^ тоже важен: без него коммит A сам в диапазон не войдёт. А этого, как правило, вы не хотите.

Отправка изменений на ваш remote

Как только вы это сделали и всё прошло гладко — вы готовы. Чтобы отправить изменения на remote, выполните:

git push

А что если мне не нужны все коммиты из диапазона?

Здесь на помощь приходит git rebase. Допустим, вы забрали диапазон коммитов и хотите выкинуть некоторые из середины. Это могут быть лишние сборки Autochangelog'ов или что-то ещё.

git rebase -i HEAD~10

Запуск этой команды откроет интерактивный rebase-файл со списком коммитов, каждый из которых снабжён префиксом pick. notepad++_xuDB6Uymt4

В любом коммите, который вы хотите выбросить, просто замените pick на drop, затем сохраните и закройте файл. После этого этих коммитов больше не будет!

Дальше — сделайте force push, чтобы обновить ваш remote перед открытием PR:

git push -f

А если возникли merge-конфликты?

Часто всё проходит не гладко, и возникает merge-конфликт. В таких случаях придётся разрешать его вручную.

В сети полно гайдов на эту тему, например, этот, но небольшая подсказка, если вы используете VSC: один из самых простых способов найти конфликты — это просто искать по <<< (маркер merge-конфликта). Исключение — конфликт с отсутствующим файлом или изменённым .dmi, где придётся выбрать, какую версию файла оставить. Если в такой момент вы не знаете как поступить, можно просто взять версию файла из TG и скопировать её сюда.

Открытие pull request'а

Теперь вы готовы открыть свой pull request! Можно зайти на GitHub, открыть свой форк и пройти процесс создания PR через веб-интерфейс, либо использовать приложение GitHub Desktop, в котором есть кнопка, ведущая прямиком к созданию Pull Request. У Fork тоже есть эта возможность — на левой панели, если кликнуть правой кнопкой по ветке master Nemesis.

Если вы включили Autochangelog'и из TG (что настоятельно рекомендуется), пожалуйста, не указывайте changelog в теле PR.

Иначе, если это одиночное зеркалирование — пожалуйста, оставьте ссылку на оригинальный TG-PR в теле pull request. Если это батч — заморачиваться с этим не нужно. Ещё раз: если вы включили коммиты Autochangelog'а — пожалуйста, не пишите changelog отдельно, иначе записи в changelog'е задвоятся.

Руководство по GUI с использованием Git-Fork

Эта часть руководства, по сути, повторяет описанное выше, но с использованием Git-Fork, который облегчает процесс затягивания нескольких PR в один новый Pull Request для Nemesis. Он, по сути, даёт визуализацию списка коммитов по порядку и позволяет выбирать их через shift/ctrl+клик, вместо того чтобы искать хеши коммитов и устраивать rebase'ы. Так быстрее, когда привыкнешь, поэтому это рекомендуемый способ, если вы планируете заниматься этим часто. Но в обязательном порядке он не требуется!

Откройте Git-Fork и через него — директорию с клонированным форком (или клонируйте форк, если он ещё не клонирован).

На левой панели должен быть список всех remote-ов репозитория — кликните по нему правой кнопкой и выберите add new remote. Дайте remote'у любое имя (например, tgstation), а в URL репозитория впишите https://github.com/tgstation/tgstation.

Скриншот Скриншот2

Дальше просто нажмите add new remote.

Теперь сделаем PR, затягивающий изменения из TG. Создайте новую ветку через выпадающее меню Repository в заголовке окна -> New Branch. Или используйте хоткей Ctrl+Shift+B и назовите ветку как угодно.

Отсюда добавлять Pull Request'ы из TG в свой pull request на мерж в Nemesis — проще простого. На боковой панели, где перечислены remote'ы, кликните по кнопке-фильтру с подсказкой show branches from here only. Рекомендуется закрепить ветку master tgstation на левой панели, чтобы можно было удобно нажимать кнопку фильтра (она справа от кнопки закрепления), когда нужно. Сброс фильтра веток — Ctrl+Shift+A, используйте это, чтобы быстро переключаться между коммитами TG и собственными ветками. image

Скриншот

А затем из основного представления, удерживая Ctrl, кликайте по PR и его changelog'у — по каждому Pull Request, который хотите перенести в Nemesis. Кликните по любому из них правой кнопкой, выберите Cherry-pick... и затем в открывшемся диалоге нажмите Cherry Pick n commits.

Скриншот Скриншот2

Дальше можно просто запушить изменения, разрешить конфликты или ошибки и через Fork, GitHub Desktop или сайт GitHub оформить Pull Request в Nemesis.

В вашем downstream-репозитории при мерже Mirror/batch Pull Request, содержащего несколько коммитов, рекомендуется использовать опцию «Create a Merge Commit» (она же «Merge Pull Request») вместо «Squash and Merge» — чтобы сохранить историю коммитов.

418799841-a0ede384-d3d9-462f-a41f-4108734bb894

418800033-39a658d0-d85b-454b-945d-8e77d6b032a9

(Примечание: опцией «Rebase and Merge» тоже можно пользоваться — на ваше усмотрение. Обе сохраняют историю коммитов, у каждой свои плюсы и минусы. Здесь, в Nemesis, мы используем исключительно merge-коммиты.)