hg log 'filename' not showing merges?

Matt Mackall mpm at selenic.com
Mon May 21 16:18:36 UTC 2007


On Mon, May 21, 2007 at 03:54:46PM +0200, Lars Marowsky-Bree wrote:
> On 2007-05-21T08:52:36, Matt Mackall <mpm at selenic.com> wrote:
> 
> > > Is this expected behaviour?
> > Probably. If there wasn't an actual three-way merge in the merge
> > changeset, then there wasn't a file-level change for that changeset.
> 
> So, "hg log <filename>" isn't the appropriate way to find out all
> changes to a given file - is there a better way of achieving this then,
> short of going through all changesets and grepping lsdiff?

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.

Similarly, in your merge case, the file -didn't change-. The history
from the file's perspective looks like this:

         e-f-g-h              "remote"
        /       \
 a-b-c-d-----... `-i-j-k      "local"

>From the point of view of "k", there's a continuous history back
through the merge to the beginning of time. Because there were no
changes on the "local" branch, no "merge" actually happens, so nothing
is recorded between "h" and "i". In other words, this file-level
history graph is the same as:

 a-b-c-d-e-f-g-h-i-j-k

..which is what you get when you ask for a file's history.

But we still haven't solved your problem, which can be phrased as
"when did file X get changed -relative- to branch Y"? And
unfortunately, we don't currently store enough data in each changeset
to make answering this question fast. We store a list of changed files
but that's only "changed" in the sense above. So we'll have to hack
something up:

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

This generates a list of all revisions that are ancestors of the
working directory and then uses manifest to report which version of
the file is present:

4450:c055efc3fbc852e42abbbd00615333862b12ec4f 644 mercurial/dirstate.py
4448:c055efc3fbc852e42abbbd00615333862b12ec4f 644 mercurial/dirstate.py
4447:c055efc3fbc852e42abbbd00615333862b12ec4f 644 mercurial/dirstate.py
4445:9d8392f4c054555f585d0ee3a1f8252729796584 644 mercurial/dirstate.py
4444:9d8392f4c054555f585d0ee3a1f8252729796584 644 mercurial/dirstate.py
4443:9d8392f4c054555f585d0ee3a1f8252729796584 644 mercurial/dirstate.py
4442:9d8392f4c054555f585d0ee3a1f8252729796584 644 mercurial/dirstate.py
4441:23f94ad20488d79e1cbf7fcefb9307be94a71fbb 644 mercurial/dirstate.py
4440:23f94ad20488d79e1cbf7fcefb9307be94a71fbb 644 mercurial/dirstate.py
4439:b7ee0e106aac8762262aac72c1de9d35b08b359d 644 mercurial/dirstate.py
4438:9d8392f4c054555f585d0ee3a1f8252729796584 644 mercurial/dirstate.py
4437:9d8392f4c054555f585d0ee3a1f8252729796584 644 mercurial/dirstate.py
4436:9d8392f4c054555f585d0ee3a1f8252729796584 644 mercurial/dirstate.py
4435:9d8392f4c054555f585d0ee3a1f8252729796584 644 mercurial/dirstate.py
4434:9d8392f4c054555f585d0ee3a1f8252729796584 644 mercurial/dirstate.py

Change the -f to -fm and it'll do so only for merges.

We could probably add an option like the --removed log option to show
revisions where the file was affected by a merge.

-- 
Mathematics is the supreme nostalgia of our time.



More information about the Mercurial mailing list