42

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?

Kostas
  • 1,292
  • 1
  • 13
  • 20

8 Answers8

41

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,

Ry4an Brase
  • 78,112
  • 7
  • 148
  • 169
  • Pretty sure this is the right answer - and needs more upvotes to get pushed to the top. – slim Feb 11 '13 at 10:43
  • 10
    Caveat: Doing `hg remove [file]` on an unmodified file removes the file from the filesystem. In this case, `hg add [file]` fails and to add it back you have to do `hg revert [file]`. `hg add [file]` is the correct answer for files that have been modified prior to removal. – dinosaur Oct 28 '14 at 20:15
  • It's true. That's why `hg forget` is always a better option. Leave the deletion to good old (non-mercurial) `rm`. – Ry4an Brase Oct 29 '14 at 04:21
  • **if one uses Eclipse with Mercurial** (e.g. via *MercurialEclipse* plugin) then if you want to **keep the file changes on a file marked for deletion** (due to previous to-be-undone work dir changes / which are not yet committed, but you see a red cross) then using **`Team -> Revert` would restore the old version** of the file and **override your changes**. So you should **backup your changes before doing `Revert`**. *(sorry - found this is the best place to put this info when googleing)* – Andreas Covidiot Jan 25 '15 at 17:59
  • Re-adding after an accidental `hg forget` does not preserve the file history, at least for me it didn't. `hg revert -a` sorted that out and the file history was preserved. – ogggre Jun 05 '23 at 16:21
25

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

jk.
  • 13,817
  • 5
  • 37
  • 50
  • Ok I am aware of revert. Since I used "hg remove -Af" (i.e. remove the files from the repository in the next commit and not from the disk), I was looking for a solution that will just unmark the files so that that stay in the repository. "hg revert" will also replace them with previous versions. I expected there would be a way similar to "hg add"/"hg forget". "hg forget" just unmarks the files marked for addition in the next commit. – Kostas Feb 02 '10 at 12:00
  • AFAIK revert is your only option for un-removing - certainly the help for remove says to see revert for un-removing stuff (while as you say add suggests forget as an oposite). you should get .orig files with your changes in however – jk. Feb 02 '10 at 13:04
  • Seriously. I just want it to drop the "remove" mark from some files I accidentally "forgot." I DO NOT WANT MY FILES MODIFIED. If I accidentally hg add, hg forget undoes it. The reverse is NOT true. If I hg forget a file, no amount of hg add'ing will unmark it. BOOOOOOO TERRIBLE UX. – Michael Blackburn Apr 04 '12 at 20:12
15

hg revert

I'm pretty sure Mercurial even makes backups of your changes by default.

pestilence669
  • 5,698
  • 1
  • 23
  • 35
  • 1
    yes, unless you tell it not to, changes are put in .orig files – jk. Feb 01 '10 at 10:16
  • 1
    I just ran `hg revert` on a file I indirectly removed with `hg mv`. It didn't did **NOT** store my changes, and reverted back to the copy from the last commit. – cesar Sep 23 '11 at 02:43
  • 4
    this is _not_ the right answer. Revert alters the working the directory and this question is about how to undo a "mark for removal" – Ry4an Brase May 11 '12 at 17:09
  • 1
    @Ry4an: I marked files for removal, and `hg revert` worked perfectly to undo that change. – Nic Foster Aug 22 '12 at 21:23
  • 3
    Yeah, but revert misses the "without losing the changes I have made" part. If you've both edited a file, and marked it for removal ("hg forget FILENAME") then revert will undo both of those changes. Just unforgetting them with `hg add` is the better and easier fix. – Ry4an Brase Aug 23 '12 at 14:19
  • As I commented on the "revert -a" suggestion, revert won't do because it modifies the working directory, i.e. it will lose all changes I have made to files and do not want to lose. It looks the 'hg add' is the way to go. – Kostas Oct 08 '12 at 07:39
  • if you already amended the changes, then do `unamend` before doing `revert` and it works! done it few times.. – ThunderWiring Oct 09 '17 at 07:39
6

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.

dinosaur
  • 3,164
  • 4
  • 28
  • 40
  • 1
    This answer is far better than the most voted one, since it explains why and when each command works instead of just giving a recipe away. – Carles Sala Jul 16 '15 at 08:50
4

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.

Nick White
  • 2,063
  • 16
  • 10
3

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).

Ricardo Cárdenes
  • 9,004
  • 1
  • 21
  • 34
2

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.

hegemon
  • 6,614
  • 2
  • 32
  • 30
0

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 *

nettie
  • 628
  • 1
  • 11
  • 23