Undoing last addremove in Mercurial? - mercurial

I typed
$ hg addremove
but later realized that some of the files should not be part of the commit. What I should have done was to add these files to .hgignore and after that run addremove and commit.
Is there a way of fixing this?

If you have not commited yet just use hg forget fileToForget or use Tortoise to remove the files.
If you have committed and you don't mind the files to be part of history, just forget them and commit again.
If you don't want them to be part of your repository history, and if commiting them is the very last operation you've made, you can try to rollback (use hg rollback or go in the recovery menu in Tortoise). You will have to forget the file and then commit again
If you're dealing with too many files, you can try to automate the task by getting a list of all added files, forgetting them, modify you .hgignore and do the addremove again.
Example of the first step in powershell with no commit made
hg status --added --no-status | foreach-object {hg forget $_};

To undo an addremove you did not commit yet simply run:
$ hg revert --all

Related

Remove file from a commit in Mercurial

I have a commit onto which I have amended some files. Some of these files that were part of the amend I do not want in this commit. Is there a way in Mercurial to remove certain files from the commit without losing the changes I have made to them? Thank you.
Steps:
Made some changes
hg commit -m
Made some more changes (some of these file accidentally amended)
hg amend
Try out:
hg forget somefile.txt
hg commit --amend
If the file was new (i.e. you had used hg add).
If that file already existed try:
cp somefile.txt somefile.txt.bak
hg revert somefile.txt --rev .~1
hg commit --amend
Which is basically telling mercurial to revert the file (somefile.txt) back to the state it was one revision ago (--rev .~1).
Just make sure to back up the file you are reverting before entering the command so that you do not lose your changes. I was under the impression mercurial does this automatically for you, but after testing it quickly I'm not so sure.
hg uncommit somefile.txt does exactly this for me.
Like plain git reset, it removes the change from the commit but leaves the file contents unchanged, so now hg diff shows the change you just uncommitted.
The uncommit command claims to come from the uncommit extension, but may actually be coming from the evolve extension, I admit I'm not 100% sure!

Undoing a revert in mercurial (not a duplicate query)

I have a mercurial repo with no uncommitted changes. I was on revision 846, and decided my last 2 commits were junk and wanted to carry on as if from revision 844. So I was going to type:
hg revert -r 844 --all
Unfortunately I mistyped, and wrote:
hg revert -r 44 --all
So my whole repository has changed dramatically, including directory structure. I don't see any .orig files, so I don't think the answer in:
How to undo a revert in mercurial
helps me.
hg log still has all of my commits up to revision 846 - do you think I can revert back to revision 846?
Advice very welcome
hg revert just sets your working copy to the revision that you specify so if you didn't do a commit after the revert then your repository has not changed. To fix it you can just do hg update -C and then delete all the .orig files.
After that you can do the correct revert statement to remove the last two revisions.
If you did do the commit then the command that you wanted to do (hg revert -r 844 --all) would still get you to the point that you want by undoing the revert commit as well as the two commits that you originally intended to undo.

Empty commit with Mercurial

Is it possible to do a commit without any changes in the current repository with Mercurial, like git's --allow-empty?
Trick I read somewhere:
touch tmp
hg add tmp
hg commit -m "tmp"
hg rm tmp
hg commit --amend -m "Real commit message"
Unfortunately it doesn't survive rebasing (and maybe other operations).
The answer from #Thomas above is correct but doesn't fully explain how to modify the file content of a commit.
A simple method to use this feature to force an commit empty is as follows:
Add a new file (say, Dummy.txt) and commit.
hg forget Dummy.txt
hg commit --amend
This will remove Dummy.txt from the previous commit, leaving it empty.
With amend you can change the user, date, commit message and files content:
hg commit -m"new message" -d"$(date --rfc-2822)" -u"new user" --amend
These are probably all the reasons why you would want to commit an empty changeset.

How to undo "hg qnew"?

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>

hg remove directory from repo?

I'd like to remove a directory and all the files in it from a repo.
I have removed all the files with hg remove, but how do I remove the directory itself?
Will it just automatically vanish once I commit all the removed files?
Yes. Because mercurial doesn't track directories at all, only files, it only creates directories that have files in them, and if someone hg updates to a revision any directories that become empty are automatically removed. So if you do:
hg remove directory/*
hg commit -m 'removed all files in directory'
hg update -r 0 # updates to a different revision
hg update tip # jump back to the tip
That last update would remove the directory. For everyone else it's even easier. When they hg update to your new changes their directory will just vanish (provided they have no uncommitted file in it).
hg remove dir
If you end up with empty directories and you want to get rid of them, an easy way is the purge extension. (add purge= under the [extensions] group in your .hrgc file to unlock).
You can then use
hg purge
to clean up the empty dirs... You must be careful with the purge command as it removes everything that is untracked in your repos. I strongly suggest you run a
hg purge -p
beforehand to see what the command will do ( -p will print a "test run" without doing anything.) Never forget the --help option! ;)
edit: I prefer using purge to hg update in succession as updating triggers rebuilds in my IDE if it is open (and it's a good bet it is when I do that). hg purge will probably be smoother. And you can use --all to include ignored files too (must be careful though).
To remove a directory, Just do
hg remove <dir>
hg commit -m "..."
This will remove the directory and all files under it.