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

Цель этого документа — предоставить людям, которые раньше не использовали Git, повторяемое упражнение, чтобы попрактиковаться в его использовании. В этом руководстве будет использоваться интерфейс командной строки. Хотя я настоятельно рекомендую привыкнуть к CLI, можно также использовать подключаемый модуль IDE.

Некоторые части рабочего процесса являются общими, где мы используем GitHub для определенных операций. После того, как вы выполнили это ката, вы должны понять следующие понятия:

  • Локальные и удаленные репозитории Git.
  • Что такое fetch, pull, push, merge и rebase.
  • Концепции фиксации объектов.
  • Как зафиксировать код.
  • Как слить код обратно в основную линию разработки.

Скучная часть 😴

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

Загрузите и установите Git

Установите последнюю версию Git на свой компьютер, следуя инструкциям на веб-сайте Git, https://git-scm.com/.

Настройка имени пользователя и электронной почты в Git

Откройте терминал/командную строку на своем компьютере.

Установите свое имя пользователя:

$ git config --global user.name "Joyce Byers"

Подтвердите, что вы правильно установили свое имя с помощью следующей команды:

$ git config --global user.name
> Joyce Byers

Установите свой адрес электронной почты:

$ git config --global user.email "[email protected]"

Подтвердите, что вы правильно установили свой адрес электронной почты с помощью следующей команды:

$ git config --global user.email
> [email protected]

Это важно, потому что каждый коммит Git использует эту информацию.

