Hg: как сделать rebase как git rebase

В Git я могу сделать это:

1. Start working on new feature:
$ git co -b newfeature-123  # (a local feature development branch)
do a few commits (M, N, O)

master A---B---C
                \
newfeature-123   M---N---O

2. Pull new changes from upstream master:
$ git pull
(master updated with ff-commits)

master A---B---C---D---E---F
                \
newfeature-123   M---N---O

3. Rebase off master so that my new feature 
can be developed against the latest upstream changes:
(from newfeature-123)
$ git rebase master

master A---B---C---D---E---F
                            \
newfeature-123               M---N---O


Я хочу знать, как сделать то же самое в Mercurial, и я просмотрел интернет для ответа, но лучшее, что я мог найти, было: git rebase - может hg сделать это

Эта ссылка содержит 2 примера:
1. Я признаю, что это: (заменив ревизии из примера на мой собственный пример)

hg up -C F  
hg branch -f newfeature-123  
hg transplant -a -b newfeature-123 

не так уж плохо, за исключением того, что он оставляет заново M-N-O в качестве незакрепленной головы и создает 3 новые коммиты M ', N', O ', которые представляют собой ветки с обновленной основной линией.

В основном проблема заключается в том, что я получаю следующее:

master A---B---C---D---E---F
                \           \
newfeature-123   \           M'---N'---O'
                  \
newfeature-123     M---N---O

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

  1. Другой вариант из той же ссылки -
hg qimport -r M:O
hg qpop -a
hg up F
hg branch newfeature-123
hg qpush -a
hg qdel -r qbase:qtip

и это приводит к желаемому графику:

master A---B---C---D---E---F
                            \
newfeature-123               M---N---O

но эти команды (все 6 из них!) кажутся намного сложнее, чем

$ git rebase master

Я хочу знать, является ли это единственным эквивалентом в Hg или существует какой-то другой способ, который прост как Git.

Ответ 1

VonC имеет ответ, который вы ищете, расширение Rebase. Тем не менее, стоит потратить секунду или два на размышления о том, почему по умолчанию в mercurial не включены ни mq, ни rebase, потому что mercurial - это все о неизгладимых наборах изменений. Когда я работаю так, как вы описываете, что почти ежедневно, вот образец, который я принимаю:

1. Start working on a new feature:
$ hg clone mainline-repo newfeature-123
do a few commits (M, N, O)

master A---B---C
                \
newfeature-123   M---N---O

2. Pull new changes from upstream mainline:
$ hg pull

master A---B---C---D---E---F
                \
newfeature-123   M---N---O

3. merge master into my clone so that my new feature 
can be developed against the latest upstream changes:
(from newfeature-123)
$ hg merge F

master A---B---C---D---E---F
                \           \
newfeature-123   M---N---O---P

и это действительно все, что необходимо. Я в итоге с newfeature-123 клон, я могу легко вернуться к магистрали, когда я доволен этим. Самое главное, однако, я никогда не менял истории. Кто-то может посмотреть на мои csets и посмотреть, из чего они были изначально закодированы, и как я реагировал на изменения в основной линии на протяжении всей моей работы. Не все думают, что это имеет значение, но я твердо убежден в том, что это задача контроля источника, чтобы показать нам не то, что мы хотели, но то, что на самом деле произошло - каждая ошибка и каждый рефактор должны оставлять неизгладимый след и переустанавливать и другие методы редактирования истории скрывают это.

Теперь перейдите в ответ VonC, пока я не вытащил свою мыльную корзину.:)

Ответ 2

Возможно, вы ищете Rebase Extension. (реализован как часть SummerOfCode 2008)

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

Получение из:

alt text

в

alt text

Ответ 3

Предполагая, что у вас установлена ​​современная установка Hg, вы можете просто добавить:

[extensions]
rebase = 

to ~/.hgrc.

Затем вы можете использовать команды hg rebase, hg pull --rebase или hg help rebase.

Ответ 4

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

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

@  9a4c0eb66429 Feature 3 commit 2 tip feature3
|
| o  af630ccb4a80 default againagainagain  
| |
o |  98bdde5d2185 Feature 3 branch commit 1  feature3
|/
o  e9f850ac41da foo   

Если я нахожусь в ветке feature3 и хочу переустановить его с помощью commit еще раз, я понимаю, что я буду запускать hg rebase -d default. Это имеет следующий результат:

@  89dada24591e Feature 3 commit 2 tip 
|
o  77dcce88786d Feature 3 branch commit 1  
|
o  af630ccb4a80 default againagainagain  
|
o  e9f850ac41da foo  

Миссия выполнена? Я так не думаю. Проблема в том, что когда коммиты на ветке feature3 были переустановлены на reagainagain, ветвь feature3 была удалена. Мои коммиты были перенесены в ветку по умолчанию, чего я пытался избежать в первую очередь.

В Git результат будет выглядеть так:

@  9a4c0eb66429 Feature 3 commit 2 tip
|
o  98bdde5d2185 Feature 3 branch commit 1 **feature3**
|
o  af630ccb4a80 default againagainagain
|
o  e9f850ac41da foo

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

UPDATE. Я обнаружил флаг --keepbranches, поддерживаемый hg rebase, и я рад сообщить, что все это okey-dokey. Используя hg rebase -d default --keepbranches, я точно повторяю поведение Git, которое я жаждал. Несколько псевдонимов позже, и я перестраиваю, как никто другой.

Ответ 5

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

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

Страница x265 contributors объясняет как повторно зафиксировать набор изменений, над которыми вы работаете, чтобы они были готовы к представление в проект x265. (Включая использование TortoiseHG для фиксации некоторых, но не всех изменений в отдельном файле, например git gui stage/unstage diff hunk для фиксации).

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

Я предполагаю, что вы скопировали/вставляли, а затем редактировали сообщения фиксации из предыдущих итераций патч-набора, который вы пересматриваете. Или, может быть, вы можете перенести свои старые коммиты (вишневый выбор на git), а затем поменять их один за другим, чтобы ваши старые сообщения о фиксации стали отправной точкой для редактирования.