- The Git-SCM online book
- Atlassian’s git guides. Хорошие руководства по более продвинутым вещам
- Oh shit, Git?!, список решений распространённых проблем с Git. Этот пригодится.
- Learn Git Branching. Интерактивный и очень глубокий, но вы выучите Git к его концу. Рекомендуется для пользователей Git среднего уровня.
1. Установка Git
- TortoiseGit — старая, но надёжная Git GUI, которая показывает информацию в меню проводника и делает базовые вещи лёгкими
- SmartGit — полнофункциональная Git GUI, очень настраиваемая и простая в использовании
- Fork — быстрая и чрезвычайно эргономичная GUI, мой личный фаворит. «Non-free», но на уровне WinRAR, так что практически бесплатно. Поддерживает частичное staging.
- Sublime Merge — очень похож на Fork, выглядит и ощущается отлично, я получил много рекомендаций, хотя сам не много использовал. Также поддерживает частичное staging.
Python 3.7+, если у вас его ещё нет. Вы можете сделать это здесь для Windows и Mac, а если вы на Linux, Python почти наверняка уже установлен. Если нет, разбирайтесь сами, балбес!
user.name и user.email знайте, что они публично отображаются во всех создаваемых вами коммитах. Если вы хотите сохранить свою информацию в тайне, вы можете установить user.name как ваше имя пользователя вместо реального имени, а user.email — как тот, который предоставляет GitHub, когда опция Keep my email addresses private включена в Настройках Email GitHub.1.1 Зачем мы вообще используем Git?
Git — это система контроля версий — по сути, это простой способ отслеживать изменения в коде и управлять ими без головной боли. Это бесценный инструмент для разработки ПО, поскольку он позволяет легко вносить новые изменения, просматривать различные изменения, видеть, кто внёс изменения и т.д., без необходимости координировать и табулировать всё самостоятельно. GitHub — это онлайн-сервис, который размещает Git репозитории (кодовые базы) для удобной совместной работы. Он идеально подходит для такой кодовой базы, как SS14, с большим количеством контрибьюторов и обширной историей. Это также означает, что мы открыты — любой может перейти на наш GitHub и скачать код!2. Настройка ваших репозиториев
Как я уже говорил, репозиторий — это просто кодовая база. Репозитории содержат несколько веток, а эти ветки содержат разные коммиты. Вы могли слышать об обоих — я расскажу о них подробнее позже. Удалённый репозиторий — это репозиторий на GitHub. Локальный репозиторий — это тот, который находится на вашем компьютере.2.1 Создание удалённого репозитория
Сначала давайте создадим наш собственный удалённый репозиторий (форк) Space Station 14. Для этого, конечно, понадобится учётная запись GitHub. «Форкинг» означает, что вы копируете всю историю и изменения репозитория в свой собственный удалённый репозиторий, чтобы вы могли свободно работать с кодом. Ваш удалённый репозиторий не обновляется автоматически изменениями из оригинального SS14 — вам нужно будет делать это самостоятельно, о чём я расскажу позже. Перейдите в репозиторий Space Station 14 и нажмите здесь:
space-station-14, если вы просто хотите помогать с разработкой.
2.2 Создание локального репозитория
Теперь нам нужно загрузить наш удалённый репозиторий на компьютер (клонирование), чтобы мы могли добавитьTortoiseGit
TortoiseGit
Щёлкните правой кнопкой мыши, чтобы увидеть контекстное меню TortoiseGit:
SmartGit
SmartGit
Откройте SmartGit и перейдите в нужное место, затем:
Git Bash
Git Bash
Щёлкните правой кнопкой мыши:
Затем мы введём команду для клонирования нашего удалённого репозитория, а не
space-wizards-federation/space-station-14.
TortoiseGit
TortoiseGit


SmartGit
SmartGit

Git Bash
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, который может вызывать эту проблему. Это можно сделать, найдя Manage App Execution Aliases в поиске Windows и отключив два упоминания Python.
Если вы хотите напрямую изменять движок или обновлять субмодуль вручную (автообновление иногда может быть проблемой), создайте файл с именем DISABLE_SUBMODULE_AUTOUPDATE внутри директории BuildChecker/.
Если вам когда-либо понадобится обновить RobustToolbox вручную, вы можете использовать cd RobustToolbox; git checkout v0.4.87 (замените v0.4.87 на последний релиз RobustToolbox), затем используйте cd..\ для возврата в ваш SS14 репозиторий. Это также пример использования cd для навигации по файлам из командной строки.
3. Настройка удалённых репозиториев (remotes)
Когда вы клонировали свой удалённый репозиторий, remote был автоматически добавлен в ваш локальный репозиторий. Remotes — это просто именованные URL-адреса удалённых репозиториев, которые Git отслеживает, чтобы вы могли загружать (pull) новые изменения в код или отправлять (push) код в ваш форкнутый репозиторий. В данном случае автоматически добавленный remote называетсяorigin и указывает на https://github.com/[имя-пользователя]/space-station-14 (или как вы назвали удалённый репозиторий).
Одна проблема: у нас нет ссылки на оригинальный space-wizards-federation/space-station-14 remote! Как мы будем обновлять наш локальный репозиторий без него? Итак, убедитесь, что мы находимся внутри папки локального репозитория, и добавим новый remote:
TortoiseGit
TortoiseGit


SmartGit
SmartGit


Git Bash
Git Bash

Всё это делает — добавляет новый remote с именем
upstream, указывающий на оригинальный репозиторий space-wizards-federation/space-station-14. Теперь мы можем получать обновления из основного репозитория, когда захотим! (см. ниже, как это сделать).
Принято называть remote, указывающий на оригинальный репозиторий, upstream, но технически вы можете назвать его как угодно. Я буду называть его «upstream», и эта терминология также используется в руководствах по Git.
Дополнение для разработчиков форков/даунстримов: Если даунстрим-репозиторий, в который вы хотите внести вклад, настроен как прямой форк (т.е. GitHub показывает метку «forked from» под именем репозитория), вам также нужно добавить этот форк как remote (но если форк не настроен так, вы можете это игнорировать). Вы можете сделать это аналогично тому, как вы добавили upstream как remote (просто используйте ссылку на GitHub форка в качестве URL remote), но обязательно замените имя remote upstream на любое имя, которое вы считаете подходящим. Ваш собственный форк не обязательно должен быть форком даунстрима; важно только, чтобы история коммитов в отдельных ветках, которые вы пушите в свой remote, совпадала с историей того места, куда вы собираетесь отправить PR.
4. Branching & Commits
Ветки и коммиты — два самых важных понятия в Git, и большая часть вашей работы будет вращаться вокруг них.4.1 Что такое коммит?
Как я упоминал ранее, коммиты — это просто упакованные изменения кода. Как разработчик, вы выбираете, какие изменения попадают в коммит и когда их коммитить. Коммитинг означает создание коммита, и по сути это создание точки сохранения, к которой вы можете вернуться в любое время. Коммиты имеют автора, временную метку, сообщение и некоторые изменения кода. У них также есть очень длинный «commit hash» — уникальный идентификатор, используемый для ссылки на различные коммиты. Коммиты — это то, как строится история; вы можете просмотреть историю каждого отдельного коммита, сделанного в репозитории SS14 с самого начала:
git log --reverse)
4.2 Что такое ветка?
Ветки очень важны. По сути, это просто список изменений кода (коммитов). Ветка по умолчанию — ‘master’, и все наши серверы используют её для компиляции кода. Вы почти всегда «находитесь на ветке», когда работаете с кодом, и вы можете легко переключаться между ветками. Обычно ветки называются в честь того, над чем вы собираетесь в них работать, но на самом деле не важно, как они называются. Вы можете создавать столько веток, сколько захотите. Когда вы создаёте ветку, она «ответвляется» от текущей ветки и становится независимой сущностью, в которую вы можете добавлять коммиты.
Слияние веток
Ветки важны, потому что их можно сливать вместе. Так функции интегрируются в основную веткуmaster. Слияние означает «взять специальные коммиты из этой ветки и применить их к другой ветке». Вы можете слить любые две ветки вместе.
Иногда это проходит негладко, потому что обе ветки изменяют одну и ту же часть файла противоречивым образом; в этом случае вы получите конфликт слияния — об этом подробнее в дополнениях.
Pull request на GitHub — это, по сути, «запрос на слияние» — вы говорите, что хотите слить коммиты вашей ветки в другую ветку, обычно в их master. Подробнее об этом позже.
Pull request очень хорошо показывают всю эту информацию:


Но зачем?
Хорошо, технически вы можете делать всю работу в веткеmaster и делать pull request оттуда. Однако создание отдельных веток упрощает понимание того, где вы находитесь, сколько изменений вы сделали, и позволяет работать над несколькими функциями одновременно.
Также мы закроем ваш PR, если он сделан из вашей ветки master (это может легко вызвать проблемы), так что не делайте этого.
4.3 Создание и работа с ветками
Создавать ветки довольно легко. Давайте создадим новую ветку с именемfunny-feature:
TortoiseGit
TortoiseGit


SmartGit
SmartGit


Git Bash
Git Bash

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

SmartGit
SmartGit

Git Bash
Git Bash

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

SmartGit
SmartGit

Git Bash
Git Bash

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


SmartGit
SmartGit


Git Bash
Git Bash

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


SmartGit
SmartGit


Git Bash
Git Bash

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


upstream, а не origin!
SmartGit
SmartGit


Git Bash
Git Bash

Теперь мы сольём эти загруженные изменения в нашу ветку
master. Вам не обязательно сливать в master; вы можете слить в другую ветку. Если вы просто хотите быстро обновить одну из ваших веток, чтобы ваш PR был актуален, вы можете слить в эту ветку.
Переключитесь на ветку, в которую хотите слить изменения. Затем,
TortoiseGit
TortoiseGit


SmartGit
SmartGit


Git Bash
Git Bash

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


SmartGit
SmartGit



Git Bash
Git Bash

Если любой из методов прошёл успешно, вы успешно обновили вашу ветку master (или любую другую ветку, которую вы выбрали для обновления)! Делайте это регулярно и всегда перед началом работы над новой веткой.
Дополнения
1. Вещи, которые нужно иметь в виду
Вы более или менее изучили рабочий процесс для разработки функций для SS14 с точки зрения Git, но вот некоторые вещи, которые я хотел бы вдолбить вам в голову:- При создании новой функции всегда всегда всегда создавайте новую ветку от
masterперед коммитом чего-либо. Если вы случайно закоммитите свои изменения физики в ветку для bike horn, вас ждёт невесёлое время, но это исправимо (см. Oh Shit, Git?! выше). - Никогда не коммитьте RobustToolbox или любые субмодули, такие как Lidgren.Network, если вы не знаете, что делаете. В локальном репозитории верхнего уровня эти субмодули считаются «файлами», поэтому их легко случайно застейджить и закоммитить. Не делайте этого. См. ниже, как исправить свои косяки, если это произойдёт.
- Если вам нужна дополнительная помощь с Git, не стесняйтесь спрашивать в Discord SS14 в #howdoicode.
2. Быстрый пример рабочего процесса
Чтобы всё уложилось в голове и резюмировать всё, вот пример рабочего процесса для создания нескольких pull request с использованием команд Git Bash.Словарь: Внутреннее устройство Git
Для справки, вот небольшой словарь концепций и терминов Git, объяснённых немного подробнее, все в одном месте.- ‘Branches’ — это самодостаточные версии кодовой базы, в которые вы можете добавлять коммиты. Ветка по умолчанию — master, но вы можете создавать сколько угодно.
- ‘Repositories’ — это, по сути, просто папки, где вы можете использовать Git для внесения изменений и отслеживания сделанных изменений. Локальные репозитории — это репозитории на вашем компьютере, а удалённые репозитории — это репозитории, которые живут на сайтах, таких как GitHub. Репозитории состоят из множества веток.
- ‘Remotes’ — это имена и ссылки на удалённые репозитории, которые может использовать ваш локальный репозиторий.
- ‘Submodules’ — это репозитории, которые находятся внутри другого репозитория.
- ‘Forks’ — это репозитории, основанные на другом репозитории. Если вы собираетесь сделать pull request в репозиторий SS14, вам нужно сначала сделать форк.
- ‘The working tree’ — это просто каждый файл, папка и т.д., которые находятся в репозитории.
- ‘Staging’ означает добавление (с помощью
git add) изменений из вашего working tree в ‘staging area’, где с ними можно выполнять некоторые действия. - ‘Commits’ — это снимки working tree репозитория в определённый момент времени. По сути, точка сохранения. ‘Commit’ — это просто список файлов, которые были изменены с последнего коммита, и изменения, которые были ‘закоммичены’, — это изменения, которые вы ‘застейджили’.
- ‘Checking out’ — это акт переключения на другую ветку, чтобы вы могли с ней работать или просматривать её изменения локально.
- ‘Merging’ — это акт интеграции изменений из одной ветки в другую ветку.
- ‘Merge conflicts’ возникают, когда интеграция изменений из одной ветки в другую не может быть выполнена автоматически, потому что обе изменяют одну и ту же область в файле, или их изменения взаимно исключают друг друга.
- ‘Fetching’ означает получение веток и коммитов удалённого репозитория, но без фактического выполнения с ними каких-либо действий. Они просто обновляются на случай, если вы захотите сделать checkout или слить их позже.
- ‘Pulling’ — это акт интеграции изменений из ветки удалённого репозитория в вашу локальную ветку.
- ‘Pull requests’ — это специфическое для GitHub действие, которое позволяет вам запросить слияние вашей локальной ветки со всеми её изменениями в ветку другого репозитория.
- ‘Pushing’ — это акт интеграции ваших локальных изменений в удалённый репозиторий.
Приложение A: Полезные советы и трюки
Есть некоторые вещи, которые я не осветил, но с которыми вы почти неизбежно столкнётесь. Я опишу их все исключительно как команды Git в Git Bash, но их не слишком сложно понять в других программах (те же ключевые слова, просто ищите их). Я рекомендую использовать их конкретные руководства, потому что я не знаю TortoiseGit / SmartGit / GitKraken / Github Desktop достаточно хорошо, чтобы помочь вам с более продвинутыми вещами. Одно замечание, поскольку это часто всплывает:HEAD — это просто имя для коммита, на котором вы сейчас находитесь. Не более того. Ветки также технически являются «именами» для коммитов, но вам пока не нужно этого знать.
Многие из этих вещей можно найти, вероятно, более красноречиво в Oh Shit, Git?! (см. ресурсы выше).
Разрешение конфликтов слияния
WIP я напишу лучшее руководство для этого позже, потому что это важно Какой-то надоедливый maintainer сказал вам ‘resolve conflicts’, иначе ваш PR ‘не будет принят’. Какой мудак! К счастью, это не слишком сложно. Сначала вам нужно обновить вашу локальнуюmaster branch. См. выше, как это сделать.
Когда вы запускаете git merge master [local branch], он либо сделает это чисто (woohoo), либо скажет, что нужно разрешить конфликты (wahhhh).
Всё, что вам нужно сделать для разрешения конфликтов вручную, — это зайти в конфликтующие файлы, удалить весь мусор >>>>HEAD и ===== <<<<master (просто обозначает, откуда пришли изменения), а затем отредактировать файл так, чтобы он правильно интегрировал оба набора изменений. Иногда это просто, иногда сложно. Если сложно, вы, вероятно, знаете, что делаете. После этого просто git commit.
У Atlassian есть очень хорошее руководство по этому поводу здесь
Просмотр истории
git log --oneline — ваш друг. Он показывает короткие хеши коммитов (уникальные ID для коммитов), их сообщения, а также их ветки и теги.
Избавление от локальных изменений
Возможно, вы случайно сделали изменения, которые не хотели, и не хотите возиться с созданием новой ветки или чего-то ещё — но вы ещё не закоммитили эти изменения.Отмена staging изменений
Ах, чёрт, я случайно застейджил RobustToolbox. Не бойся!Откат сделанного коммита
Ой, ваша ксено-эротика попала в коммит/вы случайно закоммитили субмодуль! Что теперь? Ну, есть два решения:git log --oneline и затем вызвать git revert [хеш коммита]. У Git есть более надёжная система для этого; вы можете сделать git revert HEAD~1, чтобы отменить коммит перед текущим, или git revert HEAD~2, чтобы отменить тот, что перед этим. ~1 просто означает ‘на 1 коммит раньше HEAD’.
Или,
git push origin [branch] --force), иначе это не сработает. Force push может быть опасным, так что опять же, убедитесь, что вы знаете, что делаете.
Checkout изменений PR локально
Это немного сложно. Есть несколько способов сделать это:Github CLI
Установите CLI от GitHub и сделайте так:Изменение .git/config
Зайдите в вашу папку .git (скрыта по умолчанию — может потребоваться включить отображение скрытых папок в Windows) и откройте файл ‘config’. Там должно быть что-то вроде:fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*, так что секция теперь выглядит так:
git fetch upstream. Этот метод отлично подходит, если вы maintainer, но он также загружает каждую открытую ветку из каждого PR, так что не идеально, если вы хотели только одну вещь. Отсюда вы можете git checkout upstream/pr/[номер pr], чтобы переключиться на их ветку. Это в основном то же самое, что делает GitHub CLI, но менее изощрённо.