[PATCH 3 of 3 STABLE?] cmdutil: delay examination of dirstate parents until editor invocation
Yuya Nishihara
yuya at tcha.org
Tue Nov 17 07:29:32 CST 2015
On Mon, 16 Nov 2015 18:54:00 -0800, Pierre-Yves David wrote:
> On 11/15/2015 01:14 AM, Yuya Nishihara wrote:
> > On Sat, 14 Nov 2015 03:46:25 +0900, FUJIWARA Katsunori wrote:
> >> # HG changeset patch
> >> # User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
> >> # Date 1447437921 -32400
> >> # Sat Nov 14 03:05:21 2015 +0900
> >> # Branch stable
> >> # Node ID f90cd44b9860347b58e04e2bf4228bb9566de3f5
> >> # Parent 24e29f6c10ed52935786e394954e01af8b0e258b
> >> cmdutil: delay examination of dirstate parents until editor invocation
> >>
> >> Before this patch, 'mergeeditform()' immediately examines dirstate
> >> parents, even though it may be invoked outside wlock scope (normal "hg
> >> commit" is typical case).
> >>
> >> This may show "ignoring unknown working parent" message occasionally,
> >> because current dirstate parents may not be contained in changelog,
> >> which is cached outside wlock scope (see issue4378 for detail).
> >>
> >> In such case, "editform" may have ".normal" suffix, even if the
> >> working directory has actually two parents.
> >>
> >> This patch delays examination of dirstate parents until editor
> >> invocation by returning callable object if examination of dirstate
> >> parents is needed.
> >>
> >> This callable object is evaluated at external editor invocation, and
> >> wlock should be already acquired at that point.
> >>
> >> diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
> >> --- a/mercurial/cmdutil.py
> >> +++ b/mercurial/cmdutil.py
> >> @@ -333,19 +333,26 @@ def logmessage(ui, opts):
> >> return message
> >>
> >> def mergeeditform(ctxorbool, baseformname):
> >> - """return appropriate editform name (referencing a committemplate)
> >> + """return appropriate editform name or the callable object to get it
> >>
> >> 'ctxorbool' is either a ctx to be committed, or a bool indicating whether
> >> merging is committed.
> >>
> >> - This returns baseformname with '.merge' appended if it is a merge,
> >> - otherwise '.normal' is appended.
> >> + This (or the returned callable object) returns baseformname with
> >> + '.merge' appended if it is a merge, otherwise '.normal' is appended.
> >> """
> >> if isinstance(ctxorbool, bool):
> >> if ctxorbool:
> >> return baseformname + ".merge"
> >> - elif 1 < len(ctxorbool.parents()):
> >> - return baseformname + ".merge"
> >> + else:
> >> + # delay accessing to changelog via localrepository.dirstate
> >> + # (see issue4378 for detail)
> >> + def geteditform():
> >> + if 1 < len(ctxorbool.parents()):
> >> + return baseformname + ".merge"
> >> + else:
> >> + return baseformname + ".normal"
> >> + return geteditform
> >
> > These patches make me think that the problem is the locking scope is too
> > narrow to do commit consistently. Is it wrong to take both lock and wlock
> > earlier, at cmdutil.commit() for example?
>
> I agree with Yuya that we have a wider locking scope issue here. We
> should prepare the commit on a locked repository, otherwise we will end
> up with a strange state.
>
> (also the branchheads() things is a bug we just uncovered)
>
> Patch 1 seems correct in itself, Foozy, can you confirm we should still
> take it ?
I consider the patch 1 is also a locking scope issue. If repo.lock is taken,
dirstate.parents() can see the fresh changelog after repo.invalidate().
More information about the Mercurial-devel
mailing list