Close

Переключение на запрос pull с помощью команды git fetch: новый уровень мастерства

Фотография Николы Паолуччи
Николя Паолуччи

Консультант по разработке


Сегодня для внесения исправлений в проект достаточно создать форк (чтобы в свое удовольствие возиться с полной удаленной копией проекта), выбрать нужный файл, нажать Edit (Правка) и сделать коммит с изменениями.

А что, если вы на другой стороне и получаете запрос pull? Проработанный веб-интерфейс функционирует прекрасно, и зачастую этого вполне достаточно. Нажмите Approve (Подтвердить), затем Merge (Объединить), и готово.

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

Загрузить запрос pull от коллеги или участника проекта с помощью команд fetch и checkout совсем не сложно, однако можно сделать эту процедуру еще проще, если учесть несколько важных нюансов.

В этой статье я расскажу об инструментах git для удобной работы с запросами pull через командную строку.

Перед началом: добавление имени и статуса ветки в приглашение оболочки


Меня поражает, что многие работают с пустым приглашением командной строки, где не отображается ни имя текущей ветки git, ни наличие измененных/неотправленных файлов в рабочем каталоге. Узнали в этом описании себя? Позвольте помочь вам, а заодно поразить ваше воображение!

Сделайте себе одолжение: установите что-нибудь вроде дивного скрипта liquid prompt, который выдает полезные пояснения о состоянии рабочего каталога git (а также других систем контроля версий):

(На скриншоте выше можно увидеть мое приглашение, которое показывает, что я нахожусь в ветке newbranch и добавил 5 строк в файлы, которые отслеживаю в своем рабочем каталоге, а удалил 0 строк.)

Логотип Git
Связанные материалы

Установка Git

Логотип Bitbucket
СМ. РЕШЕНИЕ

Изучите Git с помощью Bitbucket Cloud

Когда все работают в одном репозитории


Если вы всей командой работаете в одном репозитории, переключиться на запрос pull очень просто: достаточно выполнить команды fetch и checkout для ветки, из которой его создавали:

  • Получите все ветки, опубликованные в общем репозитории:
git fetch origin
  • Создайте локальную ветку, которая отслеживает нужную удаленную ветку:
git checkout -b PRJ-1234 origin/PRJ-1234
  • Теперь можно выполнить команды diff и merge, а затем проверять код хоть до потери пульса:
git diff main ./run-tests.sh
  • Когда вы будете довольны результатами, можно просто вернуться в веб-интерфейс и оставить отзыв или сразу нажать Approve (Подтвердить).

Когда участники работают в своих форках


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

  • Прежде всего добавьте удаленный репозиторий участника:
git remote add jsmith http://bitbucket.org/jsmith/coolproject.git
  • Сначала соберите все последние обновления из origin — основного репозитория:
git checkout main git fetch origin git merge main
  • Получите все ветки, опубликованные в форке участника:
git fetch jsmith
  • Создайте локальную ветку, которая отслеживает нужную удаленную ветку:
git checkout -b jsmith-PRJ-1234 jsmith/PRJ-1234
  • Теперь можно выполнить команды diff и merge, а затем проверять код хоть до потери пульса:
git diff main ./run-tests.sh

Избавление от лишней работы с помощью ссылок на запрос pull


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

  • Что делать, если у вас много участников и все они работают в своих форках? Добавлять и обрабатывать по отдельности каждый форк будет нецелесообразно.
  • Что делать, если у вас вообще нет доступа к некоторым форкам и переключиться на ветку с исходным кодом невозможно?

Обе эти проблемы можно решить с помощью ссылок на запросы pull, которые предоставляют некоторые серверы git. Я покажу процедуру, которую поддерживают некоторые серверы git и которая немного различается в зависимости от того, какой сервер вы используете. Далее я расскажу, как получить все запросы pull с помощью команды fetch в Stash (теперь Bitbucket Server) и GitHub.

Не бойтесь спецификаций ссылок

Прежде всего нужно ознакомиться со спецификациями ссылок. Спецификации ссылок — это классная и совсем не страшная вещь. Это всего лишь сопоставления удаленных веток с локальными ссылками, другими словами, простой способ указать git, что эту удаленную ветку (или набор удаленных веток) нужно локально соотнести с этими именами в этом пространстве имен.

Например, команда:

git fetch +refs/heads/main:refs/remotes/origin/main

…сопоставит удаленную ветку main в удаленном репозитории origin c локальной origin/main, после чего можно будет написать:

git checkout origin/main

…и по-прежнему обращаться к этой удаленной ветке. С помощью знака плюс (+) в определении мы сообщаем git, что ссылку нужно обновить даже без ускоренного слияния.

