Mercurial - determine where file was removed? - mercurial

If you do hg log myfile -v you see a list of changesets that the file was modified in.
In our case, in the most recent changeset, the file was removed. But you can't tell this by looking at the verbose (-v) output of hg log. Is there an easy Mercurial command you can use to determine if and when a file has been removed from the repo?
Update: Note that this is on a Windows client, and we are using Mercurial v 1.4.3
Update 2: Appears the answers below would work with a more recent version of Mercurial, however an upgrade isn't in the cards right now. Any other ideas for v 1.4.3 ???

You can check which revision deleted a file (any many other interesting features) using revsets:
hg log -r 'removes(<myfile>)'
Some examples:
hg log -r 'removes(build.xml)' // where build.xml used to be in the current directory
hg log -r 'removes("**/build.xml")' // where build.xml may have been in sub directories
See hg help revsets for details.

The --removed flag should get you what you are looking for:
hg log myfile -v --removed
From the help for hg log:
--removed include revisions where files were removed

This is what I use to list all the deleted files in my repository:
hg log --template "{rev}: {file_dels}\n" | grep -v ':\s*$'

Related

Generating patches in Mercurial

I've looked for that in the manual, but I can't generate a patch for the last commit.
I tried
hg qnew patch_name
but it does only file with
# HG changeset patch
# Parent a6a8e225d16ff5970a8926ee8d24272a1c099f9c
I also tried
hg export tip
but it doesn't do anything. I committed the changes exactly.
How to generate a patch file with the last commit in?
The command to do this is export:
$ hg export -o FILE -r REV
It doesn't require redirection and will thus work correctly on any platform/shell.
Your hg export tip is the best way to do it, and the hg diff and hg log based answers are just lesser versions of the same. What exactly do you see/get when you type hg export tip? What does the output of hg log -p -r tip show?
The changeset tip is just means "the changeset that most recently arrived in my repository" which isn't as useful a concept as you might think, since hg pull and hg tag all create changesets too. If you really want the last thing you committed you'll need a more precise revspec.
Like so:
hg diff -r tip > tip.patch
You can use this command:
hg log -r tip -p > tip.patch
this will generate a patch for just that revision.
If you want to convert the latest commit to a patch file, use
hg qimport -r tip
This will replace the topmost regular commit with an applied MQ patch file.
To generate patches using "mq extensions" in mercurial, you can follow the below given steps. This will create a patch using mercurial:
1) Enabling mq extensions: Add the following lines to your hgrc file and save it.
[extensions]
mq =
2) Creating a patch using mq extensions: To create a patch using mq extensions you can do the following.
hg qnew -e -m "comment you want to enter" bug_name.patch
In the above command, -e flag is for editing the patch and -m flag is for adding a message to the patch.
3) Updating the patch: For updating the patch, you can use the following command when a patch is already applied.
hg qrefresh

Mercurial, revert files to a past revision by wildcard?

