Hg: Как сделать ребаз, например, git's rebase - PullRequest
207 голосов
/ 20 апреля 2010

В 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.

Ответы [ 5 ]

233 голосов
/ 20 апреля 2010

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

102 голосов
/ 20 апреля 2010

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

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

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

alt text

до:

alt text


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

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

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

(--keepbranches: наследовать исходное имя ветви.)

Мойца упоминает:

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

Как показано ниже от Джонатан Блэкберн :

 hg rebase -d default --keepbranches
44 голосов
/ 20 апреля 2010

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

[extensions]
rebase = 

до ~ / .hgrc.

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

21 голосов
/ 19 апреля 2013

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

Допустим, я начинаю с этого графа (созданного с использованием расширения 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, которое я жаждал. Пару псевдонимов позже, и я отказываюсь, как никто другой.

3 голосов
/ 15 декабря 2014

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

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

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

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

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

...