I am using mercurial for version control of a few files in a directory. Suppose I have 10 commits (10 changesets or revisions). I want to just view how a particular file, say thisFile.py, looked in its 7th revision. I don't want to revert back to this older version. I don't want to go and make any changes or fix any bugs in this previous version. I simply want to see it, without affecting the latest version of the file or the mercurial history in any way. Is there a simple way to do it?
Use the hg cat command with the -r (revision) argument.
hg cat path_to/myfile.cpp -r 46
where 46 is the revision number (use hg log to see revision history)
hg cat [OPTION]... FILE...
Print the specified files as they were at the given revision.
If no revision is given, the parent of the working directory is used,
or tip if no revision is checked out.
Output may be to a file, in which case the name of the file is given
using a format string. The formatting rules are the same as for the
export command, with the following additions:
%s: basename of file being printed
%d: dirname of file being printed, or '.' if in repository root
%p: root-relative path name of file being printed
Returns 0 on success.
options:
-o, --output print output to file with formatted name
-r, --rev print the given revision
--decode apply any matching decode filter
-I, --include include names matching the given patterns
-X, --exclude exclude names matching the given patterns
To extract a specific revision of a specific file you can do this in Windows:
hg cat "<FileToBeExtractedPath>" -r 9 > "<ExtractionPath>"
Here, 9 is the revision number.
Or even better:
hg cat "<FileToBeExtractedPath>" -r 9 -o "<ExtractionPath>"
Related
I am trying to find a list of source files that have not been modified for the past few years.
This is one aspect I am trying to measure to try to help us understand the amount of stability and change in a given project over time.
Is there any way in mercurial to identify the files that have not been modified since a given revision?
There is some ambiguity in the question, but it can probably be answered using the status (st) command. For example, to obtain a listing based on a comparison of the files at revision R with those in the pwd, you could run:
hg st --rev R -cn
The -c option is equivalent to "--clean" (meaning in effect "no change").
To compare the files at revision R with those in the most recent commit:
hg st --rev R:-1 -cn
There are many ways to specify "R", e.g. 0 for the initial commit.
Posting my own answer.
I cloned the repository twice into new directories.
Then updated one to the current version and one to the original baseline revsion
hg update <rev>
Then used the diff command to find files that were identical (excluding whitespace changes)
diff -sqrbwB original current | grep "identical"
The diff flags are as follows:
-s reports identical files (facilitating the grep for "identical")
-q brief report (don't need a detailed report of differences)
-r recursively follow directories
-b ignore space changes
-w ignore all space
-B ignore Blank lines
Not sure if -b -w and -B are all necessary but it worked and output a list of files that have not chaged.
Given a file name, how can I query Mercurial for the revision of the change set which introduced this file?
You want to work with revsets!
hg log -r "adds(filename.ext)"
The description from the help:
"adds(pattern)":
Changesets that add a file matching pattern.
The pattern without explicit kind like "glob:" is expected to be relative to the current directory and match against a file or a directory.
This should work:
hg log -r : -l 1 filepath
hg log -r : prints the history in reverse order, the -l 1 switch limits the changes displayed to the first one.
To somewhat elaborate on the title question, is there a way to have Mercurial search through the repository history for a particular version of a given file, and show all of the revisions (or just the most recent one) that contain that version?
For example, let's say that the current working revision is, say, 300 and a file was reverted to an earlier version (say, revision 200). I don't know this - all I can easily see is "how different" the new file is from the 300 version. How can I find out all of the possible revisions that it could have been reverted to?
And if Mercurial cannot do this natively, is there another tool that can? (TortoiseHG?)
I don't think this is possible with any of hg's built-in functionality, but you can get something like it with judicious xargs and md5sum application:
hg log --template "{rev}\\n" | xargs -I "{}" /bin/bash -c 'echo $(hg cat -r {} <filename> | md5sum) {}'
This will give you a list of md5 checksums with the revision number, which when you sort it will give you the revisions sharing versions of the file.
I have a Mercurial repository with ~800 changesets and I need to find the first changeset where the word Example appeared. The word appears inside a .php file and not on a commit comment etc.
What is the quickest/easiest way to do that?
try hg grep Example *.php
hg grep [OPTION]... PATTERN [FILE]...
search for a pattern in specified files and revisions
Search revisions of files for a regular expression.
This command behaves differently than Unix grep. It only
accepts Python/Perl regexps. It searches repository
history, not the working directory. It always prints the
revision number in which a match appears.
By default, grep only prints output for the first
revision of a file in which it finds a match. To get it
to print every revision that contains a change in match
status ("-" for a match that becomes a non-match, or "+"
for a non-match that becomes a match), use the --all
flag.
options:
-0 --print0 end fields with NUL
--all print all revisions that match
-f --follow follow changeset history, or file
history across copies and renames
-i --ignore-case ignore case when matching
-l --files-with-matches print only filenames and revisions
that match
-n --line-number print matching line numbers
-r --rev search in given revision range
-u --user list the author (long with -v)
-d --date list the date (short with -q)
-I --include include names matching the given
patterns
-X --exclude exclude names matching the given
patterns
use "hg -v help grep" to show global options
The selected answer is incomplete:
hg grep --all --files-with-matches 'PATTERN' [FILES]
is normally what you want.
You would want to use the --diff (--all is deprecated) flag of hg grep. It searches the diffs rather than file contents itself, what this would result in is, you would get all the changesets/revisions where the word Example appeared or removed.
Now to get the first hit you need to pass this in revlog order via the -r flag. That is the revisions will be searched from 0 to tip. ( -r 0:tip )
And for the .php files you would want to pass -I flag which is for file name patterns.
So your command will be :
hg grep --all -r 0:tip "Example" -I "*.php"
hg help filesets
...
"grep(regex)"
File contains the given regular expression.
hg locate "set:grep(Example) and **.php"
or
hg locate "set:**.php and (**Example*)"
I have a couple branches that I need to merge, but I don't know where some of the changes are coming from that are showing up in my merge tool. The change sets of local and other are obvious, but how can I find out which change set the base file came from? I'm working in a repository with dozens of branches, so viewing the graph and tracking it doesn't work very well.
Using revsets (Mercurial 1.6 and later), you can get the common ancestor of two changesets with:
hg log -r ancestor(rev1,rev2)
Try the hg grep command:
hg grep [OPTION]... PATTERN [FILE]...
search for a pattern in specified files and revisions
Search revisions of files for a regular expression.
This command behaves differently than Unix grep. It only accepts
Python/Perl regexps. It searches repository history, not the working
directory. It always prints the revision number in which a match appears.
By default, grep only prints output for the first revision of a file in
which it finds a match. To get it to print every revision that contains a
change in match status ("-" for a match that becomes a non-match, or "+"
for a non-match that becomes a match), use the --all flag.
Returns 0 if a match is found, 1 otherwise.
options:
-0 --print0 end fields with NUL
--all print all revisions that match
-f --follow follow changeset history, or file history across
copies and renames
-i --ignore-case ignore case when matching
-l --files-with-matches print only filenames and revisions that match
-n --line-number print matching line numbers
-r --rev REV [+] only search files changed within revision range
-u --user list the author (long with -v)
-d --date list the date (short with -q)
-I --include PATTERN [+] include names matching the given patterns
-X --exclude PATTERN [+] exclude names matching the given patterns
--mq operate on patch repository
[+] marked option can be specified multiple times
use "hg -v help grep" to show global options
You can use it like:
hg grep "a string"
and it will tell you in which revision it was first added.
If you're looking for something less search-y and more overview-y you can use hg log -v to see what files were changes in each changeset and hg log -p to see the actual diffs for each.