Hg: how to get diff of two different files? - mercurial

I'm sorry if it's odd question. I have a mercurial repository. Is it possible to get a diff of two different files from some revision by hg? For example, there is a revision
revision xxx
- file1
- file2
How I can get a diff of file1 and file2 by standard hg command or any extensions?
Thank you.
UPD
I would like something like this:
hg diff -r xxx file1 file2
Than I will have all changes between two files of same revision.

Initially I read your question differently, but your comment made clear that you are asking about the differences between two files of the same revision. That's nothing where the VCS has any stakes in.
You simply can use (on *nix systems) the diff command:
diff FILE1 FILE2
If you need the difference of the files at particular revisions, of course you can use mercurial before that in order to get to that:
hg update -rXXX
or even to see the difference of FILE1 at revision XXX compared to FILE2 at revision YYY (but beware, it changes the working dir content; make sure to undo the revert afterwards):
hg revert -rXXX FILE1
hg revert -rYYY FILE2
diff FILE1 FILE2

Related

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.

Hg diff with multiple files

I am new to mercurial. So, please excuse my question if it sounds trivial. I am trying to figure out how to do a diff for multiple files. Here is my use case : I made changes to four files. However, I am only interested in seeing the changes I made in two of them (fileA and fileB). I thought something like this would work :
hg diff fileA fileB
But it does not.
You need either the --include(-I) or --exclude(-X) options such as:
hg diff -I fileA -I fileB
hg diff -X *.csv
Remember you can compare specific revisions too
hg diff -r 1234:tip -I fileA
Use hg help diff in the console to see all the options available or look here

Resolving conflicts: how to accept "their" changes automatically?

When merging conflicting changes using hg merge, Mercurial inserts a set of markers into the files to be merged in my working copy like this:
<<<<<<< local
version = 0.2
=======
version = 0.1
>>>>>>> other
Then I manually edit all files marked as U from a list produced by hg resolve --all -l and then I tell mercurial I have resolved them by hg resolve -m file1 file2 file3 ...
In many situations I would like however accept either my-only or their-only changes on some conflicting files. I am thinking to create two simple sed/awk/whatever scripts named accept-theirs.sh and accept-my.sh or is there any "proper" way to do it?
Use
hg resolve -t internal:other --all
to accept theirs and
hg resolve -t internal:local --all
to accept yours
Try this:
hg merge --tool internal:other
See also hg help merge-tools for more information.

Diff after committing locally

I just cloned a repo from their remote.
I built the software, changed about 4 files, committed them locally and now want to create a patch that I can show them.
When I run :
hg diff -U8p abc efg pqr > patch_file
I don't see the changes I made. Does hg diff only compare the current files with the last committed files?
How do I get this to work?
To diff the working directory against a particular revision REV, use
hg diff -r REV
To compare two revisions against each other, use
hg diff -r REV1 -r REV2
To figure out which revisions to compare, examine the output of hg log. If you'll be doing this a lot and the base revision is fixed, give it a name (e.g., whatipulled) with
hg tag -r REV whatipulled
You can then specify whatipulled as the revision, instead of a numeric rev id (or a hash).
To export your diffs in a richer format, including commit comments etc., you can also use the following which is designed for this purpose:
hg export -r REV
There's also hg bundle -r REV, which produces a binary file with similar information.
But if you're sending changes back to the parent repo, the best method is to use hg push. It communicates your changesets directly to the parent; you don't even need to know which changesets need pushing. Of course, you must have the right to push to the parent repo.
hg push [ parent_repo_url ]
(If you pulled from it, mercurial should already know the path and you can leave it out).
If the parent repo is on bitbucket and you don't have pu, you can set up your own account on bitbucket, pull/push to that from your local repo, and then issue a "pull request" to the project repo, asking them to pull from you.
All of the above have options to control their behavior, which see.
From hg help diff
If only one revision is specified then that revision is compared to the working directory
In your diff for -r you must to use old tip (latest "not your" changeset) and update to tip (your latest changeset) before diffing.
If some binary data was modified in your changesets, don't forget to use -g option
hg up & hg diff -r <CSET> -g > some.patch
Improved diff for any active changeset and without hand-work for detecting base changeset (for linear history == in single branch)
hg diff -r "parent(min(outgoing()))" -r tip
By default, hg diff compares the currently checked out file with the last commit. You can change this by adding options:
-r REV compares the currently checked out files with a specific revision REV.
-c REV shows the changes made by revision REV
So in your case hg diff -c 123 ... would give you the diff for commit 123.
My guess is that hg outgoing is exactly what you want -- it compares what you've committed locally with what is at the default remote server and shows you a list of those changesets or with -p the commits.
That does, however, shows each changeset separately. If you want to see all the changes combined, you'd have to do hg diff -r HERE -r THERE or since -r HERE is a default, hg diff -r THERE
I see you've asked in a comment "How do I know what THERE is", where THERE is the last changeset remote has, and you can get that answer by doing hg outgoing. If hg outgoing shows it would send changesets 66, 67, and 68, then you want to do hg diff -r 65 to compare what's already there (65) with what's local (68).

Mercurial: How to keep some files unchanged after merge?

I need to pull changes from one branch to another, but keep some files unchanged.
For example:
> hg up -C production
...
> hg merge feature-branch
...
> hg st
M file1
M file2
M file3
R file4
...
Is there a way to keep file2 unchanged and file4 not deleted, and then commit?
Using hg transplant is inappropriate in my case because there're too many commits to find what exactly to transplant.
$ hg revert -r . file2 file4
This reverts both files to how they were in the first parent of your working directory (.).