I issued hg qnew without realizing that it includes any outstanding changes into the patch. I'd like to back that out and pick only specific changes using hg qrecord. How can I undo qnew?
Your answer definitely works — with newer Mercurial's you can use hg strip --keep to avoid doing the import step:
$ hg strip --keep .
$ hg qdelete patch-name
The --keep flag makes strip ignore the working copy while working, that is, it deletes the commit (like hg qpop would do) but it doesn't undo the changes to the files. After stripping you still have the patch in your series (unapplied) and you can then delete it.
I've found an anwer here:
hg qpop
hg import --no-commit .hg/patches/patch-name
hg qdelete patch-name
Please add a better way, if you know.
Update: Based on Aldo's answer, there is another way:
hg qnew test
# We can undo the above qnew as:
hg qrefresh -X '*'
hg qpop -f
hg qdelete test
If you just want to undo the latest qnew retaining all your local changes, one option is:
qcrefresh 123
hg qpop -f
hg qdelete <name of the patch>
Notice that 123 is just a random string: you are telling mercurial to only include the (hopefully nonexistsnt) 123 file in the current patch.
Newer versions of Mercurial When you issue will issue a warning about the fact 123 file does not exist, but this is exactly what we want here.
If you want to retain some of the changes in the current path, you can use the qcrefresh command from the crecord extension, which allows to graphically select the changes to be included in the current patch. You need to download it from Bitbucket, extract the archive and configure it in .hgrc:
[extensions]
crecord = <path/to/crecord/package>
Related
This answer shows how you can demote a commit to a patch, but how can I convert an mq patch to local changes only?
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:
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).
I've looked for that in the manual, but I can't generate a patch for the last commit.
I tried
hg qnew patch_name
but it does only file with
# HG changeset patch
# Parent a6a8e225d16ff5970a8926ee8d24272a1c099f9c
I also tried
hg export tip
but it doesn't do anything. I committed the changes exactly.
How to generate a patch file with the last commit in?
The command to do this is export:
$ hg export -o FILE -r REV
It doesn't require redirection and will thus work correctly on any platform/shell.
Your hg export tip is the best way to do it, and the hg diff and hg log based answers are just lesser versions of the same. What exactly do you see/get when you type hg export tip? What does the output of hg log -p -r tip show?
The changeset tip is just means "the changeset that most recently arrived in my repository" which isn't as useful a concept as you might think, since hg pull and hg tag all create changesets too. If you really want the last thing you committed you'll need a more precise revspec.
Like so:
hg diff -r tip > tip.patch
You can use this command:
hg log -r tip -p > tip.patch
this will generate a patch for just that revision.
If you want to convert the latest commit to a patch file, use
hg qimport -r tip
This will replace the topmost regular commit with an applied MQ patch file.
To generate patches using "mq extensions" in mercurial, you can follow the below given steps. This will create a patch using mercurial:
1) Enabling mq extensions: Add the following lines to your hgrc file and save it.
[extensions]
mq =
2) Creating a patch using mq extensions: To create a patch using mq extensions you can do the following.
hg qnew -e -m "comment you want to enter" bug_name.patch
In the above command, -e flag is for editing the patch and -m flag is for adding a message to the patch.
3) Updating the patch: For updating the patch, you can use the following command when a patch is already applied.
hg qrefresh
I have been making some changes to my working directory, and noticed that I have accidentally been working on the wrong branch. I have not committed anything yet, and I would like my next commit to go against another branch. What is the best way to do this?
The Shelve extension can give you grief, and this can be done entirely with Mercurial commands. Krtek almost had it but he used export instead of diff. Try this:
hg diff --git > ~/saved-work.patch
hg update --clean desiredbranch
hg import --no-commit ~/saved-work.patch
You should be able to just hg up otherbranch. It is important that you do not use the --clean option to hg up, either directly or via an alias as that will discard your uncommitted changes.
Another option is to use one of the extensions that provides hg shelve. The process would then be:
$ hg shelve --all
$ hg up otherbranch
$ hg unshelve
That will create a patch of your changes within the .hg directory, returning your working directory to a clean state, switch to the 'otherbranch', and then apply the saved patch.
I don't know if it is the best solution, but you can follow these steps :
1° hg diff --git > modifications.patch
2° hg update -C the_right_branch
3° hg patch modifications.patch
Maybe it's better to copy modifications.patch somewhere safe, just in case.
edit: update with diff instead of export. Thanks to the commenters.
I have a large commit of many files on one branch, I need to transfer the modifications of a single file in that changeset to another branch. How can I do this? I am mostly using TortoiseHg but commandline solutions are also fine.
If I go to the changeset in TortoiseHg and select the file I can see the diffs I want to transfer, but not a way to actually apply them.
You can get the patch for just that file using:
hg log -r THEREVISIONWITHLOTSOFCHANGES -p -I path/to/justthatfile > justthatfile.patch
which you can then import on whatever branch you want by doing:
hg update anotherbranch
hg import --no-commit justthatfile.patch
hg commit
The most basic solution is to dump the patch of the file, apply it to the current working revision, and commit it (assuming you're at the root of the repository):
$ hg up <revision-to-apply-the-patch-to>
$ hg diff -c <revision-containing-the-patch> <files-to-include> | patch -p0
$ hg ci -m "Transplanting selected changes from <revision-contain...>"
The drawback of this method is that it isn't very obvious what you've done from a revision history perspective. A good commit message helps here, but the history graph gives no hint about the process of transplanting some changes. In that case merging and reverting may be a better solution:
$ hg up <revision-to-apply-the-patch-to>
$ hg merge -r <revision-containing-the-patch>
$ hg revert --no-backup <files-to-exclude>
$ hg ci -m "Merge in changes of <files-to-include>"
Probably there are more solutions to do this -- these two came to my mind first.
is this possible with Mercurial? and which Version Control system can do this besides Clearcase?
David is correct that you can't have a branch that exists on only a single file, but it's worth pointing out that people often have branches that alter only a single file. Since the branch metadata is stored in the changeset, and since the changeset contains only a delta (change), having a branch that alters only a single files is nearly instantanous to create, update, commit, and merge, plus it takes up almost no space on disk.
Resultingly, it's a very common way to handle per-customer configurations. Keep the tiny change for them in a branch, and merge from main, where development happened, into that branch, whenever you want to update their deployment.
How you could use MQ:
$ hg qnew -m "Changes for client0" client0
... change the file ...
$ hg qref # update the client0 patch with the changes
$ hg qpop # pop the changes off the queue stack
... develop like normal ...
... client0 asks for a build ...
$ hg qpu # apply client0's patch
$ make release
$ hg qpop
It would get a bit finicky if you've got to deal with a lot of clients… But it may be worth considering.
The other thing you could do, of course, is just commit a bunch of .diff files:
... make changes for client 0 ...
$ hg diff > client0.diff
$ hg revert --all
$ hg add client0.diff
$ hg ci -m "Adding client0 changes"
... develop ...
... client0 asks for a build ...
$ patch -p1 < client0.diff
$ make release
$ hg revert --all
No, it's not possible. A branch in Mercurial is a snapshot of the entire repository state.
You could do it with CVS, though, as CVS tracks changes on a per-file basis :)