Git для разработчика SS14
Если вам когда-либо доводилось следовать коряво написанному руководству по Git или открывать один из множества невероятно раздутых современных GUI для git вроде GitKraken, вы, вероятно, знаете, что Git может быть действительно запутанным. Цель этого руководства — дать вам ровно ту информацию, которая нужна для правильной разработки под SS14, и предоставить ресурсы для дальнейшего изучения при необходимости.
Вот ещё несколько ресурсов для изучения Git:
- Онлайн-книга Git-SCM
- Руководства по git от Atlassian. Хорошие руководства по некоторым более продвинутым вещам
- Oh shit, Git?!, список решений распространённых проблем с git. Этот пригодится.
- Learn Git Branching. Это интерактивный и очень подробный ресурс, но к его концу вы точно выучите Git. Рекомендуется для пользователей Git среднего уровня.
Вы также всегда можете попросить помощи в официальном discord Wizard’s Den или в discord разработчиков, независимом от форков
1. Настройка самого Git
Ради всего святого, не устанавливайте GitKraken или GitHub Desktop. Я не испытывал ничего, кроме бесконечных мучений, пытаясь помочь людям, использующим любой из них. Я знаю, что GitKraken выглядит солидно, а GH Desktop приятен и прост, но, пожалуйста, не используйте ни то, ни другое, если не знаете, что делаете.
Если вы следовали нашему руководству «Настройка среды разработки», у вас, вероятно, уже установлен Git. Если нет, перейдите на их сайт и установите его сейчас. Это установит бэкенд Git, а также Git Bash (если выберете эту опцию) — один из многих способов, которыми вы можете пользоваться Git.
Если вы на Linux, вы, вероятно, будете использовать Git просто через терминал или выбранную вами IDE, и скорее всего он у вас уже установлен.
Я настоятельно рекомендую хотя бы попробовать Git Bash (как и многие наши разработчики), но есть и более дружелюбные альтернативы, которыми пользуются многие, и я также покажу шаги для них:
- TortoiseGit — старый, но надёжный GUI для Git, который показывает информацию в меню проводника и делает базовые вещи лёгкими
- SmartGit — полнофункциональный GUI для Git, очень настраиваемый и простой в использовании
У меня не будет шагов для них (я рекомендую их уже после того, как изначально написал это руководство), но, попробовав ещё несколько, есть и другие очень-очень хорошие варианты:
- Fork — быстрый и чрезвычайно эргономичный GUI, мой личный фаворит. «Non-free», но это non-free уровня WinRAR, так что по сути бесплатный. Поддерживает частичное индексирование
- Sublime Merge — очень похож на Fork, отлично выглядит и ощущается, и я получил много рекомендаций о нём, хотя сам им почти не пользовался. Также поддерживает частичное индексирование.
В большинстве IDE также есть какая-либо интеграция с Git. Интеграция Git в JetBrains Rider действительно хороша (и я лично рекомендую Rider для всего, что связано с разработкой SS14). Не рекомендую интеграцию Git в Visual Studio, потому что она.. не очень хороша.
Пока вы здесь, установите также Python 3.7+, если у вас его ещё нет. Сделать это можно здесь для Windows и Mac, а если вы на Linux, у вас почти наверняка уже установлен Python. Если нет — разбирайтесь сами, балбес!
При настройке ваших user.name и user.email учтите, что они публично отображаются во всех создаваемых вами коммитах. Если вы хотите сохранить свою информацию в тайне, можете указать в user.name свой никнейм вместо настоящего имени, а в user.email — адрес, предоставленный GitHub, когда включена настройка Keep my email addresses private в настройках электронной почты GitHub.
Теперь, когда Git установлен, рекомендую сначала немного почитать основы и освоиться с тем git-клиентом, с которым вы работаете: будет ли это просто командная строка (Git Bash) или что-то другое.
Мы пройдём через процесс настройки среды Git для Space Station 14, чтобы вы могли вносить код через pull request’ы, создать собственную кодовую базу или просто изучить историю проекта.
1.1 Почему мы вообще используем Git?
Git — это система контроля версий; по сути, простой способ отслеживать изменения в коде и управлять этими изменениями без головной боли. Это бесценный инструмент для разработки ПО, поскольку он легко позволяет вносить новые изменения, просматривать разные изменения, видеть, кто их внёс, и т. д., не координируя и не сводя всё в таблицы вручную.
GitHub — это онлайн-сервис, который размещает Git-репозитории (кодовые базы) для удобной совместной работы. Он идеально подходит для такой кодовой базы, как SS14, с множеством участников и большой историей. Это также означает, что мы открытые (open-source) — любой может зайти на наш GitHub и скачать код!
2. Настройка ваших репозиториев
Как я уже говорил, репозиторий — это просто кодовая база. Репозитории содержат несколько веток, а эти ветки содержат различные коммиты. Возможно, вы слышали об обоих — я поговорю о них подробнее позже.
Удалённый репозиторий — это просто репозиторий, находящийся на GitHub. Локальный репозиторий — тот, что на самом деле на вашем компьютере.
2.1 Создание удалённого репозитория
Сначала создадим собственный удалённый репозиторий-форк Space Station 14. Для этого, конечно, понадобится аккаунт GitHub. «Форк» в таком виде просто означает, что вы копируете всю историю и изменения репозитория в свой удалённый репозиторий, чтобы свободно делать с кодом что угодно.
Ваш удалённый репозиторий не обновляется автоматически с изменениями из оригинального репозитория SS14 — этим придётся заниматься самому, о чём я расскажу позже.
Перейдите к репозиторию Space Station 14 и нажмите здесь:

