Могу ли я раздавить коммиты в Mercurial? - PullRequest
103 голосов
/ 13 ноября 2009

У меня есть пара коммитов, которые действительно должны быть только один.Если бы я использовал git, я бы использовал:

git rebase -i <some-commit-before>

, а затем раздавил их.

Могу ли я сделать это в Mercurial?Если да, то как?

Ответы [ 8 ]

85 голосов
/ 13 ноября 2009

Да, вы можете сделать это с помощью Mercurial без каких-либо расширений путем Объединения наборов изменений .

В качестве альтернативы, если вы хотите использовать расширение, вы можете использовать:

39 голосов
/ 22 мая 2014

Моя любимая команда hg strip --keep. И тогда я фиксирую все изменения в одном коммите.

Это самый быстрый и удобный способ для меня, потому что мне нравится делать много небольших коммитов во время моей ежедневной работы;)


Примечание 1: strip необходимо включить встроенное расширение mq.
Примечание 2: Мой любимый клиент Git / Mercurial (SmartGit / Hg) по умолчанию добавляет параметр --keep во время strip. И что еще удобнее: в нем предусмотрена опция join commits:]

31 голосов
/ 23 апреля 2015

Расширение Rebase работает как шарм. Сквош 2 коммитов:

$ hg rebase --dest .~2 --base . --collapse

Точка - это ярлык для текущей версии.

Еще проще, когда у вас есть несколько коммитов на ветке и вы хотите объединить их в один:

$ hg rebase --dest {destination branch (e.g. master)} --base . --collapse

Как это работает:

enter image description here

(из http://mercurial -scm.org / wiki / RebaseExtension # Collapsing )

12 голосов
/ 30 октября 2016

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

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

[extensions]
evolve = ~/evolve/hgext/evolve.py

Предполагая, что вы клонировали Evolve Repo в вашем домашнем каталоге. Теперь вы готовы идти. Вы также можете обратиться за помощью к hg help fold.

Команда 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 необходимо прочитать.

1 голос
/ 27 апреля 2019

В Mercurial 4.8 (ноябрь 2018 г., 9 лет спустя) вы могли рассмотреть новую команду hg aborb (это была экспериментальная функция до ).

См. " Поглощение изменений коммитов в Mercurial 4.8 "

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

На техническом уровне hg absorb находит все незафиксированные изменения и пытается отобразить каждую измененную строку в однозначную предыдущую фиксацию.
Для каждого изменения, которое может быть отображено корректно, незафиксированные изменения включаются в соответствующую предыдущую фиксацию. Коммиты, на которые воздействует операция, автоматически перебазируются.
Если изменение не может быть сопоставлено с однозначной предыдущей фиксацией, оно остается незафиксированным, и пользователи могут вернуться к существующему рабочему процессу (например, используя hg histedit).

Логика автоматического переписывания hg absorb реализована с помощью следования истории строк: это принципиально отличается от подхода, принятого hg histedit или git rebase, который склонен полагаться на стратегии слияния, основанные на Трехстороннее объединение для получения новой версии файла с учетом нескольких входных версий.

Этот подход в сочетании с тем, что hg поглощение пропускает изменения с неоднозначной фиксацией приложения, означает, что hg поглощение никогда не столкнется с конфликтами слияния!

Теперь вы можете подумать, что если вы проигнорируете строки с неоднозначными целями приложения, патч всегда будет применяться чисто, используя классическое трехстороннее слияние. Это утверждение логически звучит правильно. Но это не так: hg absorb может избежать конфликтов слияния, когда слияние, выполненное hg histedit или git rebase -i, завершится неудачей.

0 голосов
/ 13 декабря 2018

Предположим, вы хотите раздавить (объединить) 2 последних коммита.

  1. Найти номер ревизии

    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
    
  2. ветвь мягкого сброса

    hg strip --keep -r 155
    
  3. Повторная фиксация изменений

    hg commit -m "new commit message"
    

Примечания * * 1023 strip требует включения встроенного расширения. Создайте / отредактируйте ~/.hgrc файл конфигурации со следующим содержимым: [extensions] strip =

0 голосов
/ 12 ноября 2018

Я использую:

hg phase --draft --force -r 267
...
hg rebase --dest 282 --source 267 --collapse
0 голосов
/ 14 сентября 2018

Я думаю, 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 =
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...