hg revert -r 4 -I *.aspx
isn't working for me. Any help? And no, I don't want to use TortoiseHG.
Try hg revert -r 4 -I **/*.aspx from the root directory of the repository. The **.aspx matches any file in any subdirectory in the repository whereas *.aspx only matches them in the current directory.
See hg help patterns for more information, which I've just noticed shows a regexp-based alternative:
hg revert re:.*\.aspx$

Mercurial - use hg log to view all ancestors

Given changesets
a
--b
----c
------d
--------e
How can I get a listing of all changesets that come before d. Ie: how can you use hg log to return a-b-c?
Use:
hg log -r "ancestors(d)"
This requires the revsets feature in Mercurial 1.7 and later. See hg help revsets for some great fun.
You can do hg log -r :d (but it will also display d).
hg log -r d::a
or
hg log -r a::d
This will require a reasonably recent (I believe 1.6 or later) version of Mercurial to work.

In Mercurial (hg), how do you see a list of files that will be pushed if an "hg push" is issued?

We can see all the changesets and the files involved using
hg outgoing -v
but the filenames are all scattered in the list of changesets.
Is there a way to just see a list of all the files that will go out if hg push is issued?
First, create a file with this content:
changeset = "{files}"
file = "{file}\n"
Let's say you call it out-style.txt and put it in your home directory. Then you can give this command:
hg -q outgoing --style ~/out-style.txt | sort -u
A somewhat under-appreciated feature: hg status can show information about changes in file status between arbitrary changesets. This can be used to get a list of files changed between revisions X and Y:
hg status --rev X:Y
In this case, we can use hg outgoing, to find the first outgoing changeset X and then do
hg status --rev X:
to see the files changes since revision X. You can combine this into a single line in your shell:
hg status --rev $(hg outgoing -q --template '{node}' -l 1):
I usually use
hg outgoing -v | grep files
It makes the listing shorter, but doesnt sort. But thus far I havent been in a situation where I want to push so much (and at the same time check the files) that its been a problem.
[Edit]
To do what you want:
Use cut to remove the files: part
For changesets with more than one touched file, use tr to put them on separate lines
Finally sort the resulting output with sort
Like so:
hg outgoing -v |grep files: |cut -c 14- |tr ' ' '\n' |sort -u
You can put this in ~/outgoingfiles.sh or something to have it nice and ready.
I use Torgoise Hg, which is a shell extension that has a "synchronize" view allowing you to see outgoing files before you push them. It's convenient for commits as well, and other things.
A simple hg out will also solve this.
It will list all committed but yet to push checkins.

How can I recover a removed file in Mercurial (if at all)?

Accidentally, by using a GUI as opposed to CLI, I removed every file in a Mercurial project.
I recovered with Revert ok and lost some work, which as I have time machine I could easily get back. But is there a way of un-remove/undelete such files? Trawled through the manual and googled but cannot see anything. Any plugins?
I am probably answering my own question here but the files were gone from the directory and were not in the trash to recover so I am assuming Remove is irrevocable?
p.s. I know that hg forget or hg remove -Af will remove without deleting from the directory but my question has to do with the error I made as opposed to cool thinking the action through.
First, use hg grep to find the deleted file you wish to recover. The output of this command will show you the last revision for which the file was present, and the path to the deleted file.
Second, run hg revert -r <revision number> <path to deleted file>
The deleted file will now be in your working copy, ready to be committed back into head.
Quote from comment:
I set up a repository, committed all, Removed and then committed again
If this is the case then you just need to update the working directory to the previous revision:
$ hg update -C -r-2
Note the negative revision number. If the files you deleted aren't in the previous revision, you can find them by using:
$ hg log -v
For Mercurial 1.6 and above
If you know the name of the delete file you can find its revision easily with:
hg log -r "removes('NAME.c')"
This will give you the revision in witch a file called NAME.c (in the root) is deleted.
Then you can revert the file to the previous revision with (like other answers):
hg revert -r <revision number> <path to deleted file>
You can use a file name pattern instead to adapt to what you know, for example you can use **/NAME.c to search in all directories. You can read about it in File Name Patters. And use this link to know about the new revset specifications.
Well this worked for me.
hg revert -r revision pathToTheFile
An addition to the accepted answer - this is faster if you want to undo all removals in a commit. I deleted a large folder with a few hundred files in it and did hg addremove, which was not at all my intent, so had to undo all of those deletes.
Using Find deleted files in Mercurial repository history, quickly? + xargs + tr, revert all revision -3 removals to the version from revision -4:
hg log -r -3 --template "{rev}: {file_dels}\n" | tr ' ' '\n' | xargs hg revert -r -4
Note that this will fail if any of your files have spaces in the name; http://hgbook.red-bean.com/read/customizing-the-output-of-mercurial.html doesn't appear to have any templates where {file_dels} is split by \n at the moment.
You can undo the last commit on a repo with hg rollback. There's only one level of rollback available, so if you did the remove with more than one commit, this won't completely undo your change. This only works on your local repository, so if you've pushed you won't be able to undo it in the remote repo.
You can remove committed revisions using the hg strip command, which is provided by the mq (Mercurial Queues) extension. This should give you back your files.
Make a backup before trying that out, because it will alter Mercurial's database of changesets.
The following worked for me.
hg revert -r <Revision Number> <File Name>
(Optional, to revert all files)
hg revert -r <Revision Number> --all
The below method is straightforward and so stupid that it cannot go wrong.
If you have deleted or renamed multiple files, it will be ok.
hg clone mydirectory mydirectory1
and now you start mc (or Far Manager) and compare what it was vs what it has become.
when it's done, just delete mydirectory1.