Оттуда он спросит, куда форкать и как назвать — просто в ваш обычный аккаунт, и назовите как угодно! Впрочем, если вы просто хотите помочь с разработкой, я бы оставил space-station-14.
2.2 Создание локального репозитория
Теперь нам нужно скачать наш удалённый репозиторий на компьютер (клонирование), чтобы мы могли добавить 20 пар клоунских ботинок в каждый шкафчик некоторые изменения. Технически вы можете изменять свой удалённый репозиторий (у GitHub есть неплохие инструменты), но наличие его на компьютере позволяет использовать IDE вроде Visual Studio или Rider для сборки игры и запуска тестов, а также легко управляться с Git.
Для каждого шага будут скриншоты и инструкции для Git Bash, SmartGit и TortoiseGit на Windows.
Перейдите в какое-нибудь место на компьютере, где хотите разместить локальный репозиторий, и:
TortoiseGit
Щёлкните правой кнопкой, чтобы увидеть элементы контекстного меню TortoiseGit:

SmartGit
Откройте SmartGit, перейдите в нужное место, затем:

Git Bash
Щёлкните правой кнопкой:

Затем введём команду для клонирования нашего удалённого репозитория — не репозитория space-wizards/space-station-14.
TortoiseGit

SmartGit

Git Bash

