65

You can use hg grep, but it searches the contents of all files.

What if I just want to search the file names of deleted files to recover one?

I tried hg grep -I <file-name-pattern> <pattern> but this seems to return no results.

Serge Stroobandt
  • 28,495
  • 9
  • 107
  • 102
wsorenson
  • 5,701
  • 6
  • 32
  • 29

6 Answers6

88

using templates is simple:

$ hg log --template "{rev}: {file_dels}\n"
dfa
  • 114,442
  • 31
  • 189
  • 228
  • I hadn't seen this but you can imagine how it is not exactly "quick" when you have a repository with thousands of revisions and thousands of file deletions. – wsorenson Jun 18 '09 at 16:21
  • 6
    A minor tweak to get rid of commits where no deletion happend: hg log --template "{rev}: {file_dels}\n" | grep -v ':\s*$' – Peter Rowell Jun 20 '09 at 22:56
  • 4
    Could someone explain how to use this with grep to find the name of the file you care about, for us newbies? thanks! – Richard Jul 08 '11 at 10:14
  • 2
    This command is really simple. It writes the whole repository log using the provided template. In this case it writes revision number and the deleted filed for each revision - you can use grep to find the needed file. Once you have the revision you can use `hg revert -r 123 path/to/the/file.txt` to recover it. Note that you need to specify a revision prior to the one where you deleted the file! (just substract 1) – johndodo Jan 20 '12 at 10:01
  • 3
    This solution is really slow, if you are a current mercurial, you should go with th revset solution in the other answer. – Lars Noschinski Jan 30 '12 at 09:35
  • It worked really quite fast for me. Do you have a huge repo? What is a "current mercurial"? – occulus Jun 22 '12 at 08:14
  • 1
    @LarsNoschinski: I found the opposite. I found that the revset solution took significantly longer to run when applied to a repository having over 150,000 changesets. See my comments http://stackoverflow.com/questions/1013550/find-deleted-files-in-mercurial-repository-history-quickly#comment37142518_3651395 and http://stackoverflow.com/questions/1013550/find-deleted-files-in-mercurial-repository-history-quickly#comment37142877_3651395. – Derek Mahar Jun 06 '14 at 14:27
54

Update for Mercurial 1.6

You can use revsets for this too:

hg log -r "removes('**')"

(Edit: Note the double * - a single one detects removals from the root of the repository only.)


Edit: As Mathieu Longtin suggests, this can be combined with the template from dfa's answer to show you which files each listed revision removes:

hg log -r "removes('**')" --template "{rev}: {file_dels}\n"

That has the virtue (for machine-readability) of listing one revision per line, but you can make the output prettier for humans by using % to format each item in the list of deletions:

hg log -r "removes('**')" --template "{rev}:\n{file_dels % '{file}\n'}\n"
Community
  • 1
  • 1
anton.burger
  • 5,637
  • 32
  • 48
  • 3
    I'd combine both of those: hg log --template "{rev}: {file_dels}\n" -r "removes('*')". Otherwise, your default hg log template might not show which files were removed. – Mathieu Longtin Mar 17 '12 at 13:22
  • 1
    With a repository of over 150,000 changesets and using Mercurial 2.5.4, I found that `hg log -r "removes('**')"` took significantly longer to find and display the most recently removed files than did `hg log --template "{rev}: {file_dels}\n"`. Does `hg log -r "removes('**')"` search the entire repository history before it generates output? – Derek Mahar Jun 06 '14 at 14:14
  • 1
    By "significantly longer", I meant that I had canceled `hg log -r "removes('**')"` after it had been running for over 12 minutes and had not output a single result. On the other hand, `hg log --template "{rev}: {file_dels}\n"` output its first page of results in under one minute. – Derek Mahar Jun 06 '14 at 14:23
  • @Derek That's a good question, but I don't know the answer. Possibly one for the mailing list? – anton.burger Jun 07 '14 at 14:45
  • Seems one runs in chronological order, and the other in reverse chronological order, so that could explain the observed difference? – Jesse Glick Sep 21 '15 at 14:33
