Comparing revisions in Mercurial - mercurial

Coming from Subversion I have used the "Mark For Comparison" and "Compare URLs" feature in TortoiseSVN. This gave me the ability to compare the development branch with the last release version to get a list of files that changed.
We use this list of files for final code review, documentation of the next version, etc.
As you can see it is possible to get a list of files and also be able to click each file to see a visual diff of the changes.
Is it possible to do something similar with Mercurial? The best I have found thus far is this command, however the list of files is far less useful than what I was able to get with Subversion.
hg status --change {revisionnumber}

On the command-line you can:
hg diff -r <first changeset> -r <second changeset> or
thg vdiff -r <first changeset> -r <second changeset>
In TortoiseHg, you can also select the 2 revisions you want to compare and get a visual diff as shown below:

Related

Mercurial find files that have not been modified since a revision

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.

How to see changes in subrepos between commits

I have a mercurial repo with subrepos (also mercurial). Imagine the situation where I have changed the subrepos and the main repo. Now I want to see the changes between several commits including the changes in the subrepos.
Is it possible?
I use TortoiseHG and diffmerge. In diffmerege calling for visual diff from TortoiseHg, I can't see the changes in the subrepos between several commits.
In the command line you can do the following. Let us say you want to see all the changes of a subrepo named example between the changesets (in the main repo) c608f6017bd7 and 72d284a44170.
In the main repo
hg diff -rc608f6017bd7:72d284a44170 .hgsubstate | grep example
will return the changesets of the subrepo example, something like:
-001fc0acef220bcd42898ef3932dee8330ea64c0 example
+77f9db4d51c4b483607178aba91c872b0adedf1e example
Now you can see the logs and the diffs of the subrepo changes with:
cd example
hg log -r001fc0acef220bcd42898ef3932dee8330ea64c0:77f9db4d51c4b483607178aba91c872b0adedf1e
hg diff -r001fc0acef220bcd42898ef3932dee8330ea64c0:77f9db4d51c4b483607178aba91c872b0adedf1e
If you need it often, you can create a bash script named sublog like:
#!/bin/bash
r=$(hg diff -r$1:$2 .hgsubstate | grep $3 | cut -c 2-41 | tr '\n' ':' | sed 's/:$//'; echo '')
cd $3
hg log -r:$r
and use it like:
sublog c608f6017bd7 72d284a44170 example
I can only tell you how to achieve it on the command line - but that is readily available with tortoiseHG, too:
Most commands can be made aware of subrepositories by using the -S or --subrepos flag. As such, in order to see the diff between two changesets X and Y, including those on all subrepositories, do at the main repository:
hg diff -S -rX:Y
Mind, of course, that it will not show a diff in the subrepositories if there was no change of the sub-repository version(s) committed to the main one.
With the versions of TortoiseHg I've used (which doesn't include the last few releases), I haven't seen a way of doing what you're asking about. There are a few options though:
you can type commands directly in the output log window in TortoiseHg, so you can do hg diff -S -rX:Y there.
Archive the versions of the parent repo which you want to diff to some directories (hg archive --repository <path-to-repo> -r <rev> -S -t files -- <outputfolderpath>, or in TortoiseHg, right-click the changeset, select Export -> Archive). Then use diffmerge on the archive directories. This is a bit tedious (especially if you want to diff many changesets), but you will get a "deep" visual diff.

How do I diff incoming changesets with Beyond Compare 4 and hg?

I have been using the mercurial and Beyond Compare 4 tools together for about 2 weeks now and feel fairly confident in my usage, however I still seem to have a problem when comparing incoming changesets against my current local codebase. The problem is emphasized when I attempting a complicated merge.
Just to clarify, I am avoiding the use of tools such as TortoiseHg,
although I do have it installed. I am searching for feedback via cmd line operations only.
My current templated method to pull down the incoming changesets via the following ( as an [alias] )
hg in --verbose -T "\nchangeset: \t{rev}\nbranch: \t{branch}\nuser: \t\t{author}\ndate: \t\t{date(date,'%m-%d-%Y %I:%M%p')}\ndescription: \n\t{desc|fill76|tabindent}\n\n{files % ' \t{file}\n'}\n----------\n"
As an example, here is a simplified (and cleverly abstracted) block returned ::
changeset: 4685
branch: Feature-WI209825
user: Jack Handy <jhandy#anon.com>
date: 01-19-2015 10:19AM
description:
Display monkey swinging from vines while whistling dixie
Zoo/MonkeyCage/Resources/Localization.Designer.cs
Zoo/MonkeyCage/Resources/Localization.resx
Zoo/MonkeyCage/Utility/Extensions.cs
If I were to be comparing changes locally, I would simply use the following command ::
hg bcomp -r 4685 -r default <optional file name>
and then I would get an instance of Beyond Compare with a folder structure and files and I could just navigate accordingly to view the changes...however, when I attempt to do this with a changeset that has yet to be pulled into my local repository, I can't.
How do I diff incoming changesets with my local repository?
---- UPDATE --------------------------------
I pursued the idea of bundling the incoming changes and then trying to use BC4 to diff the bundle to any given branch/revision on my local repo.
hg in --bundle "C:\Sandboxes\Temp\temp.hg"
This creates a compressed file archive containing all the new changes.
Now I simply need to diff this bundle with my local, however am having difficulty optimizing this. Currently, I am using variations on the following command:
hg -R "C:\Sandboxes\Temp\temp.hg" bcomp -r default
Alas, I am still having difficulty perfecting this...any insight is appreciated.
I don't see how you can, since your local repository doesn't yet have that changeset, so mercurial can't create a local copy of the revision, as it doesn't have visibility of what the change actually is.
The -p flag to hg incoming will show you the patch for each revision, but that isn't what you want.
Why not just pull the remote changes anyway? It wont hurt unless you actually update. You can then do your diff in the normal way.
hg diff is a local operation.
But you can simply call hg incoming -p in order to obtain a diff view of what you're going to pull. See hg help incoming for more options and refinement (e.g. if you need to diff against a specific rev etc)