Затем смените каталог с помощью:
cd space-station-14
(Это может отличаться, если вы клонировали другой форк; почти всегда это совпадает с именем репозитория)
Каждая команда Git будет выглядеть примерно так — git, а затем ключевое слово вроде add, commit, pull и т. д.
После завершения у вас появится локальный репозиторий, который теперь можно изменять! Впрочем, предстоит ещё кое-что настроить.
2.3 Проблемы с подмодулями
Обратите на это внимание! Если этого не сделать, при попытке собрать игру вы получите кучу странных ошибок о том, что что-то недоступно.
У Space Station 14 много подмодулей — в первую очередь наш движок RobustToolbox. Подмодули — это просто репозитории внутри репозитория, и их нужно обновлять вручную. Или нет?
У нас есть автоматический обновлятор подмодулей, так что вам не нужно беспокоиться о постоянном запуске git submodule update --init --recursive (команды для ручного обновления подмодулей).
Запустите RUN_THIS.py внутри скачанного репозитория с помощью Python. Желательно тоже из терминала (python RUN_THIS.py или python3 RUN_THIS.py). Это должно занять несколько секунд, так что если оно мгновенно останавливается, вероятно, вы используете не Python 3.7+ или что-то в этом роде.
Если вы на Windows и вас перенаправляет в Microsoft Store или в терминале появляется сообщение о том, что Python не установлен, при попытке выполнить указанную выше команду, вам нужно отключить ярлык Microsoft, который может быть причиной этой проблемы. Сделать это можно, найдя в поиске Windows Manage App Execution Aliases и отключив оба упоминания Python.
Однако если вы хотите напрямую изменять движок или обновлять подмодуль вручную (автообновление иногда может докучать), создайте файл с именем DISABLE_SUBMODULE_AUTOUPDATE в каталоге BuildChecker/.
Если вам когда-либо понадобится вручную обновить RobustToolbox по какой-либо причине, можно использовать cd RobustToolbox; git checkout v0.4.87 (замените v0.4.87 на последний релиз RobustToolbox), затем cd..\, чтобы вернуться в свой репозиторий SS14. Это также пример использования cd для навигации по файлам из уюта командной строки.
3. Настройка удалённых репозиториев
Когда вы клонировали свой удалённый репозиторий, в локальный репозиторий автоматически был добавлен remote. Remotes — это просто именованные URL удалённых репозиториев, которые Git отслеживает, чтобы вы могли скачивать (pull) новые изменения кода или загружать (push) код в свой форк.
В этом случае автоматически добавленный remote называетсяorigin и указывает на https://github.com/[username-here]/space-station-14 (или как вы назвали удалённый репозиторий).
Одна проблема: у нас нигде нет ссылки на оригинальный удалённый репозиторий space-wizards/space-station-14! Как же мы обновим локальный репозиторий без неё? Поэтому убедимся, что мы находимся внутри папки локального репозитория, и добавим новый remote:
TortoiseGit

SmartGit

Git Bash

Всё это лишь добавляет новый remote с именем upstream, указывающий на оригинальный репозиторий space-wizards/space-station-14. Теперь мы можем получать обновления из основного репозитория когда захотим! (как это делать — см. ниже).
По соглашению remote, указывающий на оригинальный репозиторий, называют upstream, но технически можно назвать как угодно. Впрочем, я буду называть его «upstream», и это терминология, которую используют руководства по Git.
Дополнение для разработчиков форков/downstream: Если downstream-репозиторий, в который вы хотите внести вклад, настроен как прямой форк (т. е. GitHub показывает метку «forked from» под именем репозитория), то дополнительно нужно добавить этот форк как remote (но если форк так не настроен, это можно игнорировать). Сделать это можно так же, как вы добавляли upstream в качестве remote (просто используйте ссылку на GitHub форка как URL remote), но обязательно замените имя remote upstream на любое подходящее вам. Ваш собственный форк не обязан быть форком форка downstream; важно лишь, чтобы история коммитов в отдельных ветках, которые вы отправляете в свой remote, совпадала с историей коммитов того места, куда вы намерены отправить PR.
Пожалуйста, обязательно прочитайте Заморозки и ограничения и убедитесь, что ваша идея не попадает под заморозки или что для вашего PR не требуется какое-либо предварительное условие.
4. Ветвление и коммиты
Ветки и коммиты — два из самых важных понятий в Git, и большая часть вашей работы будет вращаться вокруг них.
4.1 Что такое коммит?
Как я упоминал ранее, коммиты — это просто упакованные изменения кода. Как разработчик, вы выбираете, какие изменения попадут в коммит и когда зафиксировать эти изменения. Коммит (действие) означает создание коммита и по сути создаёт точку сохранения, к которой можно вернуться в любой момент.
У коммитов есть автор, отметка времени, сообщение и прикреплённые изменения кода. У них также есть очень длинный «хэш коммита» — уникальный идентификатор, используемый для ссылок на разные коммиты.
Коммиты — так строится история; вы можете просмотреть историю каждого коммита, сделанного в репозиторий SS14 с самого начала, что довольно круто:

