hg log 'filename' not showing merges?

Lars Marowsky-Bree lmb at suse.de
Mon May 21 16:35:38 CDT 2007


On 2007-05-21T11:18:36, Matt Mackall <mpm at selenic.com> wrote:

> Actually, that won't work reliably either and it's important to
> understand why. If, when you merge, you take the file version from the
> first parent, it will appear unchanged in the diff. This is because
> diff (and the larger notion of "changed"!) is only meaningfully
> defined for two versions, while merges involve three versions.

Right. Thanks for this very extensive explanation. I thought I had
gotten how changesets and merges work, but apparently I was missing one
bit - in particular that hg log always follows the first parent.

> for rev in `hg log -f --template "{rev}\n"`; do
>   echo -n "$rev:"
>   hg manifest --debug | grep myfile
> done

That proved to be a good starting point, but I also needed to make sure
that I only follow one path down memory lane.

I hacked up a script to follow and serialize a file's history. It takes
a filename, a starting revision and a number of maximum revisions to
follow as arguments and performs absolutely no error checking on those
values. ;-)

It prints the changelog + diffs for each different revision on the
stream. (It'll print when it had several choices to follow.) That's the
functionality I'm interested in, and indeed, it picks up the changes I
was looking for.

Does the functionality make sense to anyone else? I assume it could be
done much faster within python and mercurial proper, but my python is
rather weak.


Regards,
    Lars

-- 
Teamlead Kernel, SuSE Labs, Research and Development
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
"Experience is the name everyone gives to their mistakes." -- Oscar Wilde

-------------- next part --------------
#!/bin/bash

F=${1:-lrm/lrmd/lrmd.c}
cur_rev=${2:-tip}
max_revs=${3:-100}

get_sha() {
	hg manifest --debug $1 | grep $F | cut -f 1 -d ' '
}

diff_parent() {
	local parent="$1"
	if [ -z "$parent" ]; then
		return 1
	fi
	
	local psha=$(get_sha "$parent")
	if [ "$cur_sha" != "$psha" ]; then
		return 0
	fi
	return 1
}

rev_cnt=0
while [ $rev_cnt -lt $max_revs ] ; do
	r=$(hg log --template "{rev} {parents}\n" -r "$cur_rev")

	cur_rev=$(echo $r | cut -f 1 -d ' ')

	parent1=$(echo $r | cut -f 2 -s -d ' ' | cut -d ':' -f 1)
	parent2=$(echo $r | cut -f 3 -s -d ' ' | cut -d ':' -f 1)
	cur_sha=$(get_sha $cur_rev)

	next_rev=${parent1:-$[cur_rev-1]}

	ndiff=0
	if diff_parent $parent2 ; then
		echo "info: $cur_rev - following $parent2, not $next_rev" 1>&2
		ndiff=1
		next_rev=$parent2
	else
		if diff_parent $next_rev ; then
			ndiff=1	
		fi
	fi

	if [ $ndiff -gt 0 ]; then
		hg log -r $cur_rev
		hg diff -r $next_rev -r $cur_rev -p $F
		echo
	fi

	cur_rev=$next_rev
	rev_cnt=$[rev_cnt+1]
done

exit 0



More information about the Mercurial mailing list