Site icon 8HOST.COM

Перемещение и обновление pull-запросов

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

Требования

Перемещение кода и чистка комментариев

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

Команда rebase позволяет перемещать ветки путём изменения коммита, на котором они основаны. С её помощью можно переместить код на последние коммиты ветки master. Перемещать код с помощью rebase нужно очень осторожно, особенно если вы собираетесь опубликовать ветку: эта команда может удалить работу других пользователей. Убедитесь, что вы работаете с правильными коммитами и на правильной ветке проекта, прежде чем начать перемещение.

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

cd repository
git fetch upstream

После этого вы можете очистить комментарии, склеив или переименовав сообщение о коммите (возможно, этого делать не придётся, если вы не создавали множества маленьких коммитов).

Для начала нужно выполнить интерактивное перемещение. Этот процесс позволяет редактировать созданные ранее коммиты, объединять два или несколько коммитов в один, удалять и восстанавливать коммиты. Для этого нужно указать количество коммитов.

Чтобы узнать номера коммитов, созданных вами в этом проекте, введите команду:

git log

Команда вернёт такой результат:

commit 46f196203a16b448bf86e0473246eda1d46d1273
Author: username-2 <email-2>
Date:   Mon Dec 14 07:32:45 2015 -0400
Commit details
commit 66e506853b0366c87f4834bb6b39d941cd034fe3
Author: username1 <email-1>
Date:   Fri Nov 27 20:24:45 2015 -0500
Commit details

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

git log --author=your-username

Если же вы разрабатываете несколько веток, используйте параметр –branches[=<branch>], чтобы выполнить поиск коммитов по веткам.

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

git rebase -i HEAD~x

Если же вы не знаете, сколько коммитов вы сделали в ветке, вам нужно узнать, на каких коммитах основана ветка. Для этого используйте:

git merge-base new-branch master

Эта команда вернёт длинную строку – хэш коммита. Он выглядит примерно так:

66e506853b0366c87f4834bb6b39d341cd094fe9

Вы можете использовать этот хэш в команде:

git rebase -i 66e506853b0366c87f4834bb6b39d341cd094fe9

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

Объединение коммитов

Команда squash позволяет объединить два (и больше) маленьких коммита в один большой.

Перед каждым коммитом в файле вы увидите слово pick:

pick a1f29a6 Adding a new feature
pick 79c0e80 Here is another new feature
# Rebase 66e5068..79c0e80 onto 66e5068 (2 command(s))

Теперь везде, кроме первой строки, слово pick нужно заменить словом squash, чтобы объединить коммиты:

pick a1f29a6 Adding a new feature
squash 79c0e80 Here is another new feature

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

Successfully rebased and updated refs/heads/new-branch.

Переименование коммита

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

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

pick a1f29a6 Adding a new feature
pick 79c0e80 Here is another new feature
# Rebase 66e5068..79c0e80 onto 66e5068 (2 command(s))

Перед каждым коммитом, который вы хотите переписать, замените pick словом reword:

pick a1f29a6 Adding a new feature
reword 79c0e80 Adding a second new feature
# Rebase 66e5068..79c0e80 onto 66e5068 (2 command(s))

Сохраните и закройте файл. После этого в текстовом редакторе откроется изменённое сообщение о коммите. Если вы хотите снова изменить сообщение, вы можете сделать это сейчас, прежде чем сохранить и закрыть новый файл.

Завершение перемещения

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

git rebase upstream/master

После этого Git перенесёт все коммиты на последнюю версию ветки master. Если при этом произошёл конфликт, Git предложит вам несколько вариантов его решения. Выберите один из предложенных вариантов и введите:

git rebase --continue

После этого Git завершит перемещение.

Обновление pull-запроса

После перемещения история ветки будет переписана, и вы больше не сможете использовать команду git push, потому что путь изменится.

Чтобы загрузить изменённую ветку, используйте флаг –force или –f. Так вы сможете сообщить Git о том, что вы знаете обо всех загружаемых изменениях.

Установите значение simple в push.default (по умолчанию в Git 2.0+).

git config --global push.default simple

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

git checkout new-branch
Already on 'new-branch'
. . .

После этого можно запустить force-push:

git push -f

Эта команда обновит pull-запрос.

Восстановление утраченных коммитов

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

Для этого существует команда git reflog, которая находит утраченный коммит и создаёт из него новую ветку.

Reflog – это сокращение от reference logs, так называются логи, которые фиксируют изменения в локальном репозитории.

В локальном репозитории нужно запустить:

git reflog

Команда вернёт:

46f1962 HEAD@{0}: checkout: moving from branch-1 to new-branch
9370d03 HEAD@{1}: commit: code cleanups
a1f29a6 HEAD@{2}: commit: brand new feature
38f2fc2 HEAD@{3}: commit: remove testing methods
. . .

Вы сможете узнать утраченный коммит по тексту. Хэш коммита находится слева, перед HEAD@{x}.

С помощью этой информации вы можете восстановить коммит.

git checkout -b new-new-branch a1f29a6

Эта команда создаст новую ветку на основе третьего коммита.

После этого вы можете создать новый pull-запрос или же снова переместить ветку.

Примечание: Если вы недавно запускали команду git gc, чтобы удалить ненужные файлы и оптимизировать локальный репозиторий, вероятно, вы не сможете восстановить утраченные коммиты.

Проверка кода

Отправляя pull-запрос, вы вступаете в диалог с исходным репозиторием и его владельцем. Другие разработчики смогут рассмотреть вашу работу и решить, стоит ли принимать новые функции в исходный репозиторий проекта. Потому при отправке pull-запроса очень важно чётко объяснить, почему вы создаёте этот запрос и все прилагаемые к нему коммиты.

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

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

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

Очень важно, чтобы ваши коммиты отвечали всем требованиям проекта.

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

Удаление ветки

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

Об этом уже говорилось в предыдущем руководстве (в разделе о синхронизации).

Для этого введите:

git checkout master
git pull --rebase upstream master
git push -f origin master

Теперь нужно очистить локальную и удалённую ветку. Чтобы удалить локальную ветку, введите:

git branch -d new-branch

Флаг –d удаляет указанную в команде ветку.

Примечание: Вместо new-branch нужно ввести название своей ветки.

Чтобы удалить удалённую ветку, введите:

git push origin --delete new-branch

Теперь все разработанные вами изменения находятся только в главном репозитории проекта.

Заключение

Теперь вы знаете, как внести свой вклад в разработку открытого проекта, и умеете отправлять и редактировать pull-запросы.