(сделано с помощью git log --reverse)
4.2 Что такое ветка?
Ветки очень, очень важны. По сути, это просто список изменений кода (коммитов). Ветка по умолчанию — «master», и все наши серверы используют эту ветку для компиляции кода.
Работая с кодом, вы практически всегда «находитесь на ветке», и можете легко переключаться между ветками.
Обычно ветки называют по тому, над чем вы в них собираетесь работать, но то, как они названы, на самом деле не важно.
Вы можете создавать сколько угодно веток. Когда вы создаёте ветку, она «ответвляется» (серьёзно, да ну?) от текущей ветки, в которой вы находитесь, и становится чем-то независимым, куда можно добавлять коммиты.

На этой диаграмме каждый маленький узел — отдельный коммит, а каждый цвет — отдельная ветка.
Слияние веток
Ветки важны, потому что их можно сливать вместе. Именно так функции интегрируются в основную ветку master. Слияние означает «взять особые коммиты из этой ветки и применить их к другой ветке». Слить можно любые две ветки.
Иногда это проходит не очень хорошо, потому что обе ветки противоречиво изменяют одну и ту же часть файла, и тогда вы получите конфликт слияния — подробнее об этом в дополнениях.
Pull request’ы на GitHub на самом деле являются «запросом на слияние» — вы говорите, что хотите слить коммиты со своей ветки в другую ветку, обычно в их master. Подробнее об этом позже.
Pull request’ы очень хорошо показывают всю эту информацию:

В этом pull request’е Swept начал с создания новой ветки. Поскольку теперь у него была чистая ветка, свободная от помех, он начал работать над функцией и создавал коммиты, чтобы «сохранить прогресс», когда считал это нужным. Эти коммиты добавлялись в ветку последовательно, и видно, как ветка развивалась по мере написания кода. Подробнее о pull request’ах поговорим позже.
Но почемууу?
Ладно, технически да, можно делать всю работу прямо в ветке master и отправлять pull request оттуда. Но создание отдельных веток упрощает понимание того, где вы находитесь и сколько изменений внесли, и позволяет работать над несколькими функциями одновременно.
К тому же мы закроем ваш PR, если он из вашей ветки master (это очень легко может вызвать проблемы), так что не делайте так.
4.3 Создание веток и работа с ними
Создавать ветки довольно просто. Создадим новую ветку с именем funny-feature:
TortoiseGit

SmartGit

Git Bash

Вы можете заметить, что фрагмент в скобках (master) изменился на (funny-feature)! Невероятно!
-b в git checkout здесь означает «переключиться на эту ветку и создать её, если она не существует».
Теперь вы можете свободно работать с этой веткой как угодно, не боясь испортить свою сверхважную ветку master.
Переключаться между ветками довольно просто: это называется переключением на ветку. При этом ваши локальные файлы и папки изменятся в соответствии с веткой, так что Git будет ругаться, если у вас есть локальные изменения и вы попытаетесь выполнить checkout.
Переключение на ветку:
TortoiseGit

SmartGit

Git Bash

Затем вносите какие угодно локальные изменения! Это не имеет значения. Создайте новый файл, удалите всё, измените одну строку в файле и т. д. Это не затронет вашу ветку master, потому что теперь это земля funny-feature!
4.4 Индексирование и фиксация изменений в ветке
Ещё одна важная вещь: прежде чем commit изменения, нужно add их в область индексирования (staging area). Это всего лишь означает, что вы указываете, какие файлы хотите зафиксировать. Это полезно, потому что вы почти никогда не захотите коммитить изменения подмодулей, и избегаете этого, не добавляя их в область индексирования.
Как упоминалось ранее, коммиты всегда сопровождаются сообщением — это короткое описание в повелительном наклонении того, что делается в этом коммите. Или можно быть красавчиком и называть каждый коммит «changes stuff», решать вам.
Если хотите увидеть, что вы сейчас изменили и что находится в области индексирования, это довольно просто:
TortoiseGit

TortoiseGit также показывает изменённые файлы/папки (красный значок в правом нижнем углу) в проводнике Windows, что очень удобно и ради чего я его вообще установил.
SmartGit

Это при условии, что вы установили SmartGit с опцией, при которой главное окно показывает диффы и статус. Если нет, я честно не знаю, где это.
Git Bash

Теперь, когда вы убедились, что все эти изменения выглядят хорошо, добавим их в область индексирования и зафиксируем (некоторые GUI для Git делают это в один шаг)
TortoiseGit

SmartGit

Git Bash

Ура, мы зафиксировали наши изменения в ветке! Теперь, когда они зафиксированы, они навсегда (ну, почти) остаются в истории ветки. Теперь можно многое: слить нашу ветку funny-feature в локальную ветку master (если бы мы зачем-то захотели), загрузить (push) нашу ветку funny-feature в удалённый репозиторий или полностью удалить ветку (среди прочего). Сейчас мы выберем отправку ветки и создание pull request’а.
5. Отправка и создание PR
Pull request — вещь, специфичная для GitHub. Он просто означает, что вы хотите, чтобы кодовая база слила ваши изменения из одной из ваших веток в одну из их веток — обычно в их ветку master. Прежде чем это сделать, наш удалённый репозиторий GitHub (origin) должен узнать о прекрасных ветках и коммитах, созданных локально, поэтому мы загружаем или push эти изменения в удалённый репозиторий.
5.1 Отправка коммитов
Отправить наши изменения теперь, когда мы их зафиксировали, довольно просто. Учтите, что при использовании этих команд Git, вероятно, запросит ваши учётные данные GitHub, чтобы убедиться, что вам разрешено отправлять в этот удалённый репозиторий.
При отправке изменений мы указываем удалённый репозиторий, в который отправляем, и локальную ветку, которую отправляем. Достаточно просто.
Отправка нашей ветки в удалённый репозиторий (origin):
TortoiseGit

Выбор «push all branches» делает то, что заявлено. Может быть полезно.
SmartGit

Git Bash

5.2 Создание pull request’а
А теперь самое интересное. Перейдём на GitHub и создадим pull request для нашей забавной функции.

Добавьте описание, хороший заголовок, несколько скриншотов — и, будем надеяться, его примут.
6. Обновление нашего репозитория
Возможно, прошло некоторое время, неделя или две, с вашего последнего pull request’а, и вы хотели бы сделать ещё один. Прежде чем что-либо делать, нужно скачать (pull) изменения кода из основного репозитория SS14 в свой локальный репозиторий. Иначе код у вас устареет, и локальные изменения могут не соответствовать тому, как игра будет работать на самом деле — вы даже можете получить конфликты слияния при попытке отправить PR.
Есть два способа обновить репозиторий. Оба предполагают, что у вас правильно настроен remote upstream — если нет, вернитесь к более ранней части руководства. И конечно, если вы разрабатываете для downstream, то захотите заменить upstream на то имя, которое дали downstream-репозиторию в шаге 4, чтобы работать с файлами этого downstream, а не upstream. Обязательно всегда проходите процесс обновления при переключении между вкладом в форк и вкладом в upstream, иначе неизбежно либо отправите всю историю downstream в upstream, либо создадите PR’ы в downstream, которые сразу же конфликтуют.
Первый метод, fetch+merge, даёт больше контроля, но может запутать. Второй метод, pull, прост и лёгок, но не даёт особого контроля. Впрочем, обычно достаточно pull.
6.1 Метод fetch + merge
Fetch означает скачивание новых веток и коммитов из удалённого репозитория, но пока без каких-либо действий с ними (локально ничего не изменится). После того как мы скачаем изменения из нашего remote upstream (основного репозитория SS14), мы сольём их в локальную ветку master.
Когда вы выполняете fetch для remote, он скачивает эти ветки в локальный репозиторий и добавляет к ним имя remote и слеш. Так, при fetch upstream создаётся ветка с именем upstream/master. Бонусом можно напрямую переключиться на эту удалённую ветку, если хотите, и даже создать на её основе локальную ветку, что особенно полезно, если вы работаете не только с upstream.
Сначала выполним fetch из нашего remote upstream. Это займёт немного времени.
TortoiseGit

Убедитесь, что выбрали upstream, а не origin!
SmartGit

