Со временем, когда git cherry-pickнаучились применять несколько коммитов, различие действительно стало несколько спорным, но это можно назвать конвергентной эволюцией ;-)
Настоящее различие заключается в первоначальном намерении создать оба инструмента:
git rebaseЗадача состоит в том, чтобы перенаправить серию изменений, которые разработчик имеет в своем частном репозитории, созданных для версии X некоторой восходящей ветки, на версию Y той же ветки (Y> X). Это эффективно меняет базу этой серии коммитов, отсюда и "перебазирование".
(Это также позволяет разработчику перенести серию коммитов на любую произвольную фиксацию, но это менее очевидное применение.)
git cherry-pickпредназначен для переноса интересного коммита с одной линии разработки на другую. Классический пример - перенос исправления безопасности, сделанного в нестабильной ветке разработки, в стабильную (обслуживаемую) ветку, где mergeнет смысла, так как это приведет к большому количеству нежелательных изменений.
С момента своего первого появления git cherry-pickон может выбирать сразу несколько коммитов, один за другим.
Следовательно, возможно, наиболее разительное различие между этими двумя командами заключается в том, как они обрабатывают ветку, над которой работают: git cherry-pickобычно приносит фиксацию откуда-то еще и применяет ее поверх вашей текущей ветки, записывая новую фиксацию, в то время как git rebaseберет текущую ветку и перезаписывает серия его собственных советов так или иначе фиксируется. Да, это сильно упрощенное описание того, что git rebaseможно делать, но оно сделано намеренно, чтобы попытаться понять общую идею.
Обновите, чтобы подробнее объяснить git rebaseобсуждаемый пример использования .
Учитывая эту ситуацию,

Книга утверждает:
Однако есть другой способ: вы можете взять патч изменения, который был внесен в C3, и повторно применить его поверх C4. В Git это называется перебазированием. С помощью команды rebase вы можете взять все изменения, которые были зафиксированы в одной ветке, и применить их к другой.
В этом примере вы запустите следующее:
$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command
«Загвоздка» здесь в том, что в этом примере ветвь «эксперимент» (подлежащая перебазированию) изначально была ответвлена от ветки «master», и, следовательно, она разделяет коммиты от C0 до C2 - фактически, «эксперимент» - это master "до C2 включительно плюс коммит C3 поверх него. (Это простейший случай; конечно, «эксперимент» может содержать несколько десятков коммитов поверх своей исходной базы.)
Теперь git rebaseпредлагается переназначить «эксперимент» на текущую вершину «мастера», и он git rebaseвыглядит следующим образом:
- Запускается,
git merge-baseчтобы увидеть, какая последняя фиксация используется как «экспериментальным», так и «главным» (другими словами, в чем смысл отклонения). Это C2.
- Сохраняет все коммиты, сделанные с момента переадресации; в нашем примере с игрушкой это просто C3.
- Перематывает ГОЛОВУ (которая указывает на конец фиксации «эксперимента» перед запуском операции), чтобы указать на вершину «мастера» - мы перемещаемся на него.
- Пытается применить каждый из сохраненных коммитов (как будто с
git apply) по порядку. В нашем примере с игрушкой это всего лишь одна фиксация, C3. Допустим, его приложение произведет фиксацию C3 '.
- Если все прошло успешно, ссылка на «эксперимент» обновляется и указывает на фиксацию, полученную в результате применения последней сохраненной фиксации (в нашем случае C3 ').
А теперь вернемся к вашему вопросу. Как видите, здесь технически git rebase действительно переносится серия коммитов от «эксперимента» до «вершины», так что вы можете с полным правом сказать, что действительно есть «другая ветвь» в процессе. Но суть в том, что фиксация подсказки из «эксперимента» оказалась новой фиксацией подсказки в «эксперименте», она просто изменила свою базу:

Опять же, технически вы можете сказать, что git rebaseздесь включены определенные коммиты от «мастера», и это абсолютно правильно.