Pushing to a Gerrit instance with hg-git

33 views
Skip to first unread message

Carl-Daniel Hailfinger

unread,
Jan 20, 2020, 10:09:28 AM1/20/20
to hg-...@googlegroups.com
Hi,

I'm currently trying to push a commit via hg-git to a running gerrit
instance, but the target branch selection doesn't work the way I hoped
it would.
The repository in question can be cloned either by
hg clone git+https://review.coreboot.org/flashrom.git
or
hg clone hg clone git+ssh://<username>@review.coreboot.org:29418/flashrom

The Gerrit instance is at https://review.coreboot.org/q/project:flashrom

With git and a repo cloned via ssh, pushing a commit looks like this:
git push origin HEAD:refs/for/master

WIth mercurial and hg-git, I tried to translate that command, but
apparently specifying the remote branch doesn't work as I would like:

compiler@host:~/flashrom-hg$ hg book refs/for/master
compiler@host:~/flashrom-hg$ hg push --debug --traceback
pushing to git+ssh://carl...@review.coreboot.org:29418/flashrom
finding hg commits to export
calling ssh: ssh -p 29418 'carl...@review.coreboot.org' 'git-receive-pack '\''/flashrom'\'''
searching for changes
1 commits found
list of commits:
0cc3e992c8132ff1b99af39f1d5720652a4ae11c
adding objects
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/mercurial/scmutil.py", line 154, in callcatch
return func()
File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 314, in _runcatchfunc
return _dispatch(req)
File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 918, in _dispatch
cmdpats, cmdoptions)
File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 673, in runcommand
ret = _runcommand(ui, options, cmd, d)
File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 926, in _runcommand
return cmdfunc()
File "/usr/lib/python2.7/dist-packages/mercurial/dispatch.py", line 915, in <lambda>
d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)
File "/usr/lib/python2.7/dist-packages/mercurial/util.py", line 1197, in check
return func(*args, **kwargs)
File "/usr/lib/python2.7/dist-packages/mercurial/commands.py", line 4194, in push
opargs=opargs)
File "/usr/lib/python2.7/dist-packages/hgext/git/util.py", line 56, in inner
return f(*args, **kwargs)
File "/usr/lib/python2.7/dist-packages/hgext/git/__init__.py", line 384, in exchangepush
pushop.cgresult = repo.githandler.push(remote.path, revs, force)
File "/usr/lib/python2.7/dist-packages/hgext/git/git_handler.py", line 404, in push
old_refs, new_refs = self.upload_pack(remote, revs, force)
File "/usr/lib/python2.7/dist-packages/hgext/git/git_handler.py", line 1122, in upload_pack
raise hgutil.Abort(_("git remote error: ") + str(e))
Abort: git remote error: refs/heads/refs/for/master failed to update
abort: git remote error: refs/heads/refs/for/master failed to update


The remote target branch should in theory be refs/for/master, but
apparently something in the pipeline between hg and the remote side adds
the prefix refs/heads/ to any git branch specification.
Looking through the hg-git code and dulwich code, I can find quite a few
places where refs/heads/ is added as a prefix, but I haven't yet found
the instance which causes the problem I'm having.

The last mention of the same (or similar) issue I could find was here:
https://groups.google.com/forum/#!searchin/hg-git/gerrit%7Csort:date/hg-git/SH8g0oi8EWg/HgKG83Zn6T4J

I'm running hg-git 0.8.11 from Ubuntu 18.04. My apologies if this is
already fixed in some newer version. I looked through the changelogs and
couldn't find anything which looked related.

Regards,
Carl-Daniel

Sanjay Vasandani

unread,
Apr 30, 2021, 2:55:00 AM4/30/21
to hg-git
The underlying issue is that I don't think hg-git has a way to specify the remote ref directly. You can only push to remote branches (refs/heads) and tags (refs/tags), which are mapped to entities in Mercurial. It's therefore not possible to work with Gerrit, which relies on special refs such as the refs/for and refs/meta trees.

Sanjay Vasandani

unread,
Apr 30, 2021, 1:41:25 PM4/30/21
to hg-git
To give more background, Git allows you to push to remote refs (including branches) without having it tracked locally. AFIAK hg-git does not allow this, e.g. in order to push to a remote branch you must have a corresponding bookmark.

Gerrit relies on this capability. Unlike with GitHub or other remote Git hosting, you don't tend to push remote branches in Gerrit. Instead, you push to a ref corresponding to the remote branch you want to merge into in the remote refs/for tree. This remote ref does not actually exist; you can push to it, but you cannot fetch it. Instead of a remote feature/topic branch or a pull request, the unit of review/mergability for Gerrit is a single commit. This commit has a Change-Id trailer in the commit message, such that pushing a commit with an existing change ID to the same ref updates that change.

In order for hg-git to support this, it would need to offer at minimum:
  1. A way to push to remote refs that cannot be fetched.
  2. A way to specify which arbitrary remote ref to push to, rather than being restricted to refs/heads or refs/tags.

Dan Villiom Podlaski Christiansen

unread,
May 7, 2021, 7:18:26 AM5/7/21
to hg-...@googlegroups.com
Hi

I think the core issue here is that what Gerrit requires you to do doesn't fit in any way on top of a normal, Mercurial workflow. (To me, the UX seems quite esoteric and weird, but then again, I'm not a fan of Git…) To some extent, you could work around this by interacting directly with the local Git repository:

$ hg gexport
$ GIT_DIR=$(hg debuggitdir) git push wherever whatever

I think the best approach is to add dedicated command, say `git-push`, that you'd use for all those cases where you want to push something specific, either to Gerrit or perhaps a deletion. Essentially, this command would do the following:

  • Export local commits
  • Convert the first argument to a Git remote path or URL
  • Pass any remaining arguments as refs.

Dulwich has some porcelain that should be useful for this. I'd encourage you to try to come up with a patch that implements that — hg-git could use more contributors 🙂
-- 
You received this message because you are subscribed to the Google Groups "hg-git" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hg-git+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/hg-git/c1fa6ab6-d266-4538-9e7a-e7d14ec223abn%40googlegroups.com.

--

Dan Villiom Podlaski Christiansen

Reply all
Reply to author
Forward
0 new messages