Find deleted files in Mercurial repository history, quickly?

16,761

Solution 1

using templates is simple:

$ hg log --template "{rev}: {file_dels}\n"

Solution 2

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"

Solution 3

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

Solution 4

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) <[email protected]> 
 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) <[email protected]> 
 SL-276 WIP - removed avatar_XXX_orig.xml files.

  indra/newview/character/avatar_lad_orig.xml
  indra/newview/character/avatar_skeleton_orig.xml
Share:
16,761
pIjIN
Author by

pIjIN

Engineering @HubSpot

Updated on June 25, 2022

Comments

  • pIjIN
    pIjIN about 2 years

    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.

  • pIjIN
    pIjIN about 15 years
    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.
  • Peter Rowell
    Peter Rowell about 15 years
    A minor tweak to get rid of commits where no deletion happend: hg log --template "{rev}: {file_dels}\n" | grep -v ':\s*$'
  • Richard
    Richard almost 13 years
    Could someone explain how to use this with grep to find the name of the file you care about, for us newbies? thanks!
  • johndodo
    johndodo over 12 years
    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)
  • Lars Noschinski
    Lars Noschinski over 12 years
    This solution is really slow, if you are a current mercurial, you should go with th revset solution in the other answer.
  • Mathieu Longtin
    Mathieu Longtin over 12 years
    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.
  • occulus
    occulus about 12 years
    It worked really quite fast for me. Do you have a huge repo? What is a "current mercurial"?
  • Derek Mahar
    Derek Mahar about 10 years
    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
    Derek Mahar about 10 years
    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
    Derek Mahar about 10 years
    @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 stackoverflow.com/questions/1013550/… and stackoverflow.com/questions/1013550/….
  • anton.burger
    anton.burger about 10 years
    @Derek That's a good question, but I don't know the answer. Possibly one for the mailing list?
  • Jesse Glick
    Jesse Glick almost 9 years
    Seems one runs in chronological order, and the other in reverse chronological order, so that could explain the observed difference?
  • Rob I
    Rob I about 8 years
    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.