Кажется, smartgit делает fetch из всех remote при нажатии на это?????
Если нет и он делает fetch только из origin, перейдите в левый нижний угол и сделайте так:

Git Bash

Здесь ничего не произошло, потому что я только что делал fetch, но это займёт некоторое время.
Теперь сольём те изменения, которые только что скачали, в нашу ветку master. Сливать в master не обязательно; можно слить и в другую ветку. Если вы просто хотели «перемотать» (fast-forward) одну из своих веток, чтобы убедиться, что PR актуален, можно вместо этого слить в неё.
Переключитесь на ветку, в которую хотите слить. Затем,
TortoiseGit

SmartGit

Git Bash

Также можно `git merge upstream/master [branch-to-merge-to]
6.2 Метод pull
Pull означает fetch (скачивание) новых веток и коммитов из удалённого репозитория с последующим слиянием их в ветку. Pull часто проще, потому что у Git есть удобная система автоматического определения того, из какого remote вы хотите делать fetch (но она работает чисто не всегда).
Обычно pull проще и заметно легче в выполнении.
Выполним pull из нашего remote upstream (основного репозитория SS14) и скажем ему слить изменения в локальную ветку master.
Сначала переключитесь на ветку master. Мы разбирали это ранее. Затем,
TortoiseGit

SmartGit

Git Bash

Если любой из методов прошёл успешно, вы успешно обновили свою ветку master (или любую другую, которую выбрали)! Делайте это регулярно и всегда перед началом работы над новой веткой.
Дополнения
1. Что стоит иметь в виду
Вы более или менее освоили рабочий процесс разработки функций для SS14 с точки зрения Git, но вот несколько вещей, которые я очень хотел бы вдолбить вам в голову:
- При создании новой функции всегда-всегда-всегда создавайте новую ветку от
masterперед тем, как что-либо коммитить. Если вы случайно закоммитите изменения физики в ветку с велосипедным гудком, вас ждут не самые весёлые времена, но это исправимо (см. Oh Shit, Git?! выше) - Никогда, ни в коем случае не коммитьте RobustToolbox или любые подмодули вроде Lidgren.Network, если не знаете, что делаете. В локальном репозитории верхнего уровня эти подмодули считаются «файлами», так что легко случайно добавить их в индекс и закоммитить. Не делайте этого. О том, как исправить свои косяки, если это произойдёт, см. ниже.
- Если вам нужна дополнительная помощь с Git, не стесняйтесь спрашивать в Discord SS14 в канале #howdoicode.
2. Краткий пример рабочего процесса
Чтобы всё уложилось в голове и в качестве резюме, вот пример рабочего процесса создания нескольких pull request’ов с помощью команд Git Bash.
git checkout master # Прежде чем создавать новую ветку, мы должны быть на master.
git fetch upstream # Скачаем все новые изменения из репозитория SS14..
git merge upstream/master # ..и сольём их в нашу ветку master.
git checkout -b my-new-feature # Создаём новую ветку для функции
...позже локальные изменения...
git add -A # Добавляем все наши локальные изменения в область индексирования
git commit -m "Fix spaghetti explosions" # Фиксируем их
git push origin my-new-feature # и отправляем их в наш remote
# Теперь я хочу поработать над другим pull request'ом.
git checkout master
# Прошло не так много времени, и ничего важного не было слито,
# так что я не буду снова делать fetch и merge изменений--просто новая ветка.
git checkout -b another-feature
...позже локальные изменения...
git add -A
git commit -m "Deletes nuclear operatives"
# Я закоммитил, но потом понял, что коммит был совершенно неправильным
# и займусь этим позже.
git revert HEAD
git checkout master
...неделю спустя...
# Много нового было слито, так что обновим нашу ветку.
git fetch upstream
git merge upstream/master master
git checkout another-feature
git merge master
# Теперь внесём изменения и снова отправим, на этот раз правильно.
...позже локальные изменения...
git add -A
git commit -m "Adds Highlander gamemode"
git push origin another-feature
# Сделал оба PR, оба были приняты, так что мы закончили
git checkout master
git branch -d my-new-feature # Удаляем обе старые ветки
git branch -d another-feature
Глоссарий: внутренние механизмы Git
Просто для справки: вот небольшой глоссарий понятий и терминов Git, объяснённых чуть подробнее, всё в одном месте.
- «Ветки» — самодостаточные версии кодовой базы, в которые можно добавлять коммиты. Ветка по умолчанию — master, но можно создавать сколько угодно.
- «Репозитории» — по сути просто папки, в которых можно использовать Git для внесения изменений и отслеживания сделанных изменений. Локальные репозитории — это репозитории на вашем компьютере, а удалённые репозитории — репозитории, которые живут на сайтах вроде GitHub. Репозитории состоят из множества веток.
- «Remotes» — это имена и ссылки на удалённые репозитории, которые может использовать ваш локальный репозиторий.
- «Подмодули» — репозитории, расположенные внутри другого репозитория.
- «Форки» — репозитории, основанные на другом репозитории. Если вы собираетесь сделать pull request в репозиторий SS14, сначала нужно сделать его форк.
- «Рабочее дерево» — это просто все файлы, папки и прочее, что находится в репозитории.
- «Индексирование» означает добавление (с помощью
git add) изменений из рабочего дерева в «область индексирования», где над ними можно выполнять некоторые действия - «Коммиты» — снимки рабочего дерева репозитория на определённый момент времени. По сути точка сохранения. «Коммит» — это просто список файлов, изменённых с момента последнего коммита, а изменения, которые «закоммичены», — это изменения, которые вы «проиндексировали».
- «Checkout» — действие переключения на другую ветку, чтобы можно было с ней возиться или просмотреть её изменения локально.
- «Слияние» — действие интеграции изменений из одной ветки в другую.
- «Конфликты слияния» возникают, когда интеграцию изменений из одной ветки в другую нельзя выполнить автоматически, потому что обе меняют одну и ту же область в файле или их изменения взаимоисключающи каким-то иным образом.
- «Fetch» означает получение веток и коммитов удалённого репозитория, но без фактических.. действий с ними пока. Они просто будут обновлены на случай, если вы захотите позже переключиться на них или слить их.
- «Pull» — действие интеграции изменений из ветки удалённого репозитория в вашу локальную ветку.
- «Pull request» — действие, специфичное для GitHub, позволяющее запросить слияние вашей локальной ветки и всех её изменений в ветку другого репозитория.
- «Push» — действие интеграции ваших локальных изменений в удалённый репозиторий.
Команд и концепций гораздо больше, но это всё, что вам действительно нужно знать для базовой работы над разработкой.
Приложение A: полезные советы и приёмы
Есть вещи, которые я не рассмотрел, но рано или поздно вам почти неизбежно придётся с ними столкнуться. Я быстро рассмотрю всё это исключительно как git-команды в Git Bash, но разобраться в них в других программах не так уж сложно (те же ключевые слова, просто ищите их). Рекомендую пользоваться их собственными руководствами, потому что я недостаточно хорошо знаю TortoiseGit / SmartGit / GitKraken / Github Desktop, чтобы помочь с более продвинутыми вещами.
Одно замечание, поскольку оно здесь часто всплывает: HEAD — это модное название коммита, на котором вы сейчас находитесь. Не более того. Ветки технически тоже модные названия для коммитов, но вам пока не нужно это знать.
Многие из этих вещей, вероятно, изложены более изящно в Oh Shit, Git?! (см. ресурсы выше)
Разрешение конфликтов слияния
В процессе — я позже напишу по этому поводу руководство получше, потому что это важно
Какой-то противный мейнтейнер сказал вам «разрешить конфликты», иначе ваш PR «не будет принят». Вот козёл! К счастью, это не так уж сложно.
Сначала вы захотите обновить свою локальную master branch. Как это сделать, см. выше.
Когда вы запустите git merge master [local branch], оно либо выполнится чисто (ура-а), либо скажет, что нужно разрешить конфликты (уа-а-а).
Всё, что нужно для ручного разрешения конфликтов, — зайти в конфликтующие файлы, убрать всю эту чепуху >>>>HEAD и ===== <<<<master (она лишь обозначает, откуда пришли изменения) и затем отредактировать файл, чтобы он правильно интегрировал оба набора изменений. Иногда это легко, иногда сложно. Если сложно, вы, вероятно, знаете, что делаете. После этого просто git commit.
У Atlassian есть очень хорошее руководство по этому поводу здесь
Просмотр истории
git log --oneline — ваш друг. Он показывает короткие хэши коммитов (уникальные ID коммитов), их сообщения, а также их ветки и теги.
Избавление от локальных изменений
Возможно, вы случайно внесли нежелательные изменения и не хотите возиться с созданием совершенно новой ветки или чего-то подобного, но ещё не зафиксировали эти изменения.
git reset --hard HEAD
Это означает «привести рабочее дерево к текущему коммиту, отбросив любые локальные изменения. Иначе никак». После этого вернуть локальные изменения не получится, так что будьте осторожны.
Снятие изменений с индекса
Ах чёрт, я только что случайно добавил RobustToolbox в индекс. Не бойтесь!
git reset HEAD [file]
Либо, чтобы снять с индекса всё:
git reset HEAD
Отмена сделанного коммита
О нет, ваша эротика с ксеноморфами попала в коммит / вы случайно закоммитили подмодуль! Что теперь? Есть два решения:
git revert HEAD
Это создаёт новый коммит, отменяющий текущий коммит, и затем фиксирует его. Хе-хе, коммит.
Если вы хотите отменить другой коммит, можно посмотреть его хэш в git log --oneline и затем вызвать git revert [commit hash]. У Git есть более надёжная система для этого; можно сделать git revert HEAD~1, чтобы отменить коммит перед текущим, или git revert HEAD~2, чтобы отменить предшествующий ему. ~1 просто означает «1 коммит до HEAD».
Либо,
git reset --hard HEAD~1
Не рекомендую делать это, если вы не полностью осознаёте, что делаете.
Для случаев, когда вы ОЧЕНЬ не хотите, чтобы кто-либо узнал о той эротике с ксеноморфами, которую вы только что сделали. Этот метод переписывает историю, так что он не лучший для среды совместной работы. Если вы это сделаете, придётся делать force push (git push origin [branch] --force), иначе ничего не выйдет. Force push может быть опасен, так что, повторюсь, убедитесь, что знаете, что делаете.
Локальное переключение на изменения PR
Ладно, этот немного сложнее. Есть пара способов сделать это:
Github CLI
Установите модный CLI от github и сделайте так:
gh pr checkout [pr number]
Круто.
Изменение .git/config
Зайдите в свою папку .git (по умолчанию скрыта — возможно, в Windows потребуется включить показ скрытых папок) и откройте файл «config». Там должен быть фрагмент примерно такого вида:
[remote "upstream"]
url = https://github.com/space-wizards/space-station-14
fetch = +refs/heads/*:refs/remotes/upstream/*
Добавьте к нему строку fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*, чтобы этот раздел теперь выглядел так:
[remote "upstream"]
url = https://github.com/space-wizards/space-station-14
fetch = +refs/heads/*:refs/remotes/upstream/*
fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*
Теперь git fetch upstream. Этот метод отлично подходит, если вы мейнтейнер, но он также.. скачивает все ветки, которые всё ещё открыты, из каждого открытого PR, так что не идеален, если вы хотели всего одну вещь. Отсюда можно сделать git checkout upstream/pr/[pr number], чтобы переключиться на их ветку. Это по сути то же, что делает GitHub CLI, но менее изощрённо.
Добавление нового remote
Этот метод так себе, потому что занимает время, но если вы хотите переключиться на чей-то чужой форк игры и его ветки, он довольно неплох.
На самом деле не так уж сложно, но запутанно, если вы плохо знаете Git. Настройте remote на удалённый репозиторий пользователя, скачайте его ветки, а затем переключитесь на его ветку:
git remote add [username] https://github.com/[username]/space-station-14
git fetch [username]
git checkout [username]/[branch name]
Это также позволяет делать PR’ы в их удалённую ветку, если вам так захочется.