18

This answer shows how you can demote a commit to a patch, but how can I convert an mq patch to local changes only?

Community
  • 1
  • 1
Lstor
  • 2,265
  • 17
  • 25
  • Sorry, but mq-patch **is** already "local changes only", AFAIK. Why do you want something more? – Lazy Badger Nov 20 '12 at 15:21
  • 4
    'Local changes' is Mercurial terminology for changes that are not in a changeset or tracked by a Mercurial patch. There can be several reasons for wanting to convert a patch back into local changes. Anyway, I've needed to do this several times and didn't find the answer on Stack Overflow nor through googling (I had to RTFM), so I shared the answer when I found it in case others want to do the same. – Lstor Nov 20 '12 at 19:32

2 Answers2

25

Short answer

Make sure the patch is applied, then:

hg qrefresh nothing
hg qpop --keep-changes
hg qdelete "Name of patch"

Long answer

First, you need to make sure no changes are tracked by the patch. To do that, use

hg qrefresh nothing

nothing is just a random file name that is not in the repository. I usually use hg qref 0 for brevity. hg qrefresh accepts an optional file pattern. If it is given, the patch will track the changes that match the pattern - and only those. When nothing matches the file pattern, no changes will be tracked by the patch, and thus there will be local changes only.

Now you have a useless patch lying around, and you have some local changes. To clean up, you can do

hg qpop --keep-changes

to pop the patch even though there are local changes. Finally, to remove the dead, empty and unapplied patch you can use

hg qrm "Name of patch"

You can't remove an applied patch, which is why you need the hg qpop --keep-changes step.

(Note: hg qrm and hg qremove are aliases of hg qdelete.)

If using TortoiseHg

With TortoiseHg, exporting the patch to the clipboard (Workbench > right-click the patch > Export > Copy Patch), then unapplying the patch, and finally importing from the clipboard with the destination being "Working Directory" seems to work. Here are some screen captures demonstrating this procedure: enter image description here

duplode
  • 33,731
  • 7
  • 79
  • 150
Lstor
  • 2,265
  • 17
  • 25
  • 3
    `--keep-changes` is no longer a valid option for `hg qpop`. According to `hg help qpop`, it seems `--force` is now the option that acheives what we want here: "-f --force forget any local changes to patched files" – sjbx Feb 19 '13 at 10:46
  • `hg qrefresh 0` fails with 'The system cannot find the file specified.' The alternative I've found (powershell syntax): `hg qrefresh --exclude "$(hg root)"`. This tells MQ to exclude everything in the repository. For whatever reason, just `.` didn't work, and I had to specify the full path (therefore, `hg root`). – moswald Aug 18 '13 at 14:51
  • @CraftyThumber I still see `--keep-changes`, and AFAICT `--force` will lose the changes we're trying to save. – moswald Aug 18 '13 at 14:56
  • I'd use @duplode's option since it is easier and does not use `--keep-changes` or `--force`. That being said, before I saw that I just successfully ran `hg qpop -f` with Mercurial version 2.0.2 and I still have my local changes, but I first confirmed none of the files were exactly identical names and ran `rsync -av $(hg st -qn) /tmp/` so I have a backup. Definitely back up your files if you are unsure! – sage Jun 16 '16 at 03:43
7

An arguably simpler alternative:

hg qfinish qtip
hg strip -k tip

That is, finish the patch and then remove the resulting commit while retaining its changes (the -k option to strip).

duplode
  • 33,731
  • 7
  • 79
  • 150