Как сделать pull request
Pull Request — запрос на включение. На включение написанного вами кода в чужой репозиторий.
С чего начать?
А для начала этот самый репозиторий нужно форкнуть (fork — вилка, ответвление). Разберём это нехитрое действо на примере веб-сервиса для хостинга IT-проектов, название которому GitHub. Разумеется, кроме GitHub есть и другие: BitBucket, например. Выбирать по вкусу.
Для успешного проведения нижеизложенных операций у вас (что естественно) должен быть установлен git
В консоли в зависимости от входных данных набираем нечто подобное:
Отлично. Уже можно вносить свои изменения в код проекта.
Тот репозиторий, что теперь лежит на вашем жёстком диске, независим от основного. В нём отслеживаются только ваши наработки. Но как следить за изменениями, происходящими в первоисточнике, откуда вы « стянули » репозиторий? Добавить удаленный репозиторий в отслеживаемые. Например, так:
Давайте посмотрим как сливать изменения из оригинального репозитория к себе в случае, если разработка в нём ушла вперёд пока вы сосредоточенно писали коммиты:
Если репозиторий огромен, а забирать его весь не хочется, клонируем только нужную ветку:
Что такое ветки?
Чаще всего ветки (branch — ответвление, ветвь, филиал) бывают тематическими. Например, при общей разработке, когда у всех участников есть право записи в репозиторий. В этом случае ветки используются для отделения изменений, сделанных одним из разработчиков, от общего репозитория. Ветки могут пригодиться и в случае с созданием pull-request’а.
Создание ветки происходит довольно просто. Находясь в каталоге с проектом, наберите следующие команды:
Новые ветки создаются не только из master, берите любую!
Находясь в только что созданной ветке, вы можете приступить к работе. Вносите в код свои изменения, а когда закончите просто переключитесь обратно к своей основной ветке. Вы можете отправить pull request, выбрав ветку new_branch или же прежде слить изменения из неё в основную ветку разработки. Рассмотрим это подробнее:
Если нужно отправить в свой удалённый репозиторий вновь созданную ветку (не сливать её с master), делаем следующее:
Не торопитесь сливать изменения. Если что-то не заладилось, созданную ветку можно удалить:
Удалить все локальные ветки, которые были смержены (то есть код которых теперь есть) в ветках develop или master:
Отправляем изменения
Добрались таки до ответа на поставленный вопрос: что такое pull request, зачем оно нужно и как его достичь. Как предложить владельцу репозитория свои изменения?
Для этого зайдите в свой аккаунт, выбирайте репозиторий владельца и ищите небольшую зелёную кнопку (на момент написания поста она была таковой, если даже что-то изменится, думаю, найти её будет несложно).
А дальше. ждать. Пока придёт владелец оригинального репозитория и примет/отклонит ваши изменения.
Ну вот, мы его достигли. Просветления то есть 🙂
Как отменить изменения
Когда нужно вернуть более старое состояние уже проиндексированных файлов и забыть о них совсем (помните, что упомянутая здесь операция отменит всю вашу работу до определённого коммита!):
Cмотрим на какой коммит откатиться. В примере откатываемся назад на 1 коммит. Для изменения состояния в этой же ветке удалённого репозитория тоже придётся использовать грубую силу — флаг force :
Или посмотреть все изменения, которые происходили с отдельным файлом:
А подробнее?
Итогов подводить не стану. Для заинтересованных лиц ссылочка на неофициальную документацию: The Git Community Book
Практическое занятие «Процесс Pull request на GitHub»
На предыдущем занятии Используем клиент GitHub для десктопа, мы использовали Github Desktop для управления рабочим процессом коммитов, ветвления и слияния. На этом занятии мы будем выполнять аналогичные действия, но с использованием браузерного интерфейса, который предоставляет Github, вместо использования терминала или Github Desktop.
Понимание процесса Pull request является важным для анализа изменений в опен-сорс проекте с несколькими участниками. Использование интерфейса GitHub также удобно, если рецензенты не знакомы с терминалом или Github Desktop.
Создание изменение в отдельной ветке
По умолчанию в новом репозитории есть одна ветка с именем «Master». Обычно, когда при внесении изменений или просмотра / редактировании, создается новая ветка и вносятся все изменения в ветку. Затем, по окончании, владелец репо объединяет изменения из новой ветки в «Master» через «pull request».
Для создания изменений в отдельной ветке:
При создании новой ветки, содержимое из главной (или любой другой ветки, которая сейчас просматривается) копируется в новую ветку. Процесс похож на «Сохранить как» с существующим документом.
Рецензенты могут продолжать вносить изменения таким образом, пока не закончат просмотр всей документации. Все изменения делаются в этой новой ветке, а не в мастере.
Создание Pull request
Для создания Pull request:
Когда мы сравниваем ветку с мастером, мы увидим список всех изменений. Мы можем просмотреть изменения в двух режимах просмотра: Unified или Split (это вкладки, показанные справа от содержимого). Unified показывает правки вместе в одной области содержимого, тогда как split показывает два файла рядом.
Владелец репозитория увидит pull request и сможет принять меры для его объединения.
Процесс Pull request
Теперь посмотрим на процесс со стороны владельцем проекта, который получил новый Pull request. Владельцу нужно обработать Pull request и объединить ветку sme-review с “Master”.
Также стоит обратить внимание, что если запрос на извлечение выполняется для более старой версии мастера, где исходное содержимое мастера больше не существует или перемещено в другое место, процесс слияния будет более трудным для выполнения.
Ветка sme-review объединяется с мастером. Теперь “Master” и ветка sme-review совпадают (ветки “смержены”).
Если посмотреть на список веток, то после удаления ветка sme-review больше не отображается.
Добавление участников в проект
Иногда необходимо добавлять соавторов в проект Github, чтобы они могли вносить изменения в ветку. Если другие участники проекта, не являясь соавторами, захотят внести изменения, они получат сообщение об ошибке. (Inviting collaborators to a personal repository)
Человек без прав на запись, может “форкнуть” (скопировать) репо, а не вносить изменения в ветку в том же проекте. Однако копирование проекта клонирует весь репозиторий, а не создает ветку в том же репозитории. Форк (копия) будет существовать в учетной записи пользователя GitHub. Можно объединить форкнутый репозиторий (это типичная модель для опен-сорс проектов со многими внешними участниками), но этот сценарий, вероятно, менее распространен для технических писателей, работающих с разработчиками в тех же проектах.
Для добавления соавторов в проект:
Pull request git что
Как сделать pull request
Регистрация на GitHub
Если у вас нет аккаунта на Github – регистрируемся по ссылке http://github.com/join
Если есть – просто входим по ссылке http://github.com/login
Как сделать pull request прямо на GitHub
Шаг 1. Заходим в основной репозиторий задачи https://github.com/urfu-2015/verstka-tasks-1
И делаем форк задачи к себе. Для этого жмём «fork» в правом верхнем углу.
Форк (fork) можно расматривать, как личную копию основного репозитория.
Шаг 2. Заходим к себе https://github.com/gogoleff/verstka-tasks-1. Вместо gogoleff свой логин.
Шаг 3. Нажимаем на файл, который хотим изменить. Затем кнопку редактирования.
Шаг 4. Редактируем файл до готовности прямо здесь (или вставляем код из любимого редактора)
Шаг 5. Когда всё готов создадим коммит.
Для этого внизу в поле «summary» вводим поясняющий текст, и нажимаем «Commit changes».
Коммит (commit) – можно рассматривать, как утверждение кода, создание версии (как в wiki). К каждой версии можно вернуться. Каждый новый коммит – новая версия вашего кода.
Шаг 6. Создаём pull request. Для этого выбираем пункт меню справа «Pull requests».
И нажимаем кнопку «New pull request».
Шаг 7. Нажимаем кнопку «Create pull request»
Шаг 8. Вводим своё ФИО и нажимаем кнопку «Create pull request»
Готово!
Если нужны правки, просто повторяем шаги со 2 по 5.
Как сделать pull request в windows
Шаг 1. Заходим в основной репозиторий задачи https://github.com/urfu-2015/verstka-tasks-1
И делаем форк задачи к себе. Для этого жмём «fork» в правом верхнем углу.
Форк (fork) можно расматривать, как личную копию основного репозитория.
Шаг 2. Затем скачивание приложение по ссылке https://desktop.github.com/
Шаг 3. Устанавливаем. После установки приложение попросит настроить его. Вводим логин и пароль.
Шаг 4. Затем полное имя и электронную почту (обычно уже верно заполнены).
Шаг 5. После настройки вы попадёте в приложение. Теперь клонируем репозиторий с задачей.
Для этого нажимаем «+» в левом верхнем углу, выбираем свой логин слева, и репозиторий verstka-tasks-1 справа.
Клон (clone) можно расматривать, как локальную копию личного репозитория.
Шаг 6. Выбираем рабочую директорию (обычно уже подходящая).
Шаг 7. Теперь заходим в директорию (там должны быть файлы index.html и README.md).
Шаг 9. Решаем задачу, редактируем файлы в любимом редакторе до полной готовности. В приложении видим изменения.
Шаг 10. Когда всё готов создадим коммит.
Для этого внизу в поле «summary» вводим поясняющий текст, и нажимаем «Commit to master».
Коммит (commit) – можно рассматривать, как утверждение кода, создание версии (как в wiki). К каждой версии можно вернуться. Каждый новый коммит – новая версия вашего кода.
В результате видим сообщение:
Шаг 11. Таким образом мы утвердили наши изменения в локальном (склонированном) репозитории. Теперь необходимо отправить ветку с изменениями в удалённый личный (форк) на github.com и сделать pull request. В качестве название пулл-реквеста вводим своё ФИО и нажимаем «Send Pull Request».
В результате видим сообщение:
Готово!
Если нужны правки, повторяем шаги 9 и 10. Затем нажимаем «Sync» в правом верхнем углу. Приложение отправит коммит в удалённый личный репозиторий (форк), что автоматически обновит pull request.
Как сделать pull request в windows, используя Git Shell
Здесь два варианта:
После установки, запускаем Git Bash
(ярлык для запуска можно найти в меню Пуск).
Устанавливаем вместе с приложением Git Shell.
Для этого выполняем шаги со 2 по 4 раздела Как сделать pull request в windows
После установки приложения, запускаем Git Shell
(ярлык для запуска можно найти на рабочем столе).
Далее смотрим shell команды в разделе как сделать pull request в linux.
Как сделать pull request в linux
Заходим в основной репозиторий задачи https://github.com/urfu-2015/verstka-tasks-1
И делаем форк задачи к себе. Для этого жмём «fork» в правом верхнем углу.
В linux уже установлен git и обычно настроен.
Шаг 1. Выполняем следующие команды в терминале:
Шаг 2. Заходим в к себе в репозиторий.
Шаг 3. Создаём pull request. Для этого выбираем пункт меню справа «Pull requests».
И нажимаем кнопку «New pull request».
Шаг 4. Нажимаем кнопку «Create pull request»
Шаг 5. Вводим своё ФИО и нажимаем кнопку «Create pull request»
Готово!
Если нужны правки. Вносим их в любимом редакторе, и снова делаем коммит.
Лучший Pull Request
Относительно недавно мне посчастливилось присоединиться к команде разработки Bitbucket Server в Atlassian (до сентября он был известен как Stash). В какой-то момент мне стало любопытно, как этот продукт освещён на Хабре, и к моему удивлению, нашлось лишь несколько заметок о нём, подавляющее большинство которых на сегодняшний день уже устарело.
В связи с этим я решил опробовать себя в роли рассказчика и затронуть техническую сторону Bitbucket. Прошу не рассматривать моё намерение как попытку рекламы, ибо я совершенно не преследую эту цель. Если эта статья обнаружит интерес со стороны читателей, я буду рад развивать тему и постараюсь ответить на возникающие вопросы.
Позвольте начать с перевода статьи Тима Петтерсена «A better pull request» о том, как должен выглядеть pull request, чтобы наиболее эффективно решать возложенную на него задачу.
В любой русскоязычной технической статье, касающейся систем контроля версий (как, впрочем, большинства любых связанных с IT тем), автор сталкивается с необходимостью использования специфичных терминов, которые могут быть или не быть переведены на русский. В жизни большинство этих терминов не переводится и используется при вербальном общении «как есть», то есть, по сути, транслитерируется. В письменной же форме их, строго говоря, следует переводить, однако в этом случае термины зачастую совершенно перестают быть созвучными англоязычным версиям, что сильно затрудняет их восприятие читателями.
Мне хотелось бы пользоваться привычными названиями и в письменной речи, однако некоторые термины я не буду даже транслитерировать, поскольку, на мой взгляд, они становятся слишком корявыми, и потому оставлю их в английском написании, — прошу понять и простить. С другой стороны, я открыт критике и предложениям, поэтому если вы считаете, что есть лучший способ выразить тот или иной термин, прошу делиться этими мыслями. Спасибо.
Если вы используете Git, то наверняка пользуетесь и pull request-ами. Они в той или иной форме существуют с момента появления распределённых систем управления версиями. До того, как Bitbucket и GitHub предложили удобный веб-интерфейс, pull request мог представлять собой простое письмо от Алисы с просьбой забрать какие-то изменения из её репозитория. Если они были стóящими, вы могли выполнить несколько команд, чтобы влить эти изменения в вашу основную ветку master:
Разумеется, включать изменения от Алисы в master не глядя — это далеко не лучшая идея: ведь master содержит код, который вы собираетесь поставлять клиентам, а потому наверняка хотите внимательно следить за тем, что в него попадает. Более правильный путь, чем простое включение изменений в master, — это сначала влить их в отдельную ветку и проанализировать перед тем, как cливать в master:
Приведённая команда git diff с синтаксисом трёх точек (в дальнейшем «triple dot» git diff) покажет изменения между вершиной ветки alice/branch и её merge base — общим предком с локальной веткой master, иначе говоря, с точкой расхождения истории коммитов этих веток. В сущности, это будут ровно те изменения, которые Алиса просит нас включить в основную ветку.
git diff master. alice/master эквивалентен git diff A B
На первый взгляд, это кажется разумным способом проверки изменений pull request-а. Действительно, на момент написания статьи, именно такой алгоритм сравнения применяется в реализации pull request-ов в большинстве инструментов, предоставляющих хостинг git-репозиториев.
Несмотря на это, есть несколько проблем в использовании «triple dot» git diff для анализа изменений pull request-а. В реальном проекте основная ветка, скорее всего, будет сильно отличаться от любой ветки функциональности (в дальнейшем feature-ветка). Работа над задачами ведётся в отдельных ветках, которые по окончании вливаются в master. Когда master продвигается вперёд, простой git diff от вершины feature-ветки до её merge base уже недостаточен для отображения настоящего различия между этими ветками: он покажет разницу вершины feature-ветки лишь с одним из предыдущих состояний master.
Ветка master продвигается за счёт вливания новых изменений. Результат git diff master. alice/master не отражает этих изменений master.
Почему же невозможность увидеть эти изменения в ходе анализа pull request-а является проблемой? Тому есть две причины.
Конфликты слияния (merge conflicts)
С первой проблемой вы наверняка регулярно сталкиваетесь — конфликты слияния. Если в вашей feature-ветке вы измените файл, который в то же время был изменён в master, git diff по-прежнему будет отображать только изменения, сделанные вами в feature-ветке. Однако при попытке выполнить git merge вы столкнётесь с ошибкой: git расставит маркеры конфликтов в файлах вашей рабочей копии, поскольку сливаемые ветки имеют противоречивые изменения, — такие, которые git не в состоянии разрешить даже с помощью продвинутых стратегий слияния.
Конфликт слияния
Вряд ли кому-то нравится заниматься разрешением конфликтов слияния, но они являются данностью любой системы контроля версий, — по крайней мере, из тех, которые не поддерживают блокирование на уровне файла (которое, в свою очередь, имеет ряд своих проблем).
Однако конфликты слияния — это меньшая неприятность, с которой вы можете столкнуться при использовании «triple dot» git diff для pull request-ов, по сравнению с другой проблемой: особый тип логического конфликта будет успешно слит, но сможет внести коварную ошибку в кодовую базу.
Логические конфликты, остающиеся незамеченными во время слияния
Если разработчики модифицируют разные части одного и того же файла в разных ветках, появляется вероятность того, что они создадут такой конфликт. В некоторых случаях разные изменения, которые исправно работают по отдельности и отлично сливаются безо всяких конфликтов с точки зрения системы контроля версий, могут внести логическую ошибку в код, будучи применёнными вместе.
Это может произойти различными путями, однако самым распространённым является вариант, когда два разработчика случайно замечают и исправляют одну и ту же ошибку в двух разных ветках. Представьте, что приведённый ниже код на javascript вычисляет стоимость авиабилета:
Здесь содержится очевидная ошибка: автор забыл включить в расчёт таможенный сбор!
Теперь представьте двух разработчиков, Алису и Боба, каждый из которых заметил эту ошибку и исправил её независимо от другого в своей ветке.
Алиса добавила строку для учёта customsFee перед immigrationFee:
Боб сделал аналогичную правку, однако поместил её после immigrationFee:
Поскольку в каждой из этих веток были изменены разные строки кода, слияние обеих с master пройдёт успешно одно за другим. Однако теперь master будет содержать обе добавленные строки, а значит, клиенты будут дважды платить таможенный сбор:
(Это, разумеется, надуманный пример, однако дублированный код или логика могут вызвать весьма серьёзные проблемы: к примеру, дыру в реализации SSL/TLS в iOS.)
Предположим, что вы сначала слили в master изменения pull request-а Алисы. Вот что показал бы pull request Боба, если бы вы использовали «triple dot» git diff:
Поскольку вы анализируете изменения по сравнению с общим предком, нет никакого предупреждения об угрозе ошибки, которая случится, когда вы нажмёте на кнопку слияния.
На самом же деле, при анализе pull request-а вы хотели бы видеть, как master изменится после слияния изменений из ветки Боба:
Здесь явно обозначена проблема. Рецензент pull request-а, будем надеяться, заметит дублированную строчку и уведомит Боба о том, что код нужно доработать, и тем самым предотвратит попадание серьёзной ошибки в master и, в конечном счёте, в готовый продукт.
Таким образом мы решили реализовать показ изменений в pull request-ах в Bitbucket. При просмотре pull request-а вы видите, как на самом деле будет выглядеть результат слияния (т.е. фактически, результирующий коммит). Чтобы осуществить это, мы производим настоящее слияние веток и показываем разницу между получившимся коммитом и верхушкой целевой ветки pull request-а:
git diff C D, где D — это коммит, получившийся в результате слияния, показывает все различия между двумя ветками
Если вам интересно, я разместил одинаковый репозиторий на нескольких хостингах, чтобы вы сами смогли увидеть описанную разницу между алгоритмами сравнения:
Продвижение веток
Во-первых, коммит слияния D на самом деле ещё не существует, а его создание — относительно дорогой процесс. Во-вторых, недостаточно просто создать коммит D и на этом закончить: B и C, родительские коммиты для нашего коммита слияния, могут поменяться в любое время. Мы называем изменение любого из родительских коммитов пересмотром (rescope) pull request-а, поскольку оно, по сути, модифицирует тот набор изменений, который будет применён в результате слияния pull request-а. Если ваш pull request нацелен на нагруженную ветку вроде master, он наверняка пересматривается очень часто.
Коммиты слияния создаются каждый раз, когда любая из веток pull request-а изменяется
Фактически, каждый раз когда кто-то коммитит или сливает pull request в master или feature-ветку, Bitbucket должен создать новый коммит слияния, чтобы показать актуальную разницу между ветками в pull request-е.
Обработка конфликтов слияния
Другая проблема при выполнении слияния для отображения разницы меджу ветками в pull request-е заключается в том, что время от времени вам придётся иметь дело с конфликтами слияния. Поскольку git сервер работает в неинтерактивном режиме, разрешать такие конфликты будет некому. Это ещё больше усложняет задачу, но на деле оказывается преимуществом. В Bitbucket мы действительно включаем маркеры конфликтов в коммит слияния D, а затем помечаем их при отображении разницы между ветками, чтобы явно указать вам на то, что pull request содержит конфликты:
Зелёные строки добавлены, красные — удалены, а жёлтые означают конфликт
Таким образом, мы не только заранее выявляем, что pull request содержит конфликт, но и позволяем рецензентам обсудить, как именно он должен быть разрешён. Поскольку конфликт всегда затрагивает, как минимум, две стороны, мы считаем, что pull request — это лучшее место для нахождения подходящего способа его разрешения.
Несмотря на дополнительную сложность реализации и ресурсоёмкость используемого подхода, я считаю, что выбранный нами в Bitbucket подход предоставляет наиболее точную и практичную разницу между ветками pull request-а.
Автор оригинальной статьи — Тим Петтерсен, участвовал в разработке JIRA, FishEye/Crucible и Stash. С начала 2013 года он рассказывает о процессах разработки, git, непрерывной интеграции и поставке (continuous integration/deployment) и инструментах Atlassian для разработчиков, особенно о Bitbucket. Тим регулярно публикует заметки об этих и других вещах в Twitter под псевдонимом @kannonboy.
Надеюсь, что эта статья оказалась интересной. Буду рад ответить на вопросы и комментарии.
Как сделать свой первый Pull Request
07 Марта 2016 • Михаил Панков • руководства • поддержите на Patreon
Предполагается знание основ системы контроля версий Git. Если вы ещё не работали с Git, мы дадим ссылки на официальную русскоязычную документацию по необходимым командам.
Вам также потребуется аккаунт на GitHub. Регистрация бесплатная и требует указания лишь имени пользователя и электронной почты.
Вот процесс с высоты птичьего полёта.
Работа над задачей закончена!
Теперь рассмотрим каждый этап подробнее.
Форкаем проект
Поэтому мы форкаем проект — это создаст копию репозитория в вашем аккаунте. При этом у вас появится доступ на запись в вашу копию.
Через мгновение вы будете перенаправлены на страницу вашего форка.
Клонируем репозиторий
Затем выполняем команду в терминале ( или командной строке Windows):
Создаём ветку
Теперь заходим в наш склонированный репозиторий и создаём ветку:
Вторая команда создаст ветку и перейдёт на неё ( сделает checkout).
Делаем изменения
Эти изменения мы коммитим в нашу ветку. Как это сделать — ниже.
Если вы уже достаточно разбираетесь в Git, такие не-атомарные изменения потом нужно объединить в один коммит с помощью interactive rebase и squash.
В выводе есть все необходимые вам команды:
Формат сообщения о коммите таков:
В наших проектах нужно использовать Fix #123 или Close #123 на последней строке сообщения коммита.
Проверяем изменения
Создаём Pull Request
Чтобы создать Pull Request, зайдём на страницу вашего форка. Справа от выпадающего меню с выбором ветки есть кнопка « New pull request».
Вы попадаете в окно сравнения веток.
После нажатия кнопки появится окно ввода сообщения Pull Request.
Участвуем в Code Review
Если кто-то ведёт себя неадекватно — не медлите. Сначала сообщите об этом собеседнику и призовите его к благоразумию. Если не сработало — смело обращайтесь к рецензенту или к автору данного текста ( Панкову Михаилу — @mkpankov). Это можно сделать в нашем чате.
Пожелание относительно процесса рецензирования — постарайтесь не сильно затягивать с ответами на комментарии или изменением указанных вещей.
Поздравляем! Теперь вы полноправный участник проекта.
Завершение работы
А теперь можно удалить нашу ветку fix-protobaz локально:










