On Sat, Oct 4, 2008 at 8:41 PM, Derek Scherger <[EMAIL PROTECTED]> wrote:

> On Fri, Oct 3, 2008 at 12:33 AM, Patrick Mézard <[EMAIL PROTECTED]> wrote:
>
>> The monotone test (test-convert-mtn) still pass. Are you converting a
>> public repository or can you write a simple script reproducing the issue ?
>
>
> Yeah, that test passes for me too. I'll see if I can come up with a test
> script that reproduces the issue.
> Thanks for the pointer.
>

[Background for monotone guys: I've been playing around with the mercurial
convert extension to convert a mtn repo to hg and have found that it can
fail as follows]

There are a few different problems and potentially an easy solution but I
also have a queasy feeling.

The problem is that I'm trying to run the monotone to hg conversion from
some subdirectory below my home directory and some of my home directory is a
monotone workspace. So I have something like the following:

/home/derek
/home/derek/_MTN (the monotone workspace directory)
/home/derek/foo (where I'm running the conversion from)

What happens is that monotone looks up from /home/derek/foo to see if it can
find a _MTN directory anywhere up the tree and finds the one in /home/derek.
This then means that all file paths that monotone uses are relative to
/home/derek so when you look for a file called bar, monotone thinks this
should be foo/bar, since we're in a monotone workspace rooted at
/home/derek. This is incorrect since we're doing some arbitrary conversion
that has nothing to do with my home directory workspace, monotone fails
(returning nonzero exit status) and reports the error to stderr.

On the mercurial side, in hgext/convert/common.py the checkexit function
sees the monotone failure and attempts to report it via raise
util.Abort(...) at around line 260 but something appears to be catching this
exception and silently ignoring it. Not knowing much about the mercurial
internals I haven't been able to find exactly who is eating the exception.
print_stack immediately before the raise shows:

  File "./hg", line 20, in <module>
    mercurial.dispatch.run()
  File "/home/derek/projects/mercurial/mercurial/dispatch.py", line 20, in
run
    sys.exit(dispatch(sys.argv[1:]))
  File "/home/derek/projects/mercurial/mercurial/dispatch.py", line 29, in
dispatch
    return _runcatch(u, args)
  File "/home/derek/projects/mercurial/mercurial/dispatch.py", line 45, in
_runcatch
    return _dispatch(ui, args)
  File "/home/derek/projects/mercurial/mercurial/dispatch.py", line 366, in
_dispatch
    ret = _runcommand(ui, options, cmd, d)
  File "/home/derek/projects/mercurial/mercurial/dispatch.py", line 419, in
_runcommand
    return checkargs()
  File "/home/derek/projects/mercurial/mercurial/dispatch.py", line 375, in
checkargs
    return cmdfunc()
  File "/home/derek/projects/mercurial/mercurial/dispatch.py", line 360, in
<lambda>
    d = lambda: func(ui, *args, **cmdoptions)
  File "/home/derek/projects/mercurial/hgext/convert/__init__.py", line 175,
in convert
    return convcmd.convert(ui, src, dest, revmapfile, **opts)
  File "/home/derek/projects/mercurial/hgext/convert/convcmd.py", line 336,
in convert
    c.convert()
  File "/home/derek/projects/mercurial/hgext/convert/convcmd.py", line 278,
in convert
    self.copy(c)
  File "/home/derek/projects/mercurial/hgext/convert/convcmd.py", line 249,
in copy
    newnode = self.dest.putcommit(files, copies, parents, commit,
self.source)
  File "/home/derek/projects/mercurial/hgext/convert/hg.py", line 146, in
putcommit
    a = self.repo.commitctx(ctx)
  File "/home/derek/projects/mercurial/mercurial/localrepo.py", line 797, in
commitctx
    update_dirstate=False)
  File "/home/derek/projects/mercurial/mercurial/localrepo.py", line 842, in
_commitctx
    fctx = wctx.filectx(f)
  File "/home/derek/projects/mercurial/mercurial/context.py", line 752, in
filectx
    return self._filectxfn(self._repo, self, path)
  File "/home/derek/projects/mercurial/hgext/convert/hg.py", line 116, in
getfilectx
    data = source.getfile(f, v)
  File "/home/derek/projects/mercurial/hgext/convert/monotone.py", line 176,
in getfile
    return self.mtnrun("get_file_of", name, r=rev)
  File "/home/derek/projects/mercurial/hgext/convert/monotone.py", line 58,
in mtnrun
    return self.run0('automate', *args, **kwargs)
  File "/home/derek/projects/mercurial/hgext/convert/common.py", line 268,
in run0
    self.checkexit(status, output)
  File "/home/derek/projects/mercurial/hgext/convert/common.py", line 261,
in checkexit
    print_stack()

The failure prevents mercurial from being able to get the file data from
monotone, but gets ignored so things continue on. The result is a mercurial
repo with a reasonable graph of revisions and log messages but no file data.

One easy way to fix this problem is to have mercurial run monotone with the
'--root=.' option to prevent monotone from searching for a _MTN directory.

Finding this problem would have been easier if mercurial had failed as it
apparently intends to when the converter_source has a problem (the exception
probably shouldn't be silently ignored). Mercurial is also throwing away
stderr as it executes commands. Reporting these messages was quite useful in
diagnosing the problem. Perhaps each command should save its stderr and
include this with the exception when there are problems?

It also seems somewhat questionable to me that the monotone automation
interface goes looking for a workspace root directory in the first place
although I'm sure there are reasons for this that escape me at the moment.

I'll keep looking to see if I can find whatever it is that's eating the
exception in the mercurial conversion code and I'll have a look at monotone
to see which automate commands really need to know about workspace things.

Cheers,
Derek
_______________________________________________
Monotone-devel mailing list
Monotone-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/monotone-devel

Reply via email to