Hg: Как сделать ребаз, например, git's rebase

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

1. Начните работать над новой функцией:
$ git co -b newfeature-123  # (локальная ветка разработки функций)
сделать несколько коммитов (M, N, O)

мастер A --- B --- C
                \
newfeature-123 M --- N --- O

2. Вытащите новые изменения из основной ветки разработки:
$ git pull
(мастер обновлен с помощью ff-commits)

мастер A---B---C---D---E---F
                \
newfeature-123   M---N---O

3. Перебазировать мастер, чтобы моя новая функция 
могут быть разработаны с учетом последних изменений в основной ветке разработки:
(из newfeature-123)
$ git rebase master

мастер A --- B --- C --- D --- E --- F
                            \
newfeature-123 M --- N --- O


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

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

hg up -CF  
hg branch -f newfeature-123  
трансплантация ртути -a -b newfeature-123 

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

В основном проблема в том, что я в конечном итоге с этим:

мастер 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 до F  
hg ветка newfeature-123
hg qpush -a
hg qdel -r qbase:qtip

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

мастер A --- B --- C --- D --- E --- F
                            \
newfeature-123 M --- N --- O

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

$ git rebase master

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

5 ответов

Решение

У VonC есть ответ, который вы ищете, Rebase Extension. Однако стоит потратить секунду или две на размышления о том, почему ни mq, ни rebase не включены по умолчанию в mercurial: потому что 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, пока я убираю свою мыльницу.:)

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

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

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

альтернативный текст

чтобы:

альтернативный текст


Как прокомментировал ниже steprobe:

Если вы не вносите изменения и у вас есть две ветви в репо, вы можете сделать это ( используяkeepbranches):

hg up newfeature-123 
hg rebase -d master --keepbranches

(--keepbranches: Наследовать оригинальное название ветки.)

Mojca упоминает:

Мне нравится использовать hg rebase --source {L1's-sha} --dest {R2's-sha}, но я не знал, что могу добавить --keepbranches в конце.

Как показано ниже Jonathan Blackburn:

 hg rebase -d default --keepbranches

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

[extensions]
rebase = 

до ~/.hgrc.

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

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

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

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

Если я нахожусь в ветке feature3 и хочу перебазировать ее из коммита снова, я понимаю, что я бы запустил 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 были снова перезагружены снова, ветка 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 и по умолчанию не видны. Без сохранения ветви задачи я не вижу, как это функционально отличается от слияния.

ОБНОВЛЕНИЕ: я обнаружил --keepbranches флаг поддерживается hg rebase, и я рад сообщить, что все в порядке. С помощью hg rebase -d default --keepbranchesЯ точно повторяю поведение Git, которое я жаждал. Пару псевдонимов позже, и я перебираю, как никто другой.

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

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

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

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

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

Другие вопросы по тегам