Чтобы загрузить таким образом все запросы pull, для удобства использования нужно сопоставить сохраненные в удаленном репозитории указатели HEAD запросов pull с локальным пространством имен.

Итак, если у вас есть удаленный репозиторий origin (или upstream), вот что нужно сделать.

Примечание. Как справедливо отметили несколько разработчиков Stash (теперь Bitbucket Server), ссылки, которые я продемонстрирую ниже, считаются недокументированными, частными и могут измениться в любое время.

Загрузка всех запросов pull: Stash

  • Сделайте форк репозитория.
  • Клонируйте форк в локальный репозиторий:
git clone git@stash.atlassian.com:durdn/tis.git
git remote add upstream git@stash.atlassian.com:tpettersen/tis.git
  • Получите последние указатели head от человека, сопровождающего репозиторий upstream
git fetch upstream
  • Добавьте спецификацию ссылок, по которой можно будет сопоставить удаленные запросы pull с локальным пространством имен pr. Это можно сделать с помощью команды config:
git config --add remote.origin.fetch '+refs/pull-requests/*/from:refs/remotes/origin/pr/*'
  • Если заглянуть в .git/config, можно увидеть такие записи fetch:
[remote "upstream"]
    url = git@stash.atlassian.com:docker/libswarm.git
    fetch = +refs/heads/*:refs/remotes/upstream/*
    fetch = +refs/pull-requests/*/from:refs/remotes/upstream/pr/*
  • Теперь все ветки запросов pull легко получить с помощью команды fetch:
$ git fetch upstream

remote: Counting objects: 417, done.
remote: Compressing objects: 100% (274/274), done.
remote: Total 417 (delta 226), reused 277 (delta 128)
Receiving objects: 100% (417/417), 105.28 KiB | 0 bytes/s, done.
Resolving deltas: 100% (226/226), done.

From stash.atlassian.com:docker/libswarm
 * [new ref]         refs/pull-requests/10/from-> upstream/pr/10
 [...]
 * [new ref]         refs/pull-requests/100/from -> upstream/pr/100
 * [new ref]         refs/pull-requests/101/from -> upstream/pr/101
 [...]
 * [new ref]         refs/pull-requests/109/from -> upstream/pr/109
 * [new ref]         refs/pull-requests/110/from -> upstream/pr/110
 [...]
  • Чтобы переключиться на конкретный запрос pull, теперь достаточно написать:
git checkout pr/102

Загрузка всех запросов pull: GitHub

Если форки или вышестоящие репозитории находятся на GitHub, все работает точно так же, как указано выше, но команду config нужно изменить:

 git config --add remote.origin.fetch '+refs/pull//head:refs/remotes/origin/pr/'

После этого для удаленного репозитория в .git/config появится дополнительная конфигурация команды fetch для сопоставления указателей head запросов pull с локальным пространством имен под названием pr:

[remote "upstream"] url = git@github.com:docker/libswarm.git fetch = +refs/heads/*:refs/remotes/upstream/* fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*

Получение одного запроса pull с помощью ссылок

Если вам не нужно настраивать записи fetch в файле .git/config и вы просто хотите быстро получить запрос pull, достаточно одной команды.

  • Переключение на отдельный запрос pull в Stash:
git fetch refs/pull-requests/your-pr-number/from:local-branch-name
  • Переключение на отдельный запрос pull в GitHub:
git fetch refs/pull/your-pr-number/head:local-branch-name

А если вы поймете, что часто используете вышеперечисленные команды, процесс можно упростить, создав псевдоним git:

# For Stash
git config alias.spr '!sh -c "git fetch origin pull-requests/${1}/from:pr/${1}" -'

# For Github
git config alias.gpr '!sh -c "git fetch origin pull/${1}/head:pr/${1}" -'

После настройки псевдонима получить запрос pull можно простой командой (спасибо inuit):

Заключение


Надеюсь, эта статья была для вас полезна! По большому счету, чтобы легко следить за работой коллег или участников, достаточно создать пару несложных псевдонимов или добавить соответствующие спецификации ссылок в файл .git/config. С радостью отвечу на любые ваши вопросы в Twitter по адресу @durdn или @AtlDevtools.

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


Поделитесь этой статьей

Рекомендуемые статьи

Добавьте эти ресурсы в закладки, чтобы изучить типы команд DevOps или получать регулярные обновления по DevOps в Atlassian.

Люди сотрудничают друг с другом, используя стену со множеством инструментов

Блог Bitbucket

Рисунок: DevOps

Образовательные программы DevOps

Демонстрация функций в демо-зале с участием экспертов Atlassian

Как инструмент Bitbucket Cloud работает с Atlassian Open DevOps

Подпишитесь на информационную рассылку по DevOps

Thank you for signing up