11

If you are using TortoiseHg workbench, a convenient way is to use the revision filter. Just hit ctrl+s, and then type

removes("**/FileYouWantToFind.txt")

**/ indicates that you want to search recursively in your repository. You can use * wildcard in the filename too. You can combine this query with other revision sets using and, or operators.

There is also this Advanced Query Editor: enter image description here

quamrana
  • 37,849
  • 12
  • 53
  • 71
Hope
  • 1,051
  • 13
  • 17
2

I have taken other answers and improved it.

Added "--no-merges". On large project with dev teams, there will lots of merges. --no-merger will filter out the log noise.

Change removes("**") to sort(removes("**"), -rev). For a large project with over 100K changesets, this will get to the latest files removed a lot faster. This reverses the order from starting at rev 0 to start at tip instead.

Added {author} and {desc} to ouput. This will give context as to why the files was removed by displaying the log comment and who did it.

So for my use case, it was hg log --template "File(s) deleted in rev {rev}: {author} \n {desc}\n {file_dels % '\n {file}'}\n\n" -r 'sort(removes("**"), -rev)' --no-merges

Sample output:

File(s) deleted in rev 52363: Ansariel 
 STORM-2141: Fix various inventory floater related issues:
* Opening new inventory via Control-Shift-I shortcut uses legacy and potentinally dangerous code path
* Closing new inventory windows don't release memory
* During shutdown legacy and inoperable code for inventory window cleanup is called
* Remove old and unused inventory legacy code

  indra/newview/llfloaterinventory.cpp
  indra/newview/llfloaterinventory.h

File(s) deleted in rev 51951: Ansariel 
 Remove readme.md file - again...

  README.md

File(s) deleted in rev 51856: Brad Payne (Vir Linden) <vir@lindenlab.com> 
 SL-276 WIP - removed avatar_skeleton_spine_joints.xml

  indra/newview/character/avatar_skeleton_spine_joints.xml

File(s) deleted in rev 51821: Brad Payne (Vir Linden) <vir@lindenlab.com> 
 SL-276 WIP - removed avatar_XXX_orig.xml files.

  indra/newview/character/avatar_lad_orig.xml
  indra/newview/character/avatar_skeleton_orig.xml
1

Search for a specific file you deleted efficiently, and format the result nicely:

hg log --template "File(s) deleted in rev {rev}: {file_dels % '\n  {file}'}\n\n" -r 'removes("**/FileYouWantToFind.txt")'

Sample output:

File(s) deleted in rev 33336: 
  class/WebEngineX/Database/RawSql.php

File(s) deleted in rev 34468: 
  class/PdoPlus/AccessDeniedException.php
  class/PdoPlus/BulkInsert.php
  class/PdoPlus/BulkInsertInfo.php
  class/PdoPlus/CannotAddForeignKeyException.php
  class/PdoPlus/DuplicateEntryException.php
  class/PdoPlus/Escaper.php
  class/PdoPlus/MsPdo.php
  class/PdoPlus/MyPdo.php
  class/PdoPlus/MyPdoException.php
  class/PdoPlus/NoSuchTableException.php
  class/PdoPlus/PdoPlus.php
  class/PdoPlus/PdoPlusException.php
  class/PdoPlus/PdoPlusStatement.php
  class/PdoPlus/RawSql.php
mpen
  • 272,448
  • 266
  • 850
  • 1,236
-2

from project root

hg status . | grep "\!" >> /tmp/filesmissinginrepo.txt
Matt_WOT
  • 9
  • 1
  • 2
  • Doesn't appear to answer the question. I'm cluing on asker's reference to repository history. Your command reports files that have not been deleted from repository, but are missing from the working copy. – Rob I May 11 '16 at 20:34