How to abandon all Mercurial changes that haven't been committed - mercurial

How do you abandon all repository changes since the last commit in Mercurial?
I don't think that this is the revert command, because that will actually update the working directory to the last commit. I just want to undo changes in the repository (added files, removed files, etc).
But, I'm new with Mercurial, so I could be missing something.

You do want revert. The two commands revert and update are complimentary. They both update the files in your working directory, but update also updates the parent revision (see hg parents) whereas revert doesn't. If your parent revision was tip, which it often is, then either would do in this case, but prefer revert.
Example:
ry4an#hail [~/hg/test] % hg stat
? newfile
? output.patch
? this
ry4an#hail [~/hg/test] % hg add newfile
ry4an#hail [~/hg/test] % hg stat
A newfile
? output.patch
? this
ry4an#hail [~/hg/test] % hg revert --all
forgetting newfile
ry4an#hail [~/hg/test] % hg stat
? newfile
? output.patch
? this

Any changes to your local copy that have not been committed to the repository can be undone with the command:
hg update -C
That is, update clean.

Related

Mercurial HG - How to clean repo from uncomm­itted files and stay in the current changeset?

I am using Mercurial ("HG"), I am trying to Clean the repo from uncomm­itted Changes using :
hg update --clean -R rpeo_path
It will Clean The repo and move to tip ( it will change the changeset )
How can i Clean the repo from uncomm­itted changes and stay in the current Changeset ?
Thanks in advance
The simplest is probably to use hg revert --all.
With no revision specified, revert the specified files or directories
to the contents they had in the parent of the working directory. This
restores the contents of files to an unmodified state...
The --all option will
revert all changes when no arguments given
I solved :
current_changeset = hg id -i
hg update --clean -R repo_path -r current_changeset
Please keep me updated if you have another opinion

hg merge says outstanding uncommitted changes; hg commit says nothing changed -- how to exit the loop?

The problem here is that hg' workflow apparently leads in a circle:
hg pull, get another head
hg merge, get warned of outstanding
uncommitted changes
hg commit -m "pre merge commit", get message
saying nothing changed
go to 2 hg status, see output like the
following:
! #foo.py#
? junk.out
? junk2.out
If foo.py is in your list of .hg-ignore'd files try specifying it explicity on the command line when you commit.
e.g.
hg commit -m "commit message" ./#foo.py
edit: looking more closely at your error: the file has been deleted (! in the status list), but hg hasn't tracked the deletion. You need to tell hg about the deletion using:
hg rm -A ./foo.py
The -A / --after means record the removal after it actually occured

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>

mercurial: including precommit-changed file

On commit to repository I have a hook defined in Mercurial:
[hooks]
precommit.exportDB=exportDB.bat
This creates/updates a SQL-dump from my database, which should be included in the commit.
BUT: although this works, the Sql is marked as new, but not part of the now commiting changeset.
How can I automatically include it so it gets into the set of changed files?
Hope this makes sense...
Thx
Reinhard
This'll sound crazy, but you can do it in two steps. First change your precommit hook to a pre-commit hook -- yup, both exist and they're different. Without the dash the commit has already started and some lock has been acquired. With the dash it happens before the commit starts and you can still hg add the new file.
On a unix like that total change would be:
[hooks]
pre-commit.exportDB=exportDB.sh && hg add resulting.sql
presumably there's something similar on Windows, or you could make the hg add the last line of the batch file.
P.S. Don't commit generated files. :)
Update:
I just tested this and it works as I suggested:
ry4an#four:~$ hg init reinhard
ry4an#four:~$ cd reinhard/
ry4an#four:~/reinhard$ vi .hg/hgrc
ry4an#four:~/reinhard$ cat .hg/hgrc
[hooks]
pre-commit = hg add otherfile
ry4an#four:~/reinhard$ echo text > afile
ry4an#four:~/reinhard$ echo more > otherfile
ry4an#four:~/reinhard$ hg add afile
ry4an#four:~/reinhard$ hg status
A afile
? otherfile
ry4an#four:~/reinhard$ hg commit -m 'message'
ry4an#four:~/reinhard$ hg status --all
C afile
C otherfile
Notice that before the commit only 'afile' is added and 'otherfile' is unknown, and after the commit both files are 'C' (meaning "Clean' -- they've been added and committed).

Undo a remove action in Mercurial

Suppose that I have made some changes in the working directory and accidentally marked several files (that include some of the modified ones) for removal. How do I unmark the files for removal without losing the changes I have made?
Just hg add the files.
I don't know why you're getting some many answers that modify the working directory. If you've accidentally marked some files for removal you can undo it with add.
ry4an#four:~/hgtest$ hg status --all
M another_file
C a_file
ry4an#four:~/hgtest$ hg remove --after --force *
ry4an#four:~/hgtest$ hg status --all
R a_file
R another_file
ry4an#four:~/hgtest$ hg add *
ry4an#four:~/hgtest$ hg status --all
M another_file
C a_file
That said, don't use --force with hg remove or ever really. Also try to get in the habit of using hg forget instead of hg remove --after,
there are two options using hg revert :
hg revert -a
which will go back to the previous revision and put all your changes in new files with .orig appended to the names
hg revert [names of files to unremove] to just revert those files
i'd probably go with the latter
hg revert
I'm pretty sure Mercurial even makes backups of your changes by default.
If the file exists, (likely if you've marked it for removal with hg forget or if you've modified it then hg removed it), do hg add [file] to add it back with any changes made after the last commit and before forgetting the file.
If the file does not exist (likely if the file was unmodified and you've marked the file for removal using hg remove), do hg revert [file] to revert it back to its state in the parent of the working directory.
I had the exact same problem. hg add is the inverse to hg forget (just as the opposite is true). However, attempting to re-add the directory itself did not work. Instead, I had to use hg add on each file:
hg st | egrep "^R" | sed -e "s/R //" | xargs hg add
Hope that helps. Note that in my case, there was nothing I legitimately wanted to remove. If you have files you definitely want to remove, adjust the grep accordingly.
Following your comment to jk, I checked hg forget. It seems to be just a shortcut for hg remove -Af, meaning that this is the real opposite of hg add.
Following that, if you've used hg remove -Af, then you should be able to revert that using hg add (I just tried it and seems to work).
The markers are stored in .hg/dirstate file. All you need to do i to get a one from before issuing hg remove -Af. It may look like this (not tested):
hg clone bad-repo orig-repo
cp orig-repo/.hg/dirstate bad-repo/.hg/dirstate
cd bad-repo
hg status
The last command should show the status from before removing files.
I removed a bunch of unmodified files:
hg remove *
This is what I had to do to get them back:
hg revert --all
Nothing else worked. Not hg add not hg add * nor hg revert *