Merging dirty subrepos into target revision on update

Martin Geisler mg at
Tue Dec 14 08:14:58 CST 2010


My client has asked me to fix an issue with updates to dirty subrepos.
Imagine a main repo and a subrepo where three changesets are paired like

  m0 --> s0
  m1 --> s1
  m2 --> s2

So the main and subrepo went in lock step.

Mercurial currently behaves like this when you do 'hg update m2':

  (m1, s1) --> (m2, s2)

This is all fine. However, if the subrepo is updated to a differnet
version, then we get the same result:

  (m1, s0) --> (m2', s2)

Actually, the m2' state has a dirty .hgsubstate file, namely the one
containing s1 from m1. This is the cause of

Where a subsequent commit will make an empty commit in the main repo
because it is tricked by the "dirty" .hgsubstate file.

However, my client doesn't care about that -- they are more interested
in keeping the subrepo as-is. In particular, if the history was

  m0 --> s0
  m1 --> s0
  m2 --> s1
  m3 --> s1
  m4 --> s1
  m5 --> s1

then they expect 'hg update m5' to do

  (m3, s0) --> (m5, s0)

where the subrepo is kept in its dirty state. This is consistent with
how we merge other dirty files into the target revision when updating.
One would need a 'hg update -C m5' to make the transition

  (m3, s0) --> (m5, s1)

I think this would be a sensible change -- what you think?

The first case with where we start at (m1, s0) and do 'hg update m2' is
more tricky. I think it ought to generate a conflict since updating the
subrepo corresponds to updating the .hgsubstate file, and thus there is
a conflict in the .hgsubstate file. However, we normally keep that file
sort of hidden.

I cannot begin fixing/changing this until I know if I can put the change
into Mercurial, so I would appreciate your input.

Martin Geisler

aragost Trifork
Professional Mercurial support

More information about the Mercurial-devel mailing list