tags:

views:

214

answers:

4

I wonder whether there is a mercurial command/extension that just tests whether a given changeset is in a branch. The command would be something like:

hg contains [-r branch] changeset_id

and should check whether the given changeset is in the current/given branch, returning just "Yes" or "No".

I know about the "debugancestor" command, but a "Yes/No" answer is way easier to read.

And if there is, is it possible to check for transplanted changesets as well?

EDIT: The scenario is located in a repo where named branches have multiple heads. Lets say a branch is named "dev-X", having more than 1 head and a longer history, too long at least to track it with various graph visualizations. I want to figure out whether a changeset X in branch "dev-X" was merged into another head of "dev-X". Therefore I cannot use branch names but only changeset numbers/hashes to specify a branch.

And to top it all, I'm trying to find out whether changeset X was transplanted there, possibly taking more than 1 transplantation step. I know that the necessary info is stored in mercurial (I've seen it when tampering with the mercurial internals), it's just not accessible via the command line interface.

+2  A: 

It should be pretty easy to transform the results from debugancestor into a yes or a no (but there's definitely no built-in way to do that; write a script already!). Be aware that the answer might be wrong if the branch has more than one branch head, though.

(Writing an extension to add a command to do this should also be nigh-trivial, BTW.)

djc
+4  A: 

How about this:

hg log -r changeset_id -b branchname

That will give some output if changeid_id is on branchanme and nothing if it isn't.

You could wrap it in a bash function if you want:

function contains() { if [ "$(hg log -r $1 -b $2)" == "" ] ; then echo no; else echo yes ; fi; }

which does this:

$ contains 0 default
yes
$ contains 0 other   
no
Ry4an
+1 for a full solution
Matthieu M.
Thats a very good solution for sane repos.It doesn't work in my case though, where there are multiple heads for the most named branches.Thinking about it, I should've mentioned that in the question ...
resi
Resi, i think it still works so long as you're using named branches (which can still have multiple heads). Every changeset has one and only one named branch associated with it -- "default" if you've never typed 'hg branches'.That code just checks if the cset in question has the specified name as its 'branch' field. It ignored heads (and tip) entirely and does work with multiple heads per named branch.If you're not, however, using named branches (and I don't), then it's entirely useless because every changeset has 'default' in its branch property.
Ry4an
Ry4an: The presence of a given branch tag in a cset does not mean that this cset is part of any head of this branch. You could merge the branch (including this cset) into another branch, maybe "default", while keeping other versions of this branch alive.This means that the cset we are looking for is tagged to belong to some branch but is actually only seen in the "default" branch.
resi
Sounds like a divergence between what 'branch' means in your workflow and what it means in mercurial. Your request "tests whether a given changeset is in a branch" isn't about heads. In mercurial a changeset is very literally in a (named) branch if and only if the branch property on that changeset matches that name.If you're talking about "is X an ancestor of one of many heads" then you're right to be looking at debugancestor. I've wrapped that:function isKid() if [ $(hg debugancestor $1 $2 | cut -d : -f 1) == "$1" ] ; then echo $2 is a kid of $1; else echo $2 is NOT a kid of $1; fi
Ry4an
I guess you are right, my understanding of branches might differ from mercurial. Unfortunately my shell-fu isn't mentionable, this function seems like the shortest way to do the job...
resi
A: 

You could always just print out the name of the branch for that revision (it'll be empty if it's default) and then test that against whatever you want (in bash or in a scripting language of some sort):

hg log --template '{branches}' -r <revision name/number>
Ted Naleid
+2  A: 

As mentioned in the comment above I gave it a shot, this is what came out:

http://bitbucket.org/resi/hg-contains/

resi
Nice. Mention this on the mercurial list, and add it to the extensions on the Mercurial wiki.
quark
even if its my own answer, this works best for me.
resi
Thanks for the tip. Here you go:http://mercurial.selenic.com/wiki/ContainsExtension
resi