Issue #58 resolved

Fatal error when pushing an empty hg repo to a bare git repo

Maxime R.
created an issue

Steps to reproduce:

mkdir -p emptyrepo/{hg,git}
cd emptyrepo/git
git init --bare
cd ../hg
hg init
hg bookmark -f -r default master
hg push --verbose --debug ../git
echo $?

Output:

$ ./pushemptyrepo.sh 
Initialized empty Git repository in /home/maxime/prog/hg_repos/emptyrepo/git/
abandon : unknown revision 'default' !
pushing to ../git
creating and sending data
fatal: protocol error: expected old/new/ref, got '0000000000000000000000000000000000000000 None refs/heads/master'
** unknown exception encountered, please report by visiting
**  http://mercurial.selenic.com/wiki/BugTracker
** Python 2.7.3 (default, Sep 26 2012, 21:51:14) [GCC 4.7.2]
** Mercurial version 2.2.2, système de gestion de sources distribué
** Extensions chargées : extdiff, graphlog, purge, prompt, color, hgshelve, hgsubversion, hggit, rebase, mq
Traceback (most recent call last):
  File "/usr/bin/hg", line 38, in <module>
    mercurial.dispatch.run()
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 27, in run
    sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 64, in dispatch
    return _runcatch(req)
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 87, in _runcatch
    return _dispatch(req)
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 696, in _dispatch
    cmdpats, cmdoptions)
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 472, in runcommand
    ret = _runcommand(ui, options, cmd, d)
  File "/usr/lib/python2.7/dist-packages/mercurial/extensions.py", line 184, in wrap
    return wrapper(origfn, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/hgext/color.py", line 362, in colorcmd
    return orig(ui_, opts, cmd, cmdfunc)
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 786, in _runcommand
    return checkargs()
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 757, in checkargs
    return cmdfunc()
  File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 693, in <lambda>
    d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
  File "/usr/lib/python2.7/dist-packages/mercurial/util.py", line 463, in check
    return func(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/mercurial/extensions.py", line 139, in wrap
    util.checksignature(origfn), *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/mercurial/util.py", line 463, in check
    return func(*args, **kwargs)
  File "/home/maxime/prog/hg_repos/hgsubversion/hgsubversion/wrappers.py", line 533, in generic
    return orig(ui, repo, *args, **opts)
  File "/usr/lib/python2.7/dist-packages/mercurial/util.py", line 463, in check
    return func(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/mercurial/extensions.py", line 139, in wrap
    util.checksignature(origfn), *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/mercurial/util.py", line 463, in check
    return func(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/hgext/mq.py", line 3392, in mqcommand
    return orig(ui, repo, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/mercurial/util.py", line 463, in check
    return func(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/mercurial/extensions.py", line 139, in wrap
    util.checksignature(origfn), *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/mercurial/util.py", line 463, in check
    return func(*args, **kwargs)
  File "/home/maxime/prog/hg_repos/hg-prompt/prompt.py", line 434, in _push_with_cache
    res = orig(ui, repo, *args, **opts)
  File "/usr/lib/python2.7/dist-packages/mercurial/util.py", line 463, in check
    return func(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/mercurial/commands.py", line 4549, in push
    newbranch=opts.get('new_branch'))
  File "/usr/local/lib/python2.7/dist-packages/hggit/hgrepo.py", line 22, in push
    git.push(remote.path, revs, force)
  File "/usr/local/lib/python2.7/dist-packages/hggit/git_handler.py", line 244, in push
    changed_refs = self.upload_pack(remote, revs, force)
  File "/usr/local/lib/python2.7/dist-packages/hggit/git_handler.py", line 775, in upload_pack
    changed_refs = client.send_pack(path, changed, genpack)
  File "/usr/local/lib/python2.7/dist-packages/dulwich/client.py", line 455, in send_pack
    if len(objects) > 0:
  File "/usr/local/lib/python2.7/dist-packages/dulwich/object_store.py", line 755, in __len__
    return len(list(self.itershas()))
  File "/usr/local/lib/python2.7/dist-packages/dulwich/object_store.py", line 729, in itershas
    for sha in self.sha_iter:
  File "/usr/local/lib/python2.7/dist-packages/dulwich/object_store.py", line 822, in next
    o = self.object_store[sha]
  File "/usr/local/lib/python2.7/dist-packages/dulwich/object_store.py", line 112, in __getitem__
    type_num, uncomp = self.get_raw(sha)
  File "/usr/local/lib/python2.7/dist-packages/dulwich/object_store.py", line 299, in get_raw
    if len(name) == 40:
TypeError: object of type 'NoneType' has no len()
1

Comments (4)

  1. David Carr

    The "abandon : unknown revision 'default' !" message appears to be a Mercurial thing (not related to Hg-Git); it looks like Mercurial doesn't support resolving the "default" revision when creating a bookmark if there aren't any revisions yet. If you take out the "-r default" from the bookmark command, that message goes away. Regardless, the bookmark command doesn't do anything, since you're trying to apply a bookmark to a revision that doesn't exist.

    The exit code of 1 is also a Mercurial thing. Push is defined to return 1 if there was nothing to push. If you run the following test script, which is hg pushing to hg, I think you'll see that it too returns 1 (at least in this version of Mercurial, 2.2.2).

    mkdir -p emptyrepo/{hg1,hg2}
    cd emptyrepo/hg2
    hg init
    cd ../hg1
    hg init
    hg bookmark -f -r default master
    hg push --verbose --debug ../hg2
    echo $?
    

    All that being said, the real issue here appears to be that it dies loudly when trying to push an empty repo. It isn't possible to actually have a "master" bookmark in an empty repo... which might make it so that it isn't possible for us to truly support this use case we can actually make "work" (in that it performs a push). We might be able to pretend we have a 0000000000000000000000000000000000000000 master ref when pushing an empty repo, or we could just detect the special case and skip doing any real pushing.

  2. Maxime R. reporter

    Agreed, I just stumbled over this error while testing the steps to reproduce #57, in fact the error is still present after removing the bookmark step.

    I'm not really pushing empty repos those days but was quite surprised by the stacktrace ^^ Impressed to see you already have a patch for the issue !

  3. Log in to comment