It sometimes happens in my workflow that I need to hotfix some things remotely, and in order to make those changes adhere to guidelines before pushing into mainline, I'd like to "finalize" them locally. But after I pull the commits back to local repo those changes are in public phase and MQ doesn't play well with that. Steps to reproduce (copy-and-paste-into-terminal-friendly): # 1 Initialize repo1 # ================== hg init repo1 echo foobar >> repo1/file.txt hg --cwd repo1 ci -m 'initial commit' --addremove --config ui.username=foo # 2 Clone repo1 to repo2 and make some modifications there # ======================================================== hg clone repo1 repo2 echo barbaz >> repo2/file.txt hg --cwd repo2 ci -m 'hotfix #1' --addremove --config ui.username=foo echo quxquux >> repo2/file.txt hg --cwd repo2 ci -m 'hotfix #2' --addremove --config ui.username=foo # 3 Propagate changes back to repo1 # ================================= hg --cwd repo1 pull ../repo2 # 4 Try to alter incoming changes # =============================== cd repo1 hg glog hg qimp -r 1:2 # The last command from above fails (explicably) with: # abort: revision 2 is not mutable # (see "hg help phases" for details) # 5 Ok, we know that r2 isn't really public, let's try to convince mercurial # ========================================================================== hg phase --draft --force -r2 hg qimp -r 1:2 # Oh, forgot about another mutable revision: # abort: revision 1 is not mutable # (see "hg help phases" for details) # Let's fix that too: hg phase --draft --force -r1 # 6 No more public revisions, everything should be fine now, let's try again # ========================================================================== hg qimp -r 1:2 # Failure: # abort: patch "2.diff" already exists # 7 Whoops, MQ is inconsistent state: 2.diff was imported, but series is empty # ============================================================================ ls .hg/patches/ hg qseries # 8 Let's fix that # ================ rm .hg/patches/2.diff # 9 Ok, it finally works # ====================== hg qimp -r 1:2 ls .hg/patches/ hg qseries
looks like mq has no concept of atomatic patch import.
So the issue is that an aborted qimport -r leaves a patch that interferes with a future qimport -r. So aborting a qimport -r should clean up any patches it created (but not patches it didn't create).
I have reproduced the bug in another way. I have this at the repo tip: @ changeset: 1108 | o changeset: 1107 | o changeset: 1106 |\ | | | | I have tried importing 1106 into MQ, with no success as it is a merge changeset. Afterwards, I have tried importing 1107 into MQ, but failed due to a 1107.diff already existing in the queue. So if it creates some diffs and then fails for any reason, it doesn't import what already processed but also do not delete the diffs. You could say importing is atomic (all or none are imported) but the intermediate, non imported diffs are not deleted if necessary.
Fixed by http://selenic.com/repo/hg/rev/fd7839d1107d Matt Mackall <mpm@selenic.com> qimport: record imported revs incrementally (issue3874) When an import fails, this doesn't lose the state for the earlier revisions. (please test the fix)