[PATCH 1 of 2] merge: introduce mergestate

Matt Mackall mpm at selenic.com
Mon Apr 7 12:49:01 CDT 2008


On Mon, 2008-04-07 at 14:03 -0300, Alexis S. L. Carvalho wrote:
> Thus spake Matt Mackall:
> > # HG changeset patch
> > # User Matt Mackall <mpm at selenic.com>
> > # Date 1207518365 18000
> > # Node ID 32649adf4620c895af549abaa4122a0f16488d0a
> > # Parent  9c426da6b03b2f201e23107af5138d6b4a387428
> > merge: introduce mergestate
> > 
> > diff -r 9c426da6b03b -r 32649adf4620 mercurial/filemerge.py
> > --- a/mercurial/filemerge.py	Fri Apr 04 16:39:44 2008 +0200
> > +++ b/mercurial/filemerge.py	Sun Apr 06 16:46:05 2008 -0500
> 
> > @@ -158,11 +156,8 @@
> >      back = a + ".orig"
> >      util.copyfile(a, back)
> >  
> > -    if fw != fo:
> > -        repo.ui.status(_("merging %s and %s\n") % (fw, fo))
> > -    else:
> > -        repo.ui.status(_("merging %s\n") % fw)
> > -    repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca))
> > +    repo.ui.status(_("merging %s\n") % fd)
> > +    repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcl, fco, fca))
> >  
> >      # do we attempt to simplemerge first?
> >      if _toolbool(ui, tool, "premerge", not (binary or symlink)):
> 
> I liked the "merging foo and bar" messages when there was a rename...

Except it was a bit misleading.. there are three cases:

1) merging a and a and saving the result in a
2) merging a and b and saving the result in a
3) merging a and b and saving the result in b

Before, we weren't reporting 2 and 3 differently, so people must not
have been depending on this much.

With the new code, by the time we get here (either during merge, update,
or resolve), case 3 is irrelevant. That's because file a has already
been deleted earlier in the merge process (in the case of resolve, quite
possibly a long time ago). Mergestate doesn't even remember the original
filename. Instead we always merge against the destination file.

> > @@ -176,9 +171,9 @@
> >          util.copyfile(back, a) # restore from backup and try again
> >  
> >      env = dict(HG_FILE=fd,
> > -               HG_MY_NODE=str(wctx.parents()[0]),
> > -               HG_OTHER_NODE=str(mctx),
> > -               HG_MY_ISLINK=fcm.islink(),
> > +               HG_MY_NODE=short(repo.dirstate.parents()[0]),
> > +               HG_OTHER_NODE=short(repo.dirstate.parents()[1]),
> 
> This won't work during a merge - we only update the parents of the
> dirstate after doing all the file-level merging.  It also wouldn't work
> in the "hg update; hg resolve" case.

Right.

> > diff -r 9c426da6b03b -r 32649adf4620 mercurial/merge.py
> > --- a/mercurial/merge.py	Fri Apr 04 16:39:44 2008 +0200
> > +++ b/mercurial/merge.py	Sun Apr 06 16:46:05 2008 -0500
> 
> > +class mergestate:
> > +    '''track 3-way merge state of individual files'''
> > +    def __init__(self, repo):
> > +        self._repo = repo
> > +        self._state = {}
> > +        self._data = {}
> > +    def clear(self):
> > +        p = self._repo.join("merge")
> > +        try:
> > +            for f in os.listdir(p):
> > +                os.unlink(os.path.join(p, f))
> > +        except OSError, err:
> > +            if err.errno != errno.ENOENT:
> > +                raise
> 
> shutil.rmtree?  Or put the error handling inside the loop.

I suppose.

> > +    def read(self):
> > +        try:
> > +            f = self._repo.opener("merge/state")
> > +            for l in f:
> > +                bits = l[:-1].split(" ")
> > +                dfile, state, hash, afile, anode, ofile, dflags = bits
> 
> Won't work if there are spaces in the names.

Indeed, not sure what I was thinking.

-- 
Mathematics is the supreme nostalgia of our time.



More information about the Mercurial-devel mailing list