Есть ли способ удалить локальные коммиты в Mercurial?

209

Поэтому я продолжаю делать глупую ошибку в Mercurial. Часто я начинаю работать без «hg pull» и «hg update». Когда я пытаюсь выдвинуть свои изменения, я получаю сообщение об ошибке.

Есть ли способ удалить мои локальные коммиты, чтобы избежать создания нескольких головок, веток и т. Д.? Я просто хочу удалить свои локальные коммиты, объединить мои изменения с подсказкой, а затем повторно зафиксировать. Звучит просто, правда? Кажется, я не могу найти способ легко удалить локальные коммиты, чтобы я мог слиться с подсказкой.

Опять же, я только пытаюсь удалить локальные коммиты, сделанные с помощью "hg ci". Я не хочу изменять файлы, возвращать и т. Д.

user191535
источник
Возможный дубликат stackoverflow.com/questions/2139165/…
N 1.1
12
Это не глупая ошибка, это обычный рабочий процесс, когда несколько человек работают с одним и тем же хранилищем одновременно.
Юозас Контвайнис

Ответы:

247

Включите расширение « strip » и введите следующее:

hg strip #changeset# --keep

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

Для получения дополнительной информации, проверьте расширение полосы .

Если вы получили «неизвестную команду 'strip'", вам может потребоваться ее включить. Для этого найдите файл .hgrcили Mercurial.iniи добавьте в него следующее:

[extensions]
strip =

Обратите внимание, что (как Юозас упомянул в своем комментарии) наличие нескольких головок - нормальный рабочий процесс в Mercurial. Вы не должны использовать команду полосы, чтобы бороться с этим. Вместо этого вы должны объединить свою голову с входящей головой, разрешить все конфликты, проверить и затем нажать кнопку.

Команда stripполезна, когда вы действительно хотите избавиться от наборов изменений, которые загрязняют ветку. На самом деле, если вы находитесь в ситуации с этим вопросом и хотите полностью удалить все «черновые» наборы изменений , ознакомьтесь с основным ответом , который в основном предлагает сделать следующее:

hg strip 'roots(outgoing())'
Samaursa
источник
8
@Bharath: Вам нужно включить расширение
Самаурса
1
Начиная с Mercurial 2.8, strip - это отдельное расширение, так что strip = все в порядке. WhatsNew для Mercurial 2.8
Чи-Сюань Йен,
104

Если вы используете Hg Tortoise, просто активируйте расширение " strip " в:

  1. Файл / Настройки / Extensions /
  2. Выберите полосу

Затем выберите нижнюю ревизию, с которой вы хотите начать чередование, выполнив right clickее и выбрав:

  1. Изменить историю
  2. полоса

Именно так:

введите описание изображения здесь

В этом примере он будет удален с 19-й ревизии до последней подтвержденной (22).

EliuX
источник
2
File/Settings/Extensions/Я хотел бы добавить больше голосов. Большое спасибо!
дятченко
Argh! Я попробовал это, но, похоже, все мои изменения были сброшены, несмотря на то, что я не отмечал «нет резервной копии» или «отменить локальные изменения». Я хотел сохранить эти изменения, но не совершать их! Есть ли способ восстановить их сейчас ??
Тим Тисдалл
2
Кажется, я не могу найти способ сделать это должным образом, но кажется, что нужно сохранить контент, который вам нужно передать, --keepи TortoiseHg не дает такой возможности. Итак ... вам нужно сделать это в командной строке с hg strip -r . --keep.
Тим Тисдалл
3
from strip help: 'Все удаленные наборы изменений хранятся в ".hg / strip-backup" как пакет (см. "hg help bundle" и "hg help unbundle"). Их можно восстановить, запустив "hg unbundle .hg / strip-backup / BUNDLE", где BUNDLE - это файл пакета, созданный полосой. '
Тим Тисдалл
В SourceTree это тоже было полезно. Спасибо!
Пономаренко Олег
22

Современный ответ (актуален только после Mercurial 2.1):

Используйте Фазы и отметьте ревизию (и), которую вы не хотите передавать как секретную (приватную). Таким образом, когда вы нажимаете, они не будут отправлены.

В TortoiseHG вы можете щелкнуть правой кнопкой мыши на коммите, чтобы изменить его фазу.

Также: Вы также можете использовать расширение «rebase» для перемещения ваших локальных коммитов в заголовок общего репозитория после того, как вы извлекаете.

Том Лейс
источник
Приватный == секретный сейчас
Дмитрий Осиновский
15

Как и все остальные, вы, вероятно, должны просто потянуть и затем объединить головы, но если вы действительно хотите избавиться от ваших коммитов без каких- либо инструментов EditingHistory , то вы можете простоhg clone -r репо, чтобы получить все, кроме этих изменений.

Это не удаляет их из исходного репозитория, но создает новый клон, у которого их нет. Затем вы можете удалить репо, которое вы изменили (если хотите).

Ry4an Brase
источник
"Hg clone -r" удаляет локальные изменения? Я просто хочу удалить локальные коммиты, чтобы все было просто.
user191535
4
Он не удаляет их из клонированного хранилища, но создает новый клон, в котором их нет. Затем вы можете удалить репо, которое вы изменили, если хотите.
Ry4an Brase
9

Я тоже сталкивался с этой проблемой. Я сделал 2 commitи хотел откатить и удалить оба коммита.

$ hg rollback

Но hg rollbackпросто откат до последнего коммита, а не 2 коммитов. В то время я не осознавал этого и изменил код.

Когда я обнаружил, hg rollbackчто только что откатил один коммит, я обнаружил, что могу использовать hg strip #changeset#. Итак, я обычно hg log -l 10находил последние 10 коммитов и получал нужную ревизию, которую хотел strip.

$ hg log -l 10
changeset:   2499:81a7a8f7a5cd
branch:      component_engine
tag:         tip
user:        myname<myname@email.com>
date:        Fri Aug 14 12:22:02 2015 +0800
summary:     get runs from sandbox

changeset:   2498:9e3e1de76127
branch:      component_engine
user:        other_user_name<name@email.com>
date:        Mon Aug 03 09:50:18 2015 +0800
summary:     Set current destination to a copy incoming exchange

......

$ hg strip 2499
abort: local changes found

Что abort: local changes foundзначит? Это означает, что hgнайдены изменения в коде, которые еще не были зафиксированы. Итак, чтобы решить эту проблему, вы должны hg diffсохранить код, который вы изменили и hg revertи hg strip #changeset#. Именно так:

$ hg diff > /PATH/TO/SAVE/YOUR/DIFF/FILE/my.diff
$ hg revert file_you_have_changed
$ hg strip #changeset#

После того, как вы сделали вышеупомянутое, вы можете patchдобавить файл diff и ваш код обратно в ваш проект.

$ patch -p1 < /PATH/TO/SAVE/YOUR/DIFF/FILE/my.diff
GoingMyWay
источник
9

Вы можете обойти это еще проще с расширением Rebase , просто используйте его, hg pull --rebaseи ваши коммиты автоматически перенаправляются на вытащенную ревизию, избегая проблемы ветвления.

слишком много PHP
источник
1
За счет неточной истории и возможной коррупции, если вы делаете что-то не так.
Ry4an Brase
5

Если вы знакомы с git, вы будете рады использовать histedit, который работает как git rebase -i.

нео
источник
4

hg stripэто то, что вы ищете. Это аналогично тому, git resetесли вы знакомы с git.

Используйте консоль:

  1. Вам нужно знать номер ревизии. hg log -l 10, Эта команда показывает последние 10 коммитов. Найдите коммит, который вы ищете. Вам нужен 4-значный номер из строки измененийchangeset: 5888:ba6205914681

  2. Потом hg strip -r 5888 --keep. Это удаляет запись фиксации, но сохраняет все файлы измененными, а затем вы можете повторно их подтвердить. (если вы хотите удалить файлы, просто удалите --keephg strip -r 5888

val.sytch
источник
1

[Черепаха 4.6.1] Если это последнее действие, вы можете использовать действие «Откат / Отмена» (Ctrl + U).

Изображение черепахи HG

Tomas
источник
Дважды проверьте включение изображения.
Билл Келлер
0

В дополнение к превосходному ответу Самаурсы, вы можете использовать evolveрасширения pruneкак безопасную и восстанавливаемую версию strip, которая позволит вам вернуться в случае, если вы делаете что-то не так.

У меня есть эти псевдоним на моем .hgrc:

 # Prunes all draft changesets on the current repository
 reset-tree = prune -r "outgoing() and not obsolete()"
 # *STRIPS* all draft changesets on current repository. This deletes history.
 force-reset-tree = strip 'roots(outgoing())'

Обратите внимание , что pruneтакже --keep, как и strip, чтобы сохранить рабочий каталог нетронутым позволяет подтвердить файлы.

Юлер Борхес
источник