Why does "hg status" show changed files when "hg diff -g" doesn't? (One parent)

I have a repository where:
> hg st
shows that my working directory has some uncommitted changes, while
> hg diff
> hg diff -g
> hg diff --git
display nothing.
I read here: 4.10. hg status shows changed files but hg diff doesn't! the following:
hg status reports when file contents or flags have changed relative to either parent. hg diff only reports changed contents relative to the first parent. You can see flag information with the --git option to hg diff and deltas relative to the other parent with -r.
However, if I run hg parents it shows only one parent (the tip). As I mention above, I have also tried hg diff --git and it still displays nothing.
Note:
The above is on Mercurial version 2.0.1
hg status only shows M next to a regular file.
hg diff and hg diff -g print nothing
The filesystem is NFS.
hg parents prints only one parent
Some excerpts from Mercurial in daily use (Mercurial: the definitive guide) (copying here because there seems to be no way to give a convinient link to the end of the page):
The default output of the hg diff command is backwards compatible with the regular diff command, but this has some drawbacks.
The output of hg diff above obscures the fact that we simply renamed a file. The hg diff command accepts an option, --git or -g, to use a newer diff format that displays such information in a more readable form.
This option also helps with a case that can otherwise be confusing: a file that appears to be modified according to hg status, but for which hg diff prints nothing. This situation can arise if we change the file's execute permissions.
The normal diff command pays no attention to file permissions, which is why hg diff prints nothing by default. If we supply it with the -g option, it tells us what really happened.
To summarize, hg diff command misses several kinds of information on changes: attributes, permissions, file names, etc. These changes may exist even if you have a single parent. And hg status correctly takes into account all changes. To see what has happened, use hg diff -g. It's the answer to the question 'what happens'.
Seems like backwards compatibility is the 'why'. I'm not sure, but I suppose that the 'normal diff' is some widespread or built-in Unix/Linux tool (judging from the fact that both hg and git come from that world).
In these situations (it happens a lot to my team), I find that this command will fix about anything:
hg debugrebuilddirstate
or
hg debugrebuilddirstate -r tip
It's lightly documented in the help documentation, but basically I believe it clears out the "dirstate" file which caches information about working-directory files. The next time you hg stat it will refresh it from scratch.
One caveat: if you've added or removed files, that information will be lost when the dirstate is rebuilt.
If you have ignorews or ignoreblanklines set in .hgrc then hg status will show it as changed but hg diff won't (assuming the changes are only whitespace of course).
I just deleted the files that showed up as modified (make a backup if needed) which caused all the files to show up with an ! next to it when I ran
hg st
After that I ran the following command to revert the files (which were already checked in):
hg revert --all --no-backup
and that fixed the problem
In my case something was broken with hg. (same permissions and hg diff -g shows nothing).
I fixed issue with next way:
I cloned repository again in separate folder
I removed everything from this folder except .hg
I moved from old (broken) place everything except .hg to new place
So after this step i have repository which cloned with current version of mercurial + exactly same files.
After this steps i received same (empty) results for commands: hg st and hg diff -g

How can I see a list of all files that are different between two Hg repositories?

I've got a repository that has a lot of working code. Another developer on my team went without any updates for a while and then committed about 5 changesets. So, now we have two heads that are nearly two weeks apart. The tip doesn't work, but my changeset does.
I want to see what the differences are between the two repositories without having to merge them (because I'm not sure I want to do that).
Andrew's answer tells you how to see the differences between the files. This is great when you need all the details. But here is how to directly see the names of the files themselves:
hg status --rev X --rev Y
As you all know, the status command is normally used to see what has changed in the working copy since the last commit, or more accurately, since the working copy's parent revision (see hg parents or look it up in hg glossary if you don't know what that is). However, the status command can also be used to compare other revisions.
This can be used for all sorts of nice things... an example would be for writing release notes where it would be nice to mention any new translations introduced since the last release. For Mercurial itself, I can do:
% hg status --rev 1.6.2 --rev tip i18n
M i18n/da.po
M i18n/it.po
M i18n/pt_BR.po
A i18n/ro.po
to see that the Romanian translation is new and that the Danish, Italian, and Brazilian Portuguese translations have been updated. In this case, my working copy parent revision was the tip, so I could have left out --rev tip.
If you have both heads in your repository (remember, you don't actually have to update your working copy with the other developer's head), from the root directory of your working copy:
hg diff -r <your head changeset id> -r <other dev changeset id> .
should work. Of course, you can use hg heads to get the changeset ids, one of which it sounds like could be "tip".
If the above returns too much information, and you just wish to know what files changed, try piping through grep:
hg diff -r <your head id> -r <other dev id> | grep -E '^\+{3} b/'
will probably do the trick.