Listing incoming branches in Mercurial - mercurial

I happen to work against a server repo which has a lot of named branches. I usually pull only the branch I'm currently working on, to keep me local repositories less cluttered.
Sometimes, I want to find out what branches in the server repo have any new changesets I can pull.
Is there any way I can list either the branch names, or the branch heads? Something like the opposite of:
$ hg log -r "outgoing() and head()"
Sure, I can do something along the lines of:
$ hg incoming | grep branch | uniq
but I'd be happy to find a more Mercurial-native and cross platform solution (I work on Windows).

For the time being, I decided to stick with the grep way. I added this to my hgrc:
[alias]
remote = !hg incoming | grep branch | sort | uniq
On Windows, I use grep and uniq found in UnxUtils.
The sample output looks like this:
D:\Projects\MyProject>hg remote
branch: 1.4-stable
branch: next-major
branch: ticket-199
branch: ticket-90
Unfortunately, this command still lists all the changesets under the hood, so running it can take some time.

Related

How do I check out a mercurial revision from a different repository?

In git if you have two remote repositories setup as default and other and they both contain the cool-feature branch but they get out of sync, you might have something like this:
* <--- HEAD, cool-feature, default/cool-feature
|
|
o another commit
|
|
o commit for awesome
|
|
o <--- other/cool-feature
|
.
.
.
I can jump back and forth by doing a git checkout other/cool-feature and git checkout default/cool-feature.
How do I do the equivalent in Mercurial? Is it even possible?
If you use bookmarks to emulate Git branches and you pull from two repositories where bookmarks have diverged, then one of them will be labeled as name#repo, where name is the bookmark's name and repo is either the identifier in the [paths] section of .hg/hgrc or a unique identifier when there is no such entry.
However, if the bookmarks haven't diverged, but one revision is the ancestor of another, then you'll only get the most recent one. You can still individually get bookmarks from remote repositories via:
hg pull -B name repo1
hg update name
and then:
hg pull -B name repo2
hg update name
Alternatively, you can also use hg id to figure out which nodes remote bookmarks correspond to:
hg update -r $(hg id -i -r name repo1)
or:
hg update -r $(hg id -i -r name repo2)
Note that you may want to use local tags or additional bookmarks in order to mark the revisions if you plan on switching back and forth frequently, since accessing remote repositories can be a bit slow.
If this is something that you need frequently, you may want to consider the remotenames extension. Warning: this extension changes the normal behavior of bookmarks quite a bit (making it a lot more Git-like, in fact).

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)

Mercurial extension or hook to prevent backout of merge changesets

As noted in the documentation, the hg backout command can cause problems when used with merge changesets. We have had a couple of cases recently of newer developers backing out merge changesets and causing code that we wanted to keep to be reverted when everything gets merged back together.
To avoid this, I'm trying to think of a good way to prevent this from happening at all. Is there a good general way I could write a hook or just disable the backout command entirely?
(Part of our standard developer setup is to install a custom set of extensions, so I already have a good way to install these types of rules locally for our entire development team -- I just haven't thought of a good way to implement the ruleset.)
What about this:
$ hg --version
Mercurial Distributed SCM (version 2.6.3)
...
$ hg log --graph --template='{rev} {desc}'
# 5 c5
|
o 4 merge
|\
| o 3 c4
| |
o | 2 c3
|/
o 1 c2
|
o 0 c1
$ hg backout 4
abort: cannot backout a merge changeset
So it looks like Mercurial does what you want by default. Maybe you need a more recent Mercurial version.
If you are stuck to an old Mercurial version, here is a hacky hook (for *nix/Bash) which aborts backouts of merges:
[hooks]
pre-backout=REV=`echo $HG_PATS | sed -e "s/[^0-9]//g"`; test `hg log -r "parents($REV)" --template='{node}\n' | wc -l` -eq 1 || { echo 'do not do that'; exit 1; }
It extract the revision number from $HG_PATS and then uses hg log and wc to count the number of parents of the revision in question. If there is more than one parent, it is a merge.
Still, I highly recommend to use a recent Mercurial: check the release notes for exciting features you are missing.
Here's a simple Python-based hook that prevents backout of merges. Credit goes to #Oben for pointing me in the right direction.
def prebackout_prevent_backout_merge( ui, repo, **kwargs ):
'''Don't allow backouts to of merge changesets.'''
# Figure out if a --parent version was given or not.
backout_to_parent = kwargs['opts'].get( 'parent', None )
# If no parent version was given, proceed.
if backout_to_parent is '':
return False
# Otherwise abort the operation.
from mercurial import util
raise util.Abort( 'Backout of a merge changeset is not allowed.' )
You can configure this hook in .hgrc or Mercurial.ini with:
[hooks]
pre-backout.ttd_prevent_backout_merge = python:PATH_TO_HOOK_SCRIPT:prebackout_prevent_backout_merge

In Mercurial (Hg), what is a good way to list all files modified by me since revision 4822?

I may do development work for 2 weeks before one or two features get pushed to all the production servers, and since this is a Ruby on Rails project, many files can be modified.
So using Mercurial as the source control, is there a good way to list all filenames that are modified (or added) by me, between the current version and revision 4822? (the number 4822 is before I do the first hg push, I do an hg out and see that the changeset that will go out is 4823, so I will diff with 4822)
(Update: This is to list files only modified by me, as opposed to the other 38 files modified by my teammates)
Better yet, is there a good way to invoke hg vdiff automatically, so when invoked as
checkdiff Peter 4822
It will do
hg vdiff -r 4822 [... the list of filenames modified by Peter (or me) since 4822]
Maybe use hg log and some nice one-liner?
hg log --user Peter --verbose | grep files | sed -e 's/files://' | tr ' ' '\n' | sort | uniq will give all files modified by you since beginning of repository. Use --rev to limit revision scope.