j2carv/git-hg-bridge
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
This directory contains tools used to transparently push to a mercurial
repository through a git-hg bridge. This tool is setup inside a mercurial
repository which is called the hg-bridge.
g1 h1
\ /
\ /
g2 ------ g ------- h ------ h2
/ \
/ \
g3 h3
«g1», «g2» and «g3» are _git-repositories_ which master branches are clones of
_hg-repositories_ «h1», «h2» and «h3» tips. «h» is the _hg-bridge_ which is
used to export and import commits to the _git-bridge_ labeled «g». «1», «2» and
«3» are the edge names.
* Bridge Account Layout
A user account is used to hold the bridge taken by multiple people using ssh.
The layout of the user should be:
~/ -- user account
hg/ -- hg-bridge
.hg/
bridge/ -- (This directory)
pull.sh
push.sh
git/ -- git-bridge
repos/
<edge names> -- git-repo (g1, g2 and g3)
sync.lock
sync.lock.<edge names>
git-shell-commands/ -- commands for the git-shell
changeset-to-commit -- return the commit corresponding to a changeset
commit-to-changeset -- return the changeset corresponding to a commit
hg-fetch -- start fetching all repositories
mapfile -- cat the git-mapfile
<edge names>.git -- symbolic link to ~/hg/.hg/repos/<edge name>
* Mercurial Configuration
Edge names are listed inside the hg-bridge configuration file (namely
project-bridge/.hg/hgrc) and are stored in the path section.
[paths]
try-pushonly = ssh://hg.mozilla.org/try
mozilla-inbound = ssh://hg.mozilla.org/integration/mozilla-inbound
mozilla-central = ssh://hg.mozilla.org/mozilla-central
ionmonkey = ssh://hg.mozilla.org/projects/ionmonkey
Edges names are the name on the left hand side of the equals. If it ends with
«-pushonly», no data would be pulled into hg-bridge, but a git-repo would be
created to enable pushes.
Git repositories are created from the list of paths and configured automatically
to handle pushes.
This bridge script are relying on hg-git project to map repositories from one to
another. To enable it you will need to install python-dulwich (dependency of
hg-git) and add the following lines to hg-bridge configuration file.
[extensions]
hgext.bookmarks =
hggit = <path to hg-git>
* Security Concerns
This bridge does not have any knowledge of the rights of each user. To ensure
that the user which is pushing has the right to do so, we need to ask mercurial.
Once mercurial has accepted the changes, we mirror the push in Git by accepting
the push to the master branch of the git repository.
To enable authentification from mercurial we have to transfer the credentials of
the user across the connection. Thus bridge user should accept to forward their
agent such as it can be used by mercurial servers.
~client/.ssh/config
Host git-hg-mirror.company.name
User bridge
ForwardAgent yes
Forwarding the agent implies that if not restricted, any bridge user (or root)
may steal the agent of another. To avoid this, we isolate each connection to
the bridge account by using the git-shell.
The user name needed to establish a connection to the mercurial repository is
extarcted by sshd when the connection is established. The
~/.ssh/authorized_keys allow to change the environment, and thus to set a
different environment variable based on the key used for the connection.
~/.ssh/authorized_keys
no-port-forwarding,no-X11-forwarding,environment="[email protected]" key
This HGUSER name is used in the mercurial configuration file as the login used
to connect to the remote repository:
~/hg/.hg/hgrc
...
[ui]
ssh = ssh -l "$HGUSER"
...
Pushing to the git-bridge is prevented by setting an environment variable which
is always at «no» at the beginning of the ssh session and is set to «yes» when
the update hooks of each edge is going to push to the git-bridge. git-bridge
hooks are used to only accept pushes is the user «CAN_CROSS» environment
variable is set to «yes». To reset the environment at the beginning of the
session, you should use ~/.ssh/environment file.
~/.ssh/environment
CAN_CROSS=no
*** This model is not fully secured yet. ***