У меня есть пара фиксаций, которые действительно должны быть только одним. Если бы я использовал git, я бы использовал:
git rebase -i <some-commit-before>
а затем раздавить их.
Могу ли я сделать это в меркуриальном? Если да, то как?
У меня есть пара фиксаций, которые действительно должны быть только одним. Если бы я использовал git, я бы использовал:
git rebase -i <some-commit-before>
а затем раздавить их.
Могу ли я сделать это в меркуриальном? Если да, то как?
Да, вы можете сделать это, используя mercurial без каких-либо расширений, Объединение наборов настроек.
Альтернативно, если вы хотите использовать расширение, которое вы могли бы использовать:
Моя любимая команда hg strip --keep
. И затем я фиксирую все изменения в одном коммите.
Это самый быстрый и удобный способ для меня, потому что мне нравится делать много мелких коммитов во время моей ежедневной работы;)
Примечание 1: strip
необходимо включить встроенное расширение mq
.
Примечание 2: Мой любимый Git/Mercurial клиент (SmartGit/Hg) добавляет по умолчанию параметр --keep
во время strip
. И что еще более удобно: он предоставляет опцию join commits
:]
Расширение Rebase работало как шарм. Для сквоша 2 фиксации:
$ hg rebase --dest .~2 --base . --collapse
Dot - это ярлык для текущей версии.
Это еще проще, когда у вас есть несколько коммитов на ветке и вы хотите свернуть их все в один:
$ hg rebase --dest {destination branch (e.g. master)} --base . --collapse
Как это работает:
(из http://mercurial-scm.org/wiki/RebaseExtension#Collapsing)
Если вы читаете этот ответ, вы можете забыть все остальные опции, упомянутые в этом ответе, и использовать команду
fold
из расширения evolve.
evolve
- это расширение mercurial, которое помогает нам иметь безопасную изменяемую историю, хотя оно все еще экспериментально. Вы можете использовать его путем клонирования его из репозитория и добавления его в.hgrc, как это.
[extensions]
evolve = ~/evolve/hgext/evolve.py
Предполагая, что вы клонировали репозиторий Evolve в своем домашнем каталоге. Теперь тебе пора. Вы также можете обратиться за помощью к hg help fold
.
Вы говорите " fold
чтобы раздавить/сложить линейную цепочку коммитов, которая не нарушена. Сгиб заключается в том, что он создает новый набор изменений, который содержит изменения из всех наборов изменений и помечает все эти коммиты как устаревшие. Вы можете иметь более глубокое представление об этом в документах.
Теперь предположим, что у вас есть следующая история.
a -> b -> c -> d -> e -> f -> g
Вы хотите раздавить e
, f
и g
. Ты можешь сделать
hg up g
hg fold -r e
Результат будет
a -> b -> c -> d -> h
где h
- набор изменений, который содержит изменения из всех трех коммитов e
, f
и g
.
Вы также можете сложить наборы изменений из середины истории, то есть не обязательно выбирать цепочку, включающую подсказку. Предположим, вы хотите сбросить b
, c
и d
. Ты можешь сделать
hg up d
hg fold -r b
hg evolve --all
Это приведет к
a -> i -> j
где i
- это свернутая ревизия b
, c
, d
а j
- такая же ревизия, что и h
. Руководство пользователя Evolve необходимо прочитать.
Предположим, вы хотите раздавить (объединить) 2 последних коммита.
Найти номер ревизии
hg log -G -l 3
Возможный вывод:
@ changeset: 156:a922d923cf6f
| branch: default
| tag: tip
| user: naXa!
| date: Thu Dec 13 15:45:58 2018 +0300
| summary: commit message 3
|
o changeset: 155:5feb73422486
| branch: default
| user: naXa!
| date: Thu Dec 13 15:22:15 2018 +0300
| summary: commit message 2
|
o changeset: 154:2e490482bd75
| branch: default
~ user: naXa!
date: Thu Dec 13 03:28:27 2018 +0300
summary: commit message 1
Ветка мягкого сброса
hg strip --keep -r 155
Подтвердите изменения снова
hg commit -m "new commit message"
strip
требует включения встроенного расширения. Создайте/отредактируйте ~/.hgrc
файл конфигурации со следующим содержимым:
[extensions]
strip =
Я думаю, что chistedit
(встроенный начиная с Mercurial 2.3) наиболее близок к rebase -i
то есть чисто Mercurial (chistedit
- интерактивная версия histedit
). Однажды в histedit команда fold
отображает, чтобы перебазировать карты squash
и roll
чтобы перебазировать fixup
. Посмотрите документы histedit для получения дополнительной информации.
Вот простой пример. Предположим, у вас есть следующее и вы хотите переместить все изменения 1e21c4b1 в предыдущую ревизию и просто сохранить предыдущее сообщение о ревизии.
@ 1e21c4b1 drees tip
| A commit you want to squash
o b4a738a4 drees
| A commit
o 788aa028 drees
| Older stuff
Вы можете запустить hg chistedit -r b4a738a4
чтобы отредактировать историю обратно в b4a738a4. В этом случае вы перемещаете курсор вниз до 1e21c4b1 и нажимаете r
чтобы указать, что вы хотите бросить эту ревизию. Обратите внимание, что порядок в histedit (от самого старого к новейшему) меняется с hg log
(с самого нового на самый старый).
#0 pick 160:b4a738a49916 A commit
#1 ^roll 161:1e21c4b1500c
После выбора ваших изменений вы затем выбираете c
для их фиксации. Результат следующий:
@bfa4a3be совет по сну | Совершить 788aa028 Drees | Старые вещи
Если вы относительно нового для них, того histedit
может быть лучшим выбором, чем chistedit
, поскольку она обеспечивает описания команд в файле histedit для справки. Требуется немного больше редактирования, чтобы установить команды, используя обычное редактирование текста (точно так же, как обычная перебазировка).
Обратите внимание: чтобы использовать histedit
или chistedit
вам нужно добавить histedit
к своим расширениям в вашем ~/.hgrc:
[extensions]
histedit =
Я предложил chistedit
так как он наиболее близок к rebase -i
и работает где-либо в истории. Если вы действительно хотите включить/настроить текущую ревизию в предыдущую, тогда @G. Предложение Демецки strip
может быть хорошим, так как то, что происходит, ясно. Он встроен в Mercuria 2.8. Чтобы получить эквивалентные результаты, как указано выше, вы можете сделать следующее:
hg strip .
hg add
hg commit --amend
Примечание strip
, как histedit, должен быть включен в вашем ~/.hgrc:
[extensions]
strip =
Я использую:
hg phase --draft --force -r 267
...
hg rebase --dest 282 --source 267 --collapse
В Mercurial 4.8 (ноябрь 2018 г., 9 лет спустя) вы могли рассмотреть новую команду hg aborb
(hg aborb
это была экспериментальная функция).
См. " Поглощение изменений коммитов в Mercurial 4.8 "
Расширение поглощение будет принимать каждое изменение в вашем рабочем каталоге, определять, какие коммиты в вашей серии изменили эту строку, и автоматически вносить изменения в этот коммит.
Если есть какая-то неоднозначность (то есть, несколько коммитов, измененных в одной строке), поглощение просто проигнорирует это изменение и оставит его в вашем рабочем каталоге для разрешения вручную.На техническом уровне
hg absorb
находит все незафиксированные изменения и пытается сопоставить каждую измененную строку с однозначным предварительным подтверждением.
Для каждого изменения, которое может быть отображено корректно, незафиксированные изменения включаются в соответствующую предыдущую фиксацию. Коммиты, на которые воздействует операция, автоматически перебазируются.
Если изменение не может быть сопоставлено с однозначной предыдущей фиксацией, оно остается незафиксированным, и пользователи могут вернуться к существующемуhg histedit
процессу (например, с помощьюhg histedit
).Логика автоматического переписывания
hg absorb
путем следования истории строк: это принципиально отличается от подхода,hg histedit
илиgit rebase
, которые склонны полагаться на стратегии слияния, основанные на трехстороннем слиянии, для получения новой версии. файла с учетом нескольких версий ввода.Этот подход в сочетании с тем фактом, что hg поглощение пропускает изменения при неоднозначной фиксации приложения, означает, что hg поглощение никогда не столкнется с конфликтами слияния!
Теперь вы можете подумать, что если вы проигнорируете строки с неоднозначными целями приложения, патч всегда будет применяться чисто, используя классическое трехстороннее слияние. Это утверждение логически звучит правильно. Но это не так:
hg absorb
может избежать конфликтов слияния, когда слияние, выполненноеhg histedit
илиgit rebase -i
завершится неудачно.