Использование Git в реальном мире

Основы Git очень просты, но стОит попасть в нестандартную ситуацию, и вы можете почувствовать себя совершенно запутавшимся. Ситуацию усугубляет тот факт, что при неверном решении вы рискуете потерять свои данные. На самом деле, с Git данные потерять очень трудно, но решение может быть спрятано в таком месте, куда сложно добраться, не обладая достаточными знаниями.

Вы получите свою долю злоключений с Git, но через это приходится пройти каждому. Лучшее средство от проблем - это делать коммиты часто и вовремя. Чем они меньше и модульнее, тем меньше шансов появления трудноисправимой ошибки.

Многие спорят о том, как правильно использовать Git в работе. Наше мнение таково: ваш комментарий к коммиту должен полностью описывать (в настоящем времени) его содержимое, например "add About section to navbar on static pages". Комментарий должен быть на английском языке, вне зависимости от того, какой язык используете вы или ваша команда разработчиков. Если вы хотите использовать точку или "и", то, возможно, вы включили в коммит слишком много, и его следовало бы делать более модульным и независимым.

В процессе работы может появиться непреодолимое желание немедленно исправить увиденную ошибку в коде, изменив к примеру, CSS. Увы, все грешат этим. Лучшим же решением будет взять проблему на карандаш и закончить текущую работу. Затем, когда вы сделаете коммит, или проведете слияние, можете спокойно вернуться к решению увиденного бага, выделив его в отдельную ветку.

Повторюсь, Git создан для того, чтобы вы разделяли задачи, и коммиты были независимы друг от друга. С этим принципом вы можете с легкостью переключаться между задачами, а не смешивать их в одну кучу. Если вдруг вы вернетесь назад и измените ваш единственный цельный коммит, вы поймете суть проблемы на деле, и далее станете придерживаться правильной методики.

Касаемо Git - если вы не обладаете впечатляющей памятью, вы не изучите его.. вы просто должны работать с ним. Найдите проблему, исправьте ее, получите ошибку при слиянии... погуглите причину ошибки, изучите тактику при работе с Git в реальной работе.

Вернитесь к этому уроку, когда столкнетесь с проблемой. Для начала, мы посмотрим на нашем проекте пример работы с Git из реальной жизни. Раздел дополнительных ресурсов поможет вам найти качественные источники информации, когда они вам понадобятся.

Порядок работы с Git в проектах с открытым кодом

Скажем, вы хотите внести свою лепту в этот сайт. Как это сделать? Описываемая методика - это полностью рабочий процесс, который уже используется сообществом сайта. Здесь мы подразумеваем, что вы не имеете прав на запись в оригинальный репозиторий.

Ключевыми игроками в этом случае являются upstream (оригинальный репозиторий на Github), origin (ваш форк этого репозитория) и ваш локальный клон форка ("local"). Представьте это как треугольник... за исключением того, что "local" только копирует данные с upstream, но не изменяет их, используя push.

Первоначальная настройка

  1. Используя кнопку "fork" с этой страницы, сделайте форк репозитория "upstream" в ваш собственный аккаунт на Github.
  2. Сделайте локальный клон форка, используя нечто вроде $ git clone git@github.com:your_user_name_here/codenamecrud.git (полный url можно взять на правом сайдбаре странички вашего форка на Github).
  3. Теперь у вас есть удаленный репозиторий, который указывает на origin, то есть на ваш форк. С помощью команды push, вы будете отправлять его изменения на Github. Вы также захотите иметь возможность использовать pull для оригинального репозитория на Github, который мы называем upstream, назначив его другим "удаленным". Чтобы сделать это, выполните $ git remote add upstream git@github.com:codenamecrud/codenamecrud.git.
  4. Если вы используете git впервые, не забудьте указать ваше имя и почту, выполнив:

    $ git config --global user.name "YOUR NAME"
    $ git config --global user.email "YOUR_EMAIL@EXAMPLE.COM"
    

Процесс работы