Необязательно: добавьте имя ветки Git в приглашение терминала (Mac/*nix)

Откройте ~/.bash_profile в редакторе и добавьте нижеследующее содержимое.

parse_git_branch() {
  git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
export PS1="\u@\h \W\[\033[32m\]\$(parse_git_branch)\[\033[00m\] $ "

Ссылка: https://gist.github.com/joseluisq/1e96c54fa4e1e5647940

Начнем 🎉

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

Разветвить и клонировать репозиторий

Форк — это копия репозитория. Разветвление репозитория позволяет вам свободно экспериментировать с изменениями, не затрагивая исходный проект. Здесь мы разветвим репозиторий git-kata.

  1. На GitHub перейдите в репозиторий the-pragmatic-dev/git-kata.
  2. В правом верхнем углу страницы нажмите Разветвить.

Прямо сейчас у вас есть ответвление репозитория git-kata, но на вашем компьютере еще нет файлов из этого репозитория. Давайте создадим клон вашей вилки локально на вашем компьютере.

  1. На GitHub перейдите к своему ответвлению репозитория the-pragmatic-dev/git-kata.
  2. Нажмите зеленую кнопку «Клонировать или загрузить».
  3. Чтобы клонировать репозиторий с помощью HTTPS, в разделе «Клонировать с HTTPS» скопируйте URL-адрес.

В своем терминале перейдите к папке, в которой вы хотите разместить свой репозиторий, введите git clone, а затем вставьте URL-адрес, который вы только что скопировали из GitHub. Это будет выглядеть так, с вашим именем пользователя GitHub вместо YOUR-USERNAME :

$ git clone https://github.com/YOUR-USERNAME/git-kata.git

Теперь у вас есть локальная копия ответвления репозитория git-kata remote. Смените каталог на папку git-kata. Наше дерево репозитория на данный момент выглядит очень просто:

|--------------------------------------------> master

Создайте ветку разработки

Когда мы работаем с Git, обычно у нас есть долговременная ветка, в которой команда разработчиков выполняет всю свою работу. Для этого мы создадим ветку develop из master.

🔥 Вы никогда не должны делать коммиты напрямую ни в ветку develop, ни в главную ветку; мы объединим код позже, используя запрос на вытягивание GitHub.

  1. На GitHub перейдите на главную страницу репозитория git-kata.
  2. Щелкните меню выбора ответвления.
  3. Введите develop в качестве имени ветки, затем выберите «Создать ветку: develop from ‘master’».

Теперь мы узнаем об удаленном и локальном. Мы только что создали нашу давно работающую ветку develop, но она существует только в удаленномрепозитории. Если мы будем искать нашу ветку в нашем local репозитории, мы ее не найдем, давайте попробуем. Введите следующее:

$ git branch -a

Опция -a показывает как локальные, так и удаленные ветки; обратите внимание, что вашей ветки develop не существует.

Теперь мы будем извлекать все последние данные™ из удаленного репозитория, которых нет в нашем локальномрепозитории. Это не только скопирует код, которого у нас нет локально, но и обновит ветки удаленного отслеживания и указатели на эти ветки отслеживания, но не обновит проверенные ветки (подробнее об этом позже).

Введите следующее:

$ git fetch

Теперь снова найдите свою ветку, и вы должны ее найти:

$ git branch -a
* master
...
remotes/origin/develop
...

Теперь наше дерево Git выглядит следующим образом как в наших удаленных, так и в локальныхрепозиториях:

|--------------------------------------------> master
  \
   \
    \
     -----------------------------------> develop

Создайте две ветки функций

Теперь мы хотим внести некоторые изменения, для этого мы создадим две ветки feature из нашей ветки develop. Это позволяет нам писать код изолированно от других разработчиков и позволяет проверять наш код перед его слиянием обратно в ветку develop.

Вернитесь на главную страницу репозитория git-kata на GitHub и создайте новые ветки.

  1. Щелкните меню выбора ветки и убедитесь, что выбрана ветка develop.
  2. Введите feature/task-1 в качестве имени своей ветки, затем выберите «Создать ветку: feature/task-1 из разработки».
  3. Убедитесь, что вы повторно выбрали ветку develop в меню выбора ветки, так как GitHub переключится на новую ветку. Создайте другую ветку с именем feature/task-2из ветки develop.

Хорошей практикой является создание одной функциональной ветки для каждой пользовательской истории; если предположить, что номер задачи JiraDEV-123, ваша функциональная ветвь будет называться feature/DEV-123.

В удаленном репозитории наше дерево Git теперь выглядит так:

|--------------------------------------------> master
  \
   \     -----------------> feature/task-1
    \   /
     -----------------------------------> develop
        \
         -----------------> feature/task-2

Пока так ничем не примечательна, мы еще не проделали ни одной работы. Итак, давайте подготовимся к этому. извлеките последние изменения из удаленного репозитория, как вы это делали раньше, и убедитесь, что вы видите эти новые ветки в своем локальном репозитории. Теперь ваш локальный репозиторий обновлен с вашим удаленным, и деревья Git будут выглядеть одинаково на обоих.

Наконец-то приступили к первой задаче

Здесь мы узнаем, как зафиксировать код и как отправить эти изменения на удаленный компьютер. Проверьте ветку feature/task-1, введя:

$ git checkout feature/task-1

Если мы посмотрим на файлы в каталоге, то увидим следующее:

  • .gitпапка Git, представляющая репозиторий.
  • .gitignore файл, который сообщает Git, что не следует фиксировать, например файлы сборки и файлы, специфичные для IDE.
  • index.htmlфайл, который мы изменим во время разработки.
  • README.md полезный файл разметки для чтения пользователями!

Откройте index.html в своем любимом редакторе и добавьте еще один абзац в основной текст, чтобы он выглядел так.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Starcourt Mall</title>
</head>
<body>
  <p>Eggos.</p>
  <p>Mornings are for coffee and contemplation.</p>
</body>
</html>

Чтобы увидеть, что мы внесли изменения, введите следующее:

$ git status

Команда status очень полезна, так как показывает состояние ветки и дает полезные советы о том, что нам следует делать. Здесь мы видим, что измененный нами файл выделен красным цветом.

Давайте посмотрим, какие изменения мы внесли, введите следующее:

$ git diff

Как подсказала команда status, мы можем добавить файл, который мы изменили, в промежуточную область, готовый к его фиксации. Сделайте, как было предложено, и введите следующее, чтобы добавить файл.

$ git add index.html

Теперь снова проверьте статус. Мы видим, что файл готов к фиксации в промежуточной области, выделенной зеленым цветом.

На этом этапе давайте внесем еще одно изменение в файл:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Starcourt Mall</title>
</head>
<body>
  <p>Eggos.</p>
  <p>Mornings are for coffee and contemplation.</p>
  <p>Have you ever heard of Mirkwood?</p>
</body>
</html>

Сделайте Git status. Теперь мы видим один и тот же файл в staging области и в файлах не staging. Что происходит 😱? Мы сообщили Git, что довольны первоначальным обновлением, поэтому оно было скопировано в тестовую область, готовое к фиксации, но рабочая версия также была изменена.

Чтобы увидеть различия между подготовленными и необработанными файлами, снова введите следующее:

$ git diff

Когда вы сделали этот тип:

$ git diff --cached

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

Допустим, мы остались довольны первой попыткой избавиться от текущего типа изменений:

$ git checkout -- index.html

Запустите команду status, чтобы увидеть, что теперь у нас есть изменения только в подготовленной области (зеленая).

Теперь давайте зафиксируем наше изменение, для краткости добавим сообщение фиксации в команду фиксации.

$ git commit -m "Added a new paragraph"

Хорошей практикой является ставить перед сообщениями фиксации номер пользовательской истории (например, идентификатор задачи Jira), это помогает при создании будущих заметок о выпуске.

Теперь посмотрите на статус, он говорит нам, что мы на один коммит опережаем источник. Поскольку ветвь отслеживает удаленный репозиторий, Git знает, что мы на один коммит впереди.

Давайте исследуем, где мы находимся. Дерево нашего локального репозитория выглядит следующим образом:

|--------------------------------------------> master
  \              (C1)
   \     ---------|-------> feature/task-1
    \   /
     -----------------------------------> develop
        \
         -----------------> feature/task-2

Мы можем просмотреть коммиты локально, набрав следующее:

$ git log

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

Если вы просмотрите удаленные коммиты в нашей функциональной ветке на GitHub, вы увидите, что наш новый коммит не существует. Теперь мы хотим отправить наши изменения в удаленный репозиторий, введя следующее (возможно, вам потребуется войти в систему):

$ git push

Если мы теперь пойдем и просмотрим коммиты в GitHub для нашей ветки feature/task-1, мы должны увидеть наш объект коммита, мы также можем изучить файлы, чтобы увидеть наши изменения.

Слияние функции/задачи-1 с нашей веткой разработки

Стандартные рабочие процессы разработки, такие как проверка кода, здесь не рассматриваются. Однако, как было сказано ранее, мы не должны фиксировать непосредственно в ветке develop или master. Мы делаем это с помощью pull request. В этом руководстве мы не будем указывать, кто просматривает и утверждает наш запрос на включение.

  • Перейдите на GitHub и нажмите на вкладку «Запросы на извлечение».
  • Нажмите на кнопку «Новый запрос на включение».
  • На экране «Сравнение изменений» убедитесь, что в меню выбора установлено значение «базовый: разработка» и «сравнить: функция-задача-1».
  • Нажмите кнопку «Создать запрос на включение». Затем вы можете дать запросу на вытягивание заголовок и описание. Наконец, нажмите кнопку «Создать».

Рекомендуется начинать название с номера пользовательской истории, за которым следует название нашей пользовательской истории.

Теперь нажмите «Объединить запрос на включение» и «Подтвердить слияние». Хорошей практикой является удаление веток функций после того, как мы закончим с ними, чтобы поддерживать порядок в удаленном репозитории. Для этого нажмите кнопку «Удалить ветку».

Посмотрим, где мы сейчас. Дерево remote Git теперь выглядит так:

|--------------------------------------------> master
  \
   \
    \            (C1)  merge
     -------------|------|---------------> develop
        \
         -----------------> feature/task-2

Давайте проверим наш локальныйрепозиторий, открыв ветку develop и просмотрев журнал.

$ git checkout develop
$ git log

В ветке develop нет фиксации C1 или фиксации слияния. Это понимание очень важно для работы Git. Чтобы обновить наш локальныйрепозиторий, чтобы он соответствовал нашему удаленномурепозиторию, нам нужно выбрать, а также объединить, чтобы внести изменения из отслеживаемой ветки в проверенную версию. Это можно сделать одной командой pull, которая выполняет git fetch и git merge в одном:

$ git pull

Теперь ваша локальная ветка develop будет обновлена ​​до удаленной ветки, которая содержит нашу функцию из задачи 1. ! 🎉

Далее к задаче два

Теперь вы должны быть в состоянии сделать следующее без особой помощи:

  1. Проверьте ветку feature/task-2 на локальном компьютере.
  2. Изменить заголовок страницы:
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>We're not in Hawkins anymore</title>
</head>
<body>
  <p>Eggos.</p>
</body>
</html>

3. Добавьте это изменение в подготовленную область.

4. Подтвердите изменение со следующим сообщением «Изменено название».

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

  1. Добавьте следующую метаинформацию на страницу в строке ниже текущего метатега:
<meta name="keywords" content="git">

2. Добавьте это изменение в подготовленную область.

3. Зафиксируйте изменение со следующим сообщением «Добавлен метатег HTML».

Теперь у нас есть local дерево Git, которое выглядит так:

|--------------------------------------------> master
  \
   \
    \            (C1)  merge
     -------------|------|---------------> develop
        \
         ---------|------|--> feature/task-2
                (C2)   (C3)

Мы хотим объединить наши изменения в ветке feature/task-2 с веткой develop. Чтобы сделать это аккуратно, нам нужно сделать две вещи:

  • Раздавить наши изменения; это делает дерево Git более аккуратным при просмотре истории, по одной фиксации на функцию. Это также упрощает перебазирование, так как нам нужно воспроизвести только один объект фиксации поверх других изменений (и исправить конфликты слияния для одного объекта фиксации).
  • Перебазируйте с помощью ветки develop, чтобы убедиться, что мы запускаем наш код с любым другим кодом, который был зафиксирован после того, как мы взяли нашу ветку (например, функция/задача-1!).

Итак, давайте раздавим наши два коммита. Прежде чем мы это сделаем, давайте запишем две ссылки на объект фиксации, которые у нас есть для C2 и C3, набрав:

$ git log -n2

Запишите первые шесть символов хеша коммита для каждого из коммитов, в моем случае это были 65b0b7… и 015d9d…

Теперь мы объединим два коммита вместе. Введите следующее, где 2 — это количество объектов фиксации, которые мы хотим раздавить:

$ git rebase -i HEAD~2

Затем мы следуем интерактивному руководству, выбирая, какие коммиты мы хотим сохранить (выбрать) и какие мы хотим раздавить (s). Я использую редактор vi по умолчанию.

  • Замените слово «выбрать» во второй строке на «s». Мы хотим втиснуть второй коммит в первый коммит.
  • Сохранить и выйти
  • На следующей странице просто сохраните и выйдите.

Теперь у нас есть один коммит в нашей ветке, и наше local дерево Git выглядит так:

|--------------------------------------------> master
  \
   \
    \            (C1)  merge
     -------------|------|---------------> develop
       \
        ---------|---------> feature/task-2
               (C2')

Очень важно отметить, что этот объект фиксации C2' отличается от того, что был раньше. Сделайте еще один журнал Git и проверьте хэш-код объектов фиксации, чтобы убедиться, что это действительно другой объект фиксации. Кроме того, снова запишите первые шесть символов.

Теперь мы хотим перебазироваться из нашей ветки develop, это фактически будет означать, что у нас есть другие изменения из feature/task-1 в нашей ветке. .

Во-первых, мы получим все изменения, что является хорошей практикой, чтобы убедиться, что ветки удаленного отслеживания обновлены в удаленномрепозитории:

$ git fetch

Теперь выполним ребазинг из ветки develop:

$ git rebase develop feature/task-2

Теперь наше локальное дерево Git выглядит так:

|--------------------------------------------> master
  \
   \
    \            (C1)  merge
     -------------|------|---------------> develop
       \
        ---------|---------> feature/task-2
               (C2'')

Обратите внимание, что важно понимать, что C2'' снова является другим объектом фиксации, чем C2 и C2'. Сделайте журнал Git и сравните хэш-коды коммитов Git, чтобы убедиться в этом.

Теперь самое время запустить любые существующие тесты локально и просмотреть файл index.html, чтобы увидеть, есть ли в нем все ожидаемые изменения (включая изменения из feature/task -1!).

Теперь мы можем сделать то, что делали раньше:

  • Отправьте наши изменения в удаленный репозиторий.
  • Поднимите запрос на вытягивание из исходной ветки feature/task-2 в целевую ветку develop.
  • Внесите изменения в ветку develop, а также удалите нашу ветку feature/task-2.

Затем вы можете проверить GitHub, чтобы убедиться, что все коммиты есть.

Теперь дерево Git выглядит так:

|--------------------------------------------> master
  \
   \
    \            (C1)  merge   (C2'')  merge
     -------------|------|------|--------|---> develop

GitFlow

Я настоятельно рекомендую строго следовать стратегии ветвления Git при работе в команде разработчиков. Одной из таких стратегий является GitFlow, она привлекла большое внимание благодаря тому, что очень хорошо подходит для совместной работы и масштабирования с командой разработчиков.

Самые внимательные из вас заметят, что в этом руководстве мы следовали упрощенной стратегии GitFlow. Хотя диаграмма GitFlow может показаться более сложной, все необходимые команды Git были рассмотрены! 🎉

Ссылка: https://datasift.github.io/gitflow/IntroductionGitFlow.html

Слияние с нашей основной веткой

В этом руководстве мы не объединяемся с master для краткости. Однако процесс остается прежним. GitFlow утверждает, что master должен реплицировать рабочую среду, поэтому вы должны создать запрос на вытягивание из ветки develop в ветку master для вашего следующего выпуска. Ветвь develop никогда не следует удалять, в отличие от веток feature.

Недавно я начал разработку MECO, облачной платформы с открытым исходным кодом, помогающей модерировать откровенный контент в Интернете. Посетите нашу публикацию, чтобы найти больше похожих статей. С помощью науки о данных мы можем создать более безопасную онлайн-среду.