Интерактивная перебазировка Git не сокращается при наличии быстрой перемотки вперед

#git

#git

Вопрос:

У меня есть ветка от master с тремя изменениями, и я хочу перебазировать ее обратно на master. Например:

 $git checkout master
$git branch dev amp;amp; git checkout dev
$<do 3 commits>
$git checkout master
$git rebase dev -i
  

Обычно — я бы дал мне 3 коммита и позволил мне сквош. Однако в этом случае это просто «noop», и когда перебазирование завершается, я вижу, что три коммита перенесены в master. Я предполагаю, что здесь, хотя, поскольку предок не разошелся, быстрая перемотка вперед была возможна, и вот что произошло. Но я хочу сквошить коммиты.

Я пытался использовать —no-ff, но это делает точно так же, как в моем исходном случае (noop без сжатия).

Я также пытался это сделать (находясь в ветке разработки)

 $git rebase -i HEAD~3
$git checkout master
$git rebase dev
  

Но это действительно боль, и я должен знать, сколько коммитов нужно сжать для части HEAD ~ X.

Примечание: Причина, по которой это важно для меня, заключается в том, что именно этот сжатый набор изменений будет рассмотрен в gerrit. Если они разделены, это делает просмотр невозможным.

Ответ №1:

Я не совсем уверен, почему вы делаете некоторые вещи в своем вопросе, например, вы действительно не имеете в виду $git branch dev amp;amp; git checkout dev , прежде чем выполнять коммиты? В вашей версии вы все равно просто создаете их на master . (Кстати, если я прав, вы можете сделать git checkout -b dev это как короткий путь.)

Причина, по которой вы просто получаете noop, заключается в том, что git rebase пытается повторно применить все коммиты в текущей ветке, которых нет в ветке, которую вы указываете в качестве <upstream> аргумента. Итак, когда вы делаете это git rebase -i dev во время включения master , в нем нет коммитов, master которые не включены dev . По сути, вы хотите сделать это наоборот. Я бы сделал следующее:

 git checkout dev
git rebase -i master
[... change to 'squash' all but the first of the actions ...]
  

Тогда в вашей ветке разработчиков будет только один сжатый коммит, и вы можете объединить его в master, если хотите.

В качестве альтернативы вы могли бы использовать git merge --squash :

 git checkout master
git merge --squash dev
git commit -m "The changes from dev squashed into one commit"
  

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

Комментарии:

1. Ключевым моментом здесь действительно является использование master в качестве основы для перебазирования, а не какой-то специально названный коммит. Даже если мастер слишком далеко назад, вы знаете, что все, что вы могли бы захотеть удалить, сделано с тех пор. (Кроме того, merge --squash по-прежнему не выполняется автоматическая фиксация?)

2. @Jefromi: во всех версиях git, которые я использовал в последнее время, git merge --squash изменения вносятся поэтапно. Раньше такого не было?

3. В документации, добавленной в коммит, который был представлен git merge --squash (7d0c68871a8), также говорится «на самом деле не делать коммит».

4. Тогда неважно! Возможно, это создает сообщение шаблона? Возможно, это то, о чем я думал.

5. Да, вы правы, при оформлении заказа была опечатка. Исправлено сейчас. Приветствую совет checkout -b — новичок в git!