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

Есть несколько причин для перебазирования. Мы рассмотрим почему и как из двух часто возникающих ситуаций:

  1. Вы устарели (т. е., вы носите джинсы прямого кроя)
  2. У вас есть отрывочные коммиты, из-за которых вы можете выглядеть идиотом

Мы все были там.

1. Устранение устаревших

Представьте, что вы потратили кучу денег на настройку Dodge Charger 1969 года. Покраска, диски, кузов, декали. И вот однажды вы найдете зарядное устройство «71». Ты любишь это. Вы хотите это вместо этого. Вы бы хотели взять все настройки, которые вы внесли в ‘69, и перенести их на ‘71.

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

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

Перемещение вперед происходит в двух распространенных сценариях наверстывания:

  1. После разработки, чтобы быть в курсе основных обновлений проекта с момента начала разработки.
  2. Когда запрос на вытягивание (PR) некоторое время находится в ожидании проверки и объединения (но будьте осторожны, если кто-то еще зависит от ветки, см. Советы, как не испортить раздел перебазирования ниже)

Перед выполнением перебазирования наша ветка с ее улучшениями или исправлениями ошибок (т.е., фиксирует 1, 2 и 3 ), ответвление от основного проекта в определенный момент времени (т.е., фиксация B). Тот факт, что мы усердно работали над отличными дополнениями к проекту, не означает, что время остановилось. Пока мы работали, сопровождающие добавили коммиты C, D и E в основную ветвь проекта. Теперь мы устарели.

Проблема с устареванием заключается в том, что в C, D и / или E могло быть что-то, что напрямую противоречит тому, что мы делаем в нашей ветке (например, изменяя ту же самую строку кода другим способом) или это не очень хорошо сочетается с нашей веткой (например, функциональность наша ветка зависит от изменилась).

Если мы не перебазируем, мы не заметим конфликта, пока не отправим нашу ветку в виде запроса на вытягивание (PR), и GitHub не пожалуется сообщением выше. Или может не быть конфликтов Git, но автоматизированное тестирование непрерывной интеграции (CI) может дать сбой (например, Travis-CI), потому что наш код плохо сочетается с чем-то новым.

Таким образом, мы должны протестировать наш код поверх последней, самой лучшей версии проекта и не ждать, пока время показа (т.е., PR-отправка) не обнаружится.

Но при условии, что проблем нет, выполнить быстрое перебазирование вперед очень просто. Во-первых, мы убедимся, что все настроено правильно. Затем мы выполним перебазирование.

A. Pre-Fast Forward Rebase Setup (Предварительная перемотка вперед Rebase Setup)

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

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

  1. Разветвил основной проект
  2. Клонировал вилку локально
  3. Сделал ветку под свои изменения
  4. Затем фактически внес изменения
  5. Подтвердил ваши изменения

Для перебазирования нам нужно убедиться, что у нас есть два пульта ДУ: один указывает на нашу вилку, а другой - на основной проект. Команда git remote -v сообщит нам нашу удаленную ситуацию:

$ git remote -v
origin https://github.com/YakDriver/terraform.git (fetch)
origin https://github.com/YakDriver/terraform.git (push)

Здесь у нас есть один пульт с именем origin, который указывает на нашу вилку (т.е., YakDriver следует заменить на ваше имя пользователя GitHub). Если это то, что вы видите, значит, вы в хорошей форме.

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

Теперь добавьте пульт, чтобы указать на основной проект, заменив этот пример URL-адреса Git на URL-адрес проекта, над которым вы работаете. Мы собираемся называть этот пульт upstream, что является условием, но вы могли бы назвать его как-нибудь иначе.

$ git remote add upstream https://github.com/hashicorp/terraform.git

Это все для настройки. Теперь наши пульты должны выглядеть так:

$ git remote -v
origin https://github.com/YakDriver/terraform.git (fetch)
origin https://github.com/YakDriver/terraform.git (push)
upstream https://github.com/hashicorp/terraform.git (fetch)
upstream https://github.com/hashicorp/terraform.git (push)

Б. Выполнение быстрой перебазировки вперед

А теперь собственно перебазирование!

Сначала мы получим последнюю лучшую версию основной ветки (например, master) основного (т.е., общедоступного) проекта / репозитория. Для этого мы переключаемся на основную ветку, а затем pull (т.е., загружаем) самую последнюю и объединяем ее.

ПРЕДУПРЕЖДЕНИЕ. Эта команда перезапишет локальную копию ветки master последней upstream удаленной версией master. Обычно это не проблема, потому что мы указали только нашу ветку, которая не будет затронута. Однако любые локальные фиксации master будут перезаписаны.

Мы могли бы перебазировать на ветку помимо master. Например, некоторые проекты принимают взносы только в ветке develop. В таком случае замените master на develop.

$ git checkout master
$ git pull upstream master
remote: Enumerating objects: 207, done.
remote: Counting objects: 100% (207/207), done.
remote: Compressing objects: 100% (24/24), done.
remote: Total 254 (delta 182), reused 204 (delta 182), pack-reused 47
Receiving objects: 100% (254/254), 160.37 KiB | 14.58 MiB/s, done.
Resolving deltas: 100% (188/188), completed with 121 local objects.
From https://github.com/hashicorp/terraform
* branch                master     -> FETCH_HEAD
bbd4ede96..2eb0bd4bf  master     -> upstream/master
Updating 95e44841a..2eb0bd4bf

Скачав последнюю версию основного проекта, мы готовы переключиться на нашу ветку (т.е., new-branch) и выполнить перебазирование с перемоткой вперед.

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

$ git checkout new-branch
$ git rebase upstream/master
First, rewinding head to replay your work on top of it...
Applying: Fix the bug (commit #1 summary)
Applying: Fix the other bug (commit #2 summary)
Applying: Add documentation (commit #3 summary)

Если же, с другой стороны, перебазирование приводит к одному или нескольким конфликтам, вы увидите что-то вроде этого:

$ git checkout new-branch
$ git rebase upstream/master
First, rewinding head to replay your work on top of it...
Applying: Fix the bug (commit #1 summary)
Using index info to reconstruct a base tree...
M       aws/resource_aws_iam_role.go
Falling back to patching base and 3-way merge...
Auto-merging aws/resource_aws_iam_role.go
CONFLICT (content): Merge conflict in aws/resource_aws_iam_role.go
error: Failed to merge in the changes.
Patch failed at 0001 resource/aws_iam_role: Add exclusive lists of policies to role
hint: Use 'git am --show-current-patch' to see the failed patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

Это не конец света! См. Это руководство по его устранению. В этом руководстве мы предполагаем, что все исправлено. Запустите git rebase --continue, чтобы завершить перебазирование.

На данный момент мы выполнили только локальную перестановку . Мы протестируем наш код локально с последней версией проекта.

После тестирования, чтобы загрузить новую версию ветки на GitHub, мы push ее. Поскольку мы переустановили (т.е., переписали историю), Git будет жаловаться, если мы не принудительно отправим push с помощью -f.

$ git push -f

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

2. Исправление схематичных коммитов

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

Что такое «плохая фиксация»?

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

Нет, плохая фиксация либо банальна, либо плохо описана:

  1. Исправление опечатки (т.е., тривиальная фиксация)
  2. Изменение только интервала (т.е., тривиальная фиксация)
  3. Куча изменений, пытающихся заставить что-то работать (т.е., тривиальные коммиты)
  4. Коммит без хорошего резюме (например, «asdf» или «Изменить оператор if»)

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

Однако, если вы отправляете исправление ошибки или улучшение, изменяете 10 или 100 строк кода, отдельная фиксация для исправления опечатки является тривиальной и не должна быть отдельной фиксацией .

Вот примеры плохих сообщений фиксации:

9b20300 Update index.html
e378862 Update index.html
c351b94 Update index.html
7f9ca48 aaa
55d4902 aadf
4902e37 fffd
ab1ca94 asdf

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

ВНИМАНИЕ! Провал перебазирования может действительно испортить ваш репозиторий и ваш день. Вы переписываете историю - историю, от которой вы зависите, чтобы сохранить всю свою тяжелую работу в безопасности. Следуйте этим советам!

Советы, как не облажаться с перебазированием

  • Никогда не используйте среду IDE для выполнения задач по перебазированию (или Git) за вас. Я усвоил этот урок на собственном горьком опыте. У меня были репозитории, полностью искаженные IDE, работающими с Git. Все гуру Git, которых я знаю и которым доверяю, используют Git из командной строки. Сделай это!
  • Не перебазируйте общедоступные ветки или ветки группы! Выполняя перебазирование, вы переписываете историю ветки. Если кто-то еще зависит от этой истории (например, коллеги или общественность), это может серьезно испортить их ветки. Если вам нужно исправить проблемы в общедоступной или групповой ветке, используйте вместо этого фиксацию.
  • Убедитесь, что ваше рабочее дерево чистое. Перед изменением настроек проверьте git status:
$ git status
On branch my-branch
Your branch is up to date with 'origin/my-branch'.
nothing to commit, working tree clean
  • Работайте над веткой только в одном терминале / окне. Git поддерживает блокировки репозитория и внутреннее состояние, которое может стать несовместимым, если вы изменяете что-то с нескольких терминалов.
  • Не вносите никаких изменений в файлы в своей ветке до завершения переназначения, если вам не нужно, например, исправить конфликт.
  • Обновите Git. Перед тем, как начать перебазирование, убедитесь, что у вас установлена ​​последняя версия. Если вы работаете на Mac, базовая MacOS включает старую версию Git. Вы не должны использовать его ни для чего. Используйте brew install git, чтобы получить последнюю версию. Если вы не уверены, где находитесь, проверьте страницу загрузки Git, чтобы узнать, какая последняя доступная версия, а затем проверьте свою версию:
$ git --version
git version 2.20.1
  • Не бойтесь прервать работу, если вы переусердствуете. Прервите неудачную попытку, узнайте больше, а затем вернитесь и попробуйте еще раз. При отмене все возвращается на круги своя. В этом нет ничего постыдного. Ну может немного.
$ git rebase --abort

Обсудив предупреждения, давайте рассмотрим четыре навыка, связанных с ребазированием, чтобы подготовиться к исправлению плохих коммитов: fixup, amend, squash и reword. Мы рассмотрим, когда и как их использовать.

Базовый навык: исправление

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

Что делает fixup: Git временно добавит fixup фиксацию в вашу ветку, которая исправляет предыдущую фиксацию. Когда мы будем готовы, Git объединит любые fixup коммиты с исходным коммитом. (Да, у вас может быть несколько fixup фиксаций, исправляющих одну фиксацию.)

Fixup реальность: Это должно быть исправление фиксации:

  • Это удобно, потому что вам не нужно возвращаться и пытаться вспомнить, что вы хотели сделать с несколькими коммитами, которые могут или не могут нуждаться в перебазировании (например, какие коммиты я имел в виду, чтобы раздавить? ). В то время как вы вносите изменение, вы регистрируете свое намерение относительно того, что должно произойти и с каким коммитом это должно произойти.
  • Поскольку fixup коммиты будут объединены с исходным коммитом, нам не нужно беспокоиться о крошечных, тривиальных исправлениях, загрязняющих наш журнал коммитов. При желании мы можем разбить процесс исправления на небольшие части. Если мы найдем 10 вещей, которые нужно исправить, мы можем сделать каждую из них fixup, а затем оставить Git, чтобы позже все правильно собрал.

Как исправить

Сначала внесите необходимые изменения и выполните их.

В этом примере предположим, что мы ранее работали над новым усовершенствованием, обеспечивающим функцию критериев поиска или что-то еще. Мы сделали три фиксации: одну для кода, одну для тестов и одну для документации.

После того, как мы сделали эти коммиты, мы заметили небольшую ошибку в коде, которую хотим исправить. Открываем VSCode, исправляем и сохраняем. Теперь, как и в случае с обычным коммитом, мы проведем изменение:

$ git add .

Но пока не совершайте никаких обязательств.

Во-вторых, выясните, какую фиксацию мы исправляем.

Используйте git log, чтобы найти аббревиатуру SHA для рассматриваемой фиксации (т.е., «commit SHA»):

$ git log --oneline
2eb0bd4 Add documentation for new search criteria
e227bbe Updates tests to cover search criteria
920ac5b Add new search criteria feature
7887937 Merge pull request #6893

Мы исправляем проблему в коде, а не в тестах или документах, поэтому смотрим на фиксацию 920ac5b.

В-третьих, зафиксируйте изменение как fixup предыдущую фиксацию.

Мы будем использовать SHA фиксации, найденный на предыдущем шаге в команде фиксации:

$ git commit --fixup 920ac5b

В-четвертых, найдите основание ветви.

Если вы сейчас посмотрите на свой git log, вы увидите нашу новую фиксацию с префиксом fixup!, за которым следует сообщение предыдущей фиксации. Обратите внимание на SHA фиксации, на котором основана наша ветка, или, другими словами, первая публичная фиксация или первая фиксация, которая нам не принадлежит.

$ git log --oneline
335ac23 fixup! Add new search criteria feature
2eb0bd4 Add documentation for new search criteria
e227bbe Updates tests to cover search criteria
920ac5b Add new search criteria feature
7887937 Merge pull request #6893

В нашем примере основой нашей ветки является фиксация 7887937.

В-пятых, переустановите ветку с помощью autosquash .

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

Когда мы закончим все исправления, с помощью одной команды мы можем объединить любые fixup коммиты с их родительскими или родительскими объектами. Обратите внимание на то, что мы используем фиксацию базы ветки:

$ git rebase -i --autosquash 7887937

Перебазирование является интерактивным (-i), что означает, что мы будем быстро перемещаться с Git вперед и назад. После ввода команды Git откроет редактор по умолчанию (например,, vi в MacOS), показывая нам рассматриваемые коммиты. Мы также увидим полезные комментарии, дающие нам возможность выбора.

pick 7887937 Merge pull request #6893
pick 920ac5b Add new search criteria feature
pick e227bbe Updates tests to cover search criteria
pick 2eb0bd4 Add documentation for new search criteria
fixup 335ac23 Add new search criteria feature
# Rebase 7887937..335ac23 onto 7887937 (5 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
...

Однако, поскольку в fixup мы уже проделали работу по выяснению того, что мы делаем, мы можем просто выйти, ничего не меняя (например,, q! в vi). Git выполнит перебазирование и расскажет нам, какие мы классные.

Successfully rebased and updated refs/heads/master.
You are super awesome for using a fixup!

Хорошо. Возможно, я придумал последнюю часть.

Если мы проверим наш git log сейчас, fixup исчезнет, ​​и у нас появятся новые хэши SHA. Изменение, сделанное в fixup, интегрировано в предыдущую фиксацию, которая теперь является фиксацией ae8901a:

$ git log --oneline
34adfe2 Add documentation for new search criteria
24a2ed0 Updates tests to cover search criteria
ae8901a Add new search criteria feature
7887937 Merge pull request #6893

Вуаля!

На этом этапе мы выполнили перебазирование локально. После тестирования, чтобы загрузить обновленную версию на GitHub, мы push ее с -f.

$ git push -f

Навык «Rebase»: изменить

Когда использовать amend: вы знаете, что вам нужно внести изменения в самую последнюю фиксацию.

Что делает amend: Git вносит изменение в самую последнюю фиксацию. В отличие от fixup, он может делать это без необходимости знать SHA фиксации или основание ветки.

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

Amend На самом деле. Внести поправки можно быстро, легко и удобно для ограниченного приложения. Однако внесение поправок также подвержено ошибкам, поскольку мы слепо добавляем изменение к тому, что, по нашему мнению, было самым последним коммитом. Если бы мы добавили фиксацию совсем недавно и забыли, мы могли бы легко изменить неправильную фиксацию. Использование fixup является более точным и менее подверженным проблемам этого типа.

Как сделать поправку

Сначала внесите необходимые изменения и выполните их.

В этом примере, как и в примере fixup, мы ранее поработали над новой функцией критериев поиска улучшений. Мы сделали три коммита: один для кода, один для тестов и один для документации.

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

$ git add .

Во-вторых, мы вносим поправки в коммит.

Изменить фиксацию, особенно когда мы не меняем сообщение фиксации (--no-edit), очень просто:

$ git commit --amend --no-edit
[my-branch 2eb0bd4] Add documentation for new search criteria
Date: Tue Dec 18 17:29:08 2018 -0500
1 file changed, 5 insertions(+), 6 deletions(-)

Вот и все.

Изменение коснулось только нашего локального репозитория . После тестирования мы можем загрузить на GitHub с помощью push. Если мы уже загрузили старую версию фиксации на GitHub, мы push добавим ее в -f.

$ git push -f

Восстановить навык: Сквош

Когда использовать squash: Используйте squash, чтобы объединить одну или несколько фиксаций с предыдущей фиксацией. Мы можем использовать fixup и amend, чтобы исправить существующие коммиты новой работой. Однако, если у нас уже есть все необходимые коммиты, но их нужно объединить, мы будем использовать squash.

Например, если мы добавили новое приветственное сообщение в приложение с опечаткой, а затем добавили фиксацию для исправления опечатки, мы могли бы сжать (т.е., объединить) эти две фиксации вместе. В итоге мы получим одну, правильно написанную фиксацию.

Что squash делает: Git берет существующую фиксацию и объединяет ее с предыдущей фиксацией. Сквоши могут быть объединены в цепочку, что позволяет нам объединить группу коммитов в предыдущую фиксацию.

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

Как делать сквош

Сначала определите, о чем идет речь.

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

Используя git log, мы можем найти коммиты.

$ git log --oneline
12ab32a (HEAD) Add ion cannon enhancement
34adfe2 Fix spelling error in welcome message #2
24a2ed0 Fix spelling error in welcome message
ae8901a Add new welcome message
fea12bc Update unrelated feature

Во-вторых, запросите достаточно давнюю перебазировку.

В журнале мы видим, что самая последняя фиксация, 12ab32a, вверху, не имеет отношения и должна быть оставлена ​​в покое. Этот коммит, даже если он не будет изменен, должен быть изменен, потому что он будет располагаться поверх нового объединенного коммита.

Затем у нас есть два исправления орфографии, 34adfef и 24a2ed0, и фиксация исходного приветственного сообщения, ae8901a. Перед этим есть еще одна фиксация, fea12bc, о которой мы не заботимся.

Мы ведем обратный отсчет до самого раннего коммита, который нас интересует, ae8901a, и используем этот счет, 4, для начала перебазирования в интерактивном режиме (-i).

$ git rebase -i HEAD~4

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

ПРИМЕЧАНИЕ. В этом интерактивном временном файле Git перечисляет самую последнюю фиксацию. Это может сбивать с толку, потому что когда вы делаете git log, самая последняя фиксация будет первой. Также обратите внимание, что Git иногда меняет порядок ваших коммитов, казалось бы, случайным образом. Git может сделать это, потому что так эффективнее применять коммиты, или потому, что ему скучно. Никто не знает точно. Не волнуйтесь, вы можете изменить порядок при необходимости.

pick ae8901a Add new welcome message
pick 24a2ed0 Fix spelling error in welcome message
pick 34adfe2 Fix spelling error in welcome message #2
pick 12ab32a Add ion cannon enhancement
# Rebase ae8901a..12ab32a onto 12ab32a (4 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
...

В-третьих, сообщите Git, что выполняет сжатие.

Поскольку мы хотим превратить третью фиксацию во вторую, а эту фиксацию в первую, мы просто заменяем pick на squash (или букву s) во второй и третьей строках. Помните, что Git собирается объединить фиксацию с фиксацией над ним в этом файле.

pick ae8901a Add new welcome message
squash 24a2ed0 Fix spelling error in welcome message
squash 34adfe2 Fix spelling error in welcome message #2
pick 12ab32a Add ion cannon enhancement
# Rebase ae8901a..12ab32a onto 12ab32a (4 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
...

Сохранить и выйти. Вы должны получить это сообщение.

Successfully rebased and updated refs/heads/master.

ПРИМЕЧАНИЕ. Сообщения, связанные со сдавленными коммитами, выбрасываются, как множество мертвых роз. Обычно это не проблема, но будьте осторожны, если вы привязаны к этим сообщениям.

Если мы проверим git log на этом этапе, мы должны увидеть что-то вроде этого.

$ git log --oneline
113ae33 (HEAD) Add ion cannon enhancement
f45deac Add new welcome message
fea12bc Update unrelated feature

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

На этом этапе мы выполнили перебазирование локально. После тестирования, чтобы загрузить обновленную версию на GitHub, мы push ее с -f.

$ git push -f

Rebase Skill: Reword

Когда использовать reword: используйте это, когда сама фиксация (например, изменение кода или документации) в порядке, но сообщение фиксации (т.е., сводка коммитов) - это плохо.

Что reword делает: изменение формулировки не меняет количество имеющихся у нас коммитов или их содержание. Он изменяет только сообщения фиксации.

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

Как делать пересказ

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

Используйте git log, чтобы найти фиксацию с сообщением, которое нужно переформулировать.

$ git log --oneline
2eb0bd4 (HEAD) Fix name of startup argument
e227bbe Replace the listener with event handler
920ac5b asdf
7887937 Merge pull request #6893

Здесь проблема в фиксации 920ac5b со сводкой фиксации «asdf», которая находится на 3 строки ниже.

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

Перебазирование является интерактивным (-i), что означает, что мы будем быстро перемещаться с Git вперед и назад.

Мы хотим изменить только сообщение для фиксации 920ac5b, но чтобы добраться до него, мы должны включить более поздние фиксации 2eb0bd4 и e227bbe. Эти дополнительные коммиты не будут изменены пересказом, хотя они получат новые SHA фиксации, так как они сидят на новом коммите.

$ git rebase -i HEAD~3

При вводе этой команды откроется редактор по умолчанию (например,, vi в MacOS) с коммитами и полезным разделом комментариев, в котором рассказывается, что мы можем сделать:

pick 920ac5b asdf
pick e227bbe Replace the listener with event handler
pick 2eb0bd4 Fix name of startup argument
# Rebase acf5d51..d7ba331 onto acf5d51 (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
...

Чтобы перефразировать наше сообщение о плохой фиксации, мы меняем pick на reword (или просто r).

reword 920ac5b asdf
pick e227bbe Replace the listener with event handler
pick 2eb0bd4 Fix name of startup argument

Сохраните файл и выйдите (например, используя :wq! в vi). Git откроет новый редактор по умолчанию со старым сообщением о фиксации, которое мы можем редактировать.

asdf
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Tue Dec 18 17:29:08 2018 -0500
...

Используя стандартные команды редактирования, мы редактируем старое сообщение («asdf»), добавляя кое-что полезное о что и почему фиксации.

Update flux capacitor to use Mr. Fusion
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Tue Dec 18 17:29:08 2018 -0500
...

Сохраните и закройте редактор, и Git выполнит перебазирование.

Successfully rebased and updated refs/heads/master.

Если мы проверим git log на этом этапе, мы должны увидеть что-то вроде этого.

$ git log --oneline
823f671 Fix name of startup argument
edc43ba Replace the listener with event handler
ab34cde Update flux capacitor to use Mr. Fusion
7887937 Merge pull request #6893

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

На этом этапе мы выполнили перебазирование локально. После тестирования, чтобы загрузить обновленную версию на GitHub, мы push ее с -f.

$ git push -f

Уф. Удачного ребазинга!