У нас есть две основные ветки -- master и dev. master используется для готового к работе в production кода. Любой код, попадающий сюда, будет протестирован и перейдет в production. Вы же будете работать с отдельной веткой и создавать пулл реквесты в ветку dev. Представьте, что ветки master вообще не существует.

  1. Создайте ветку для любого функционала, используя $ git checkout -b your_feature_name.
  2. Напишите код, закоммитьте его, напишите еще, повторите коммит (видите шаблон?).
  3. Когда вы сделали работу, есть шанс, что кто-то уже внес изменения в "upstream". Это значит, что ветки master и dev уже устарели. Выполните $ git fetch upstream для получения свежих данных.
  4. Используйте $ git branch --all, чтобы получить список всех веток, в том числе тех, которые обычно скрыты (например удаленных веток, которые вы только что получили). Среди них вы должны увидеть upstream/master и upstream/dev.
  5. Теперь слейте изменения из upstream в локальную версию dev, используя $ git merge. В данном случае, будет необходимо выполнить $ git checkout dev, чтобы попасть на ветку dev, и затем выполнить $ git merge upstream/dev. На этом перенос изменений в dev будет закончен.
  6. Замечу, что команды $ git fetch upstream и $ git merge upstream/some_branch - это то же самое, что и одна команда $ git pull upstream/some_branch, просто я предпочитаю разделять ее на два шага.
  7. Теперь, когда ветка dev содержит актуальные данные, необходимо слить ее с вашей веткой нового функционала. Хотя это звучит странно, тем не менее это так и есть. Хотите вместо этого слить ветку нового функционала с dev? Да хотите, но не сейчас. Ваша ветка с новым функционалом "грязная". Вы не знаете, содержит ли она потенциальные конфликты. Каждый раз, когда вы сливаетесь со "старшими" ветками (например ветку с вашим функционалом в dev, или же dev в master), вам необходимо, чтобы слияние было неконфликтным. Поэтому, сначала необходимо слить "старшую" ветку с "младшей" для разрешения конфликтов. Так что, мы выполняем $ git checkout your_feature_name, чтобы перейти на вашу ветку с новым функционалом, а затем $ git merge dev, чтобы слить в нее dev.
  8. Возможно вы получите конфликт слияния... разрешите его с помощью $ git mergetool, или просто откройте вручную конфликтующие файлы. В основном, в таких случаях, в файлы вносятся маркеры, обозначающие, какие строки относятся к новому коду, а какие - к существующему. Необходимо один за одним отредактировать эти файлы (включая удаление маркированного текста), а затем пересохранить их. После этого, необходимо провести коммит, чтобы закончить слияние.

Создание Pull Request (ПР)

  1. После того, как ветка с вашим функционалом проверена, и вы знаете, что она сольется с dev без ошибок, осталось пройти пару шагов. Выполните слияние с dev командами $ git checkout dev и $ git merge your_feature_name.
  2. Теперь необходимо отослать локальную ветку dev в origin (напомним, это ваш форк на Github). Вы не можете отослать изменения сразу на upstream, так как у вас нет туда доступа, поэтому вам необходимо выполнить Pull Request (ПР). Команда $ git push origin dev отправит ветку dev в origin.
  3. И, наконец, создайте ПР, чтобы отправить свою версию dev в ветку dev репозитория upstream. Это может быть сделано с использованием пользовательского интерфейса Github. Здесь вы должны быть уверены в том, что отправляете ПР в ветку dev, а не в master.
  4. Готово!

Пункты для размышления

Постарайтесь ответить на предложенные вопросы. После выполнения задания попробуйте ответить на них ещё раз

  • Как часто необходимо выполнять коммит?
  • Как велики они должны быть?
  • Что должен содержать комментарий?
  • Можно ли коммитить незаконченный функционал?
  • Какой метод работы вы должны использовать? (Merge? Topic Branches? Git-Flow? Rebase?). Подсказка: здесь нет правильного ответа.

Задания:

  1. Прочтите Best Practices от Тауэра.
  2. Пробегитесь по Git Best Practices от Seth Robertson. Сильно не переживайте по поводу незнакомых команд... главное понять основные концепции.

Дополнительные ресурсы

Этот раздел содержит полезные ссылки на дополнительные материалы. Они не обязательны, так что расценивайте их как нечто полезное, если вы хотите поглубже погрузиться в тему

Поделиться уроком: