add an extension that allows server-side hg->git and git->hg lookups
Summary:
This is a massive hack until Dewey becomes capable of answering these questions.
The plan is to use these commands in `arc diff` and `arc patch` to send the Git versions of the base commit over, so that the diff and land infra reaches parity with Git.
This should also unblock configerator-hg and allow the landing strip to work.
Test Plan:
In my `fbandroid-from-git` repo, enabled this extension, and then added the config:
```
[gitlookup]
mapfile = git-mapfile
```
Then, ran
```
hg id -r _gitlookup_hg_1fe73e73af4acadf1865a41e3aaa518a70cc2302 ssh://localhost//data/users/sid0/fbandroid-from-git -i --debug
```
Saw that the last line printed out was `76327beadc98c7c0559cd8aa36f0a25d93d781a5`, the Git equivalent of that commit.
After this, ran
```
hg id -r _gitlookup_git_76327beadc98c7c0559cd8aa36f0a25d93d781a5 ssh://localhost/data/users/sid0/fbandroid-from-git -i --debug
```
Saw that the last line printed out was `1fe73e73af4acadf1865a41e3aaa518a70cc2302`, as expected.
Reviewers: dschleimer, akushner, davidsp, pyd, mpm, durham
Reviewed By: durham
Subscribers: pradvenkat, akshay, thawan
Differential Revision: https://phabricator.fb.com/D1330813
Tasks: 3751836
2014-05-15 03:17:25 +04:00
|
|
|
# gitlookup.py - server-side support for hg->git and git->hg lookups
|
|
|
|
#
|
|
|
|
# Copyright 2014 Facebook, Inc.
|
|
|
|
#
|
|
|
|
# This software may be used and distributed according to the terms of the
|
|
|
|
# GNU General Public License version 2 or any later version.
|
2017-09-14 03:17:55 +03:00
|
|
|
|
|
|
|
''' extension that will look up hashes from an hg-git map file over the wire.
|
|
|
|
This also provides client and server commands to download all the Git
|
|
|
|
metadata via bundle2. Example usage:
|
|
|
|
|
|
|
|
- get the git equivalent of hg 47d743e068523a9346a5ea4e429eeab185c886c6
|
|
|
|
|
|
|
|
hg identify --id -r\\
|
|
|
|
_gitlookup_hg_47d743e068523a9346a5ea4e429eeab185c886c6\\
|
|
|
|
ssh://server/repo
|
|
|
|
|
|
|
|
- get the hg equivalent of git 6916a3c30f53878032dea8d01074d8c2a03927bd
|
|
|
|
|
|
|
|
hg identify --id -r\\
|
|
|
|
_gitlookup_git_6916a3c30f53878032dea8d01074d8c2a03927bd\\
|
|
|
|
ssh://server/repo
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
[gitlookup]
|
|
|
|
# Define the location of the map file with the mapfile config option.
|
|
|
|
mapfile = <location of map file>
|
|
|
|
|
2017-09-14 03:17:55 +03:00
|
|
|
# The config option onlymapdelta controls how the server handles the hg-git
|
|
|
|
# map. A True value corresponds to serving only missing map data while False
|
|
|
|
# corresponds to serving the complete map.
|
|
|
|
onlymapdelta = False
|
|
|
|
|
2017-09-14 03:17:55 +03:00
|
|
|
'''
|
add an extension that allows server-side hg->git and git->hg lookups
Summary:
This is a massive hack until Dewey becomes capable of answering these questions.
The plan is to use these commands in `arc diff` and `arc patch` to send the Git versions of the base commit over, so that the diff and land infra reaches parity with Git.
This should also unblock configerator-hg and allow the landing strip to work.
Test Plan:
In my `fbandroid-from-git` repo, enabled this extension, and then added the config:
```
[gitlookup]
mapfile = git-mapfile
```
Then, ran
```
hg id -r _gitlookup_hg_1fe73e73af4acadf1865a41e3aaa518a70cc2302 ssh://localhost//data/users/sid0/fbandroid-from-git -i --debug
```
Saw that the last line printed out was `76327beadc98c7c0559cd8aa36f0a25d93d781a5`, the Git equivalent of that commit.
After this, ran
```
hg id -r _gitlookup_git_76327beadc98c7c0559cd8aa36f0a25d93d781a5 ssh://localhost/data/users/sid0/fbandroid-from-git -i --debug
```
Saw that the last line printed out was `1fe73e73af4acadf1865a41e3aaa518a70cc2302`, as expected.
Reviewers: dschleimer, akushner, davidsp, pyd, mpm, durham
Reviewed By: durham
Subscribers: pradvenkat, akshay, thawan
Differential Revision: https://phabricator.fb.com/D1330813
Tasks: 3751836
2014-05-15 03:17:25 +04:00
|
|
|
|
2017-05-22 23:38:37 +03:00
|
|
|
from mercurial import bundle2, exchange, encoding, extensions, hg
|
|
|
|
from mercurial import localrepo, util, wireproto, error, registrar
|
2017-09-14 03:17:55 +03:00
|
|
|
from mercurial.node import bin, hex, nullid
|
add a command and server-side support to fetch git metadata
Summary:
When a machine is newly set up, it needs to have the git mapfile available. Generating it from scratch is prohibitively slow for large repos like `configerator`, so instead add a command that can download the entire git metadata from a server that has it.
This is a temporary hack while I work on a real fix to upstream to hg-git. A real fix would be
- part of hg-git
- not send the entire git metadata over, just the bits that are needed based on a common/heads computation
- be dependent on bundle2
- (probably) be part of the pull operation, not a separate command
- be configurable with an option
This isn't part of hg-git, even in a private branch, to emphasize its temporary nature. `gitlookup` might also not be the best fit, but I want to avoid adding yet another extension for a temporary hack.
Test Plan:
Ran the following commands. Note that the current version of `hg` deployed to devservers is broken, so we need to deploy an updated hg before enabling this. These commands were tested against 1ced7c762592
(in `fbandroid-hg`, with `gitlookup` enabled on both ends and the remotefilelog fix in D1341059)
hg gitgetmeta ../fbandroid-from-git
Saw that 3 files were written out.
hg gitgetmeta ssh://localhost//data/users/sid0/fbandroid-from-git
Saw that 3 files were written out.
Reviewers: dschleimer, davidsp, akushner, durham, pyd
Reviewed By: pyd
Differential Revision: https://phabricator.fb.com/D1341166
Tasks: 3751836
2014-05-21 09:32:54 +04:00
|
|
|
from mercurial.i18n import _
|
2017-09-14 03:17:55 +03:00
|
|
|
import errno, json
|
add a command and server-side support to fetch git metadata
Summary:
When a machine is newly set up, it needs to have the git mapfile available. Generating it from scratch is prohibitively slow for large repos like `configerator`, so instead add a command that can download the entire git metadata from a server that has it.
This is a temporary hack while I work on a real fix to upstream to hg-git. A real fix would be
- part of hg-git
- not send the entire git metadata over, just the bits that are needed based on a common/heads computation
- be dependent on bundle2
- (probably) be part of the pull operation, not a separate command
- be configurable with an option
This isn't part of hg-git, even in a private branch, to emphasize its temporary nature. `gitlookup` might also not be the best fit, but I want to avoid adding yet another extension for a temporary hack.
Test Plan:
Ran the following commands. Note that the current version of `hg` deployed to devservers is broken, so we need to deploy an updated hg before enabling this. These commands were tested against 1ced7c762592
(in `fbandroid-hg`, with `gitlookup` enabled on both ends and the remotefilelog fix in D1341059)
hg gitgetmeta ../fbandroid-from-git
Saw that 3 files were written out.
hg gitgetmeta ssh://localhost//data/users/sid0/fbandroid-from-git
Saw that 3 files were written out.
Reviewers: dschleimer, davidsp, akushner, durham, pyd
Reviewed By: pyd
Differential Revision: https://phabricator.fb.com/D1341166
Tasks: 3751836
2014-05-21 09:32:54 +04:00
|
|
|
|
|
|
|
cmdtable = {}
|
2017-05-22 23:38:37 +03:00
|
|
|
command = registrar.command(cmdtable)
|
add an extension that allows server-side hg->git and git->hg lookups
Summary:
This is a massive hack until Dewey becomes capable of answering these questions.
The plan is to use these commands in `arc diff` and `arc patch` to send the Git versions of the base commit over, so that the diff and land infra reaches parity with Git.
This should also unblock configerator-hg and allow the landing strip to work.
Test Plan:
In my `fbandroid-from-git` repo, enabled this extension, and then added the config:
```
[gitlookup]
mapfile = git-mapfile
```
Then, ran
```
hg id -r _gitlookup_hg_1fe73e73af4acadf1865a41e3aaa518a70cc2302 ssh://localhost//data/users/sid0/fbandroid-from-git -i --debug
```
Saw that the last line printed out was `76327beadc98c7c0559cd8aa36f0a25d93d781a5`, the Git equivalent of that commit.
After this, ran
```
hg id -r _gitlookup_git_76327beadc98c7c0559cd8aa36f0a25d93d781a5 ssh://localhost/data/users/sid0/fbandroid-from-git -i --debug
```
Saw that the last line printed out was `1fe73e73af4acadf1865a41e3aaa518a70cc2302`, as expected.
Reviewers: dschleimer, akushner, davidsp, pyd, mpm, durham
Reviewed By: durham
Subscribers: pradvenkat, akshay, thawan
Differential Revision: https://phabricator.fb.com/D1330813
Tasks: 3751836
2014-05-15 03:17:25 +04:00
|
|
|
|
|
|
|
def wrapwireprotocommand(command, wrapper):
|
|
|
|
'''Wrap the wire proto command named `command' in table
|
|
|
|
|
|
|
|
Just like extensions.wrapcommand, except for wire protocol commands.
|
|
|
|
'''
|
|
|
|
assert util.safehasattr(wrapper, '__call__')
|
|
|
|
origfn, args = wireproto.commands[command]
|
|
|
|
def wrap(*args, **kwargs):
|
|
|
|
return util.checksignature(wrapper)(
|
|
|
|
util.checksignature(origfn), *args, **kwargs)
|
|
|
|
wireproto.commands[command] = wrap, args
|
|
|
|
return wrapper
|
|
|
|
|
|
|
|
def remotelookup(orig, repo, proto, key):
|
|
|
|
k = encoding.tolocal(key)
|
|
|
|
if k.startswith('_gitlookup_'):
|
|
|
|
ret = _dolookup(repo, k)
|
|
|
|
if ret is not None:
|
|
|
|
success = 1
|
|
|
|
return '%s %s\n' % (success, ret)
|
|
|
|
return orig(repo, proto, key)
|
|
|
|
|
2017-03-29 17:13:41 +03:00
|
|
|
def locallookup(orig, repo, key):
|
|
|
|
gitlookup = _dolookup(repo, key)
|
|
|
|
if gitlookup:
|
|
|
|
return bin(gitlookup)
|
|
|
|
else:
|
|
|
|
return orig(repo, key)
|
|
|
|
|
add an extension that allows server-side hg->git and git->hg lookups
Summary:
This is a massive hack until Dewey becomes capable of answering these questions.
The plan is to use these commands in `arc diff` and `arc patch` to send the Git versions of the base commit over, so that the diff and land infra reaches parity with Git.
This should also unblock configerator-hg and allow the landing strip to work.
Test Plan:
In my `fbandroid-from-git` repo, enabled this extension, and then added the config:
```
[gitlookup]
mapfile = git-mapfile
```
Then, ran
```
hg id -r _gitlookup_hg_1fe73e73af4acadf1865a41e3aaa518a70cc2302 ssh://localhost//data/users/sid0/fbandroid-from-git -i --debug
```
Saw that the last line printed out was `76327beadc98c7c0559cd8aa36f0a25d93d781a5`, the Git equivalent of that commit.
After this, ran
```
hg id -r _gitlookup_git_76327beadc98c7c0559cd8aa36f0a25d93d781a5 ssh://localhost/data/users/sid0/fbandroid-from-git -i --debug
```
Saw that the last line printed out was `1fe73e73af4acadf1865a41e3aaa518a70cc2302`, as expected.
Reviewers: dschleimer, akushner, davidsp, pyd, mpm, durham
Reviewed By: durham
Subscribers: pradvenkat, akshay, thawan
Differential Revision: https://phabricator.fb.com/D1330813
Tasks: 3751836
2014-05-15 03:17:25 +04:00
|
|
|
def _dolookup(repo, key):
|
|
|
|
mapfile = repo.ui.configpath('gitlookup', 'mapfile')
|
|
|
|
if mapfile is None:
|
|
|
|
return None
|
2017-04-04 11:04:40 +03:00
|
|
|
if not isinstance(key, str):
|
|
|
|
return None
|
add an extension that allows server-side hg->git and git->hg lookups
Summary:
This is a massive hack until Dewey becomes capable of answering these questions.
The plan is to use these commands in `arc diff` and `arc patch` to send the Git versions of the base commit over, so that the diff and land infra reaches parity with Git.
This should also unblock configerator-hg and allow the landing strip to work.
Test Plan:
In my `fbandroid-from-git` repo, enabled this extension, and then added the config:
```
[gitlookup]
mapfile = git-mapfile
```
Then, ran
```
hg id -r _gitlookup_hg_1fe73e73af4acadf1865a41e3aaa518a70cc2302 ssh://localhost//data/users/sid0/fbandroid-from-git -i --debug
```
Saw that the last line printed out was `76327beadc98c7c0559cd8aa36f0a25d93d781a5`, the Git equivalent of that commit.
After this, ran
```
hg id -r _gitlookup_git_76327beadc98c7c0559cd8aa36f0a25d93d781a5 ssh://localhost/data/users/sid0/fbandroid-from-git -i --debug
```
Saw that the last line printed out was `1fe73e73af4acadf1865a41e3aaa518a70cc2302`, as expected.
Reviewers: dschleimer, akushner, davidsp, pyd, mpm, durham
Reviewed By: durham
Subscribers: pradvenkat, akshay, thawan
Differential Revision: https://phabricator.fb.com/D1330813
Tasks: 3751836
2014-05-15 03:17:25 +04:00
|
|
|
# direction: git to hg = g, hg to git = h
|
|
|
|
if key.startswith('_gitlookup_git_'):
|
|
|
|
direction = 'tohg'
|
|
|
|
sha = key[15:]
|
|
|
|
elif key.startswith('_gitlookup_hg_'):
|
|
|
|
direction = 'togit'
|
|
|
|
sha = key[14:]
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
hggitmap = open(mapfile, 'rb')
|
|
|
|
for line in hggitmap:
|
|
|
|
gitsha, hgsha = line.strip().split(' ', 1)
|
|
|
|
if direction == 'tohg' and sha == gitsha:
|
|
|
|
return hgsha
|
|
|
|
if direction == 'togit' and sha == hgsha:
|
|
|
|
return gitsha
|
|
|
|
return None
|
|
|
|
|
add a command and server-side support to fetch git metadata
Summary:
When a machine is newly set up, it needs to have the git mapfile available. Generating it from scratch is prohibitively slow for large repos like `configerator`, so instead add a command that can download the entire git metadata from a server that has it.
This is a temporary hack while I work on a real fix to upstream to hg-git. A real fix would be
- part of hg-git
- not send the entire git metadata over, just the bits that are needed based on a common/heads computation
- be dependent on bundle2
- (probably) be part of the pull operation, not a separate command
- be configurable with an option
This isn't part of hg-git, even in a private branch, to emphasize its temporary nature. `gitlookup` might also not be the best fit, but I want to avoid adding yet another extension for a temporary hack.
Test Plan:
Ran the following commands. Note that the current version of `hg` deployed to devservers is broken, so we need to deploy an updated hg before enabling this. These commands were tested against 1ced7c762592
(in `fbandroid-hg`, with `gitlookup` enabled on both ends and the remotefilelog fix in D1341059)
hg gitgetmeta ../fbandroid-from-git
Saw that 3 files were written out.
hg gitgetmeta ssh://localhost//data/users/sid0/fbandroid-from-git
Saw that 3 files were written out.
Reviewers: dschleimer, davidsp, akushner, durham, pyd
Reviewed By: pyd
Differential Revision: https://phabricator.fb.com/D1341166
Tasks: 3751836
2014-05-21 09:32:54 +04:00
|
|
|
@command('gitgetmeta', [], '[SOURCE]')
|
|
|
|
def gitgetmeta(ui, repo, source='default'):
|
|
|
|
'''get git metadata from a server that supports fb_gitmeta'''
|
|
|
|
source, branch = hg.parseurl(ui.expandpath(source))
|
|
|
|
other = hg.peer(repo, {}, source)
|
|
|
|
ui.status(_('getting git metadata from %s\n') %
|
|
|
|
util.hidepassword(source))
|
2017-09-14 03:17:55 +03:00
|
|
|
|
2015-04-23 00:49:20 +03:00
|
|
|
kwargs = {'bundlecaps': exchange.caps20to10(repo)}
|
2014-09-18 03:40:37 +04:00
|
|
|
capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
|
2017-09-14 03:17:55 +03:00
|
|
|
kwargs['bundlecaps'].add('bundle2=' + util.urlreq.quote(capsblob))
|
add a command and server-side support to fetch git metadata
Summary:
When a machine is newly set up, it needs to have the git mapfile available. Generating it from scratch is prohibitively slow for large repos like `configerator`, so instead add a command that can download the entire git metadata from a server that has it.
This is a temporary hack while I work on a real fix to upstream to hg-git. A real fix would be
- part of hg-git
- not send the entire git metadata over, just the bits that are needed based on a common/heads computation
- be dependent on bundle2
- (probably) be part of the pull operation, not a separate command
- be configurable with an option
This isn't part of hg-git, even in a private branch, to emphasize its temporary nature. `gitlookup` might also not be the best fit, but I want to avoid adding yet another extension for a temporary hack.
Test Plan:
Ran the following commands. Note that the current version of `hg` deployed to devservers is broken, so we need to deploy an updated hg before enabling this. These commands were tested against 1ced7c762592
(in `fbandroid-hg`, with `gitlookup` enabled on both ends and the remotefilelog fix in D1341059)
hg gitgetmeta ../fbandroid-from-git
Saw that 3 files were written out.
hg gitgetmeta ssh://localhost//data/users/sid0/fbandroid-from-git
Saw that 3 files were written out.
Reviewers: dschleimer, davidsp, akushner, durham, pyd
Reviewed By: pyd
Differential Revision: https://phabricator.fb.com/D1341166
Tasks: 3751836
2014-05-21 09:32:54 +04:00
|
|
|
# this would ideally not be in the bundlecaps at all, but adding new kwargs
|
|
|
|
# for wire transmissions is not possible as of Mercurial d19164a018a1
|
|
|
|
kwargs['bundlecaps'].add('fb_gitmeta')
|
|
|
|
kwargs['heads'] = [nullid]
|
2014-09-18 03:40:37 +04:00
|
|
|
kwargs['cg'] = False
|
2017-09-14 03:17:55 +03:00
|
|
|
kwargs['common'] = _getcommonheads(repo)
|
add a command and server-side support to fetch git metadata
Summary:
When a machine is newly set up, it needs to have the git mapfile available. Generating it from scratch is prohibitively slow for large repos like `configerator`, so instead add a command that can download the entire git metadata from a server that has it.
This is a temporary hack while I work on a real fix to upstream to hg-git. A real fix would be
- part of hg-git
- not send the entire git metadata over, just the bits that are needed based on a common/heads computation
- be dependent on bundle2
- (probably) be part of the pull operation, not a separate command
- be configurable with an option
This isn't part of hg-git, even in a private branch, to emphasize its temporary nature. `gitlookup` might also not be the best fit, but I want to avoid adding yet another extension for a temporary hack.
Test Plan:
Ran the following commands. Note that the current version of `hg` deployed to devservers is broken, so we need to deploy an updated hg before enabling this. These commands were tested against 1ced7c762592
(in `fbandroid-hg`, with `gitlookup` enabled on both ends and the remotefilelog fix in D1341059)
hg gitgetmeta ../fbandroid-from-git
Saw that 3 files were written out.
hg gitgetmeta ssh://localhost//data/users/sid0/fbandroid-from-git
Saw that 3 files were written out.
Reviewers: dschleimer, davidsp, akushner, durham, pyd
Reviewed By: pyd
Differential Revision: https://phabricator.fb.com/D1341166
Tasks: 3751836
2014-05-21 09:32:54 +04:00
|
|
|
bundle = other.getbundle('pull', **kwargs)
|
|
|
|
try:
|
|
|
|
op = bundle2.processbundle(repo, bundle)
|
2016-01-08 05:30:24 +03:00
|
|
|
except error.BundleValueError as exc:
|
2016-01-08 05:30:24 +03:00
|
|
|
raise error.Abort('missing support for %s' % exc)
|
add a command and server-side support to fetch git metadata
Summary:
When a machine is newly set up, it needs to have the git mapfile available. Generating it from scratch is prohibitively slow for large repos like `configerator`, so instead add a command that can download the entire git metadata from a server that has it.
This is a temporary hack while I work on a real fix to upstream to hg-git. A real fix would be
- part of hg-git
- not send the entire git metadata over, just the bits that are needed based on a common/heads computation
- be dependent on bundle2
- (probably) be part of the pull operation, not a separate command
- be configurable with an option
This isn't part of hg-git, even in a private branch, to emphasize its temporary nature. `gitlookup` might also not be the best fit, but I want to avoid adding yet another extension for a temporary hack.
Test Plan:
Ran the following commands. Note that the current version of `hg` deployed to devservers is broken, so we need to deploy an updated hg before enabling this. These commands were tested against 1ced7c762592
(in `fbandroid-hg`, with `gitlookup` enabled on both ends and the remotefilelog fix in D1341059)
hg gitgetmeta ../fbandroid-from-git
Saw that 3 files were written out.
hg gitgetmeta ssh://localhost//data/users/sid0/fbandroid-from-git
Saw that 3 files were written out.
Reviewers: dschleimer, davidsp, akushner, durham, pyd
Reviewed By: pyd
Differential Revision: https://phabricator.fb.com/D1341166
Tasks: 3751836
2014-05-21 09:32:54 +04:00
|
|
|
writebytes = op.records['fb:gitmeta:writebytes']
|
|
|
|
ui.status(_('wrote %d files (%d bytes)\n') %
|
|
|
|
(len(writebytes), sum(writebytes)))
|
|
|
|
|
2017-09-14 03:17:55 +03:00
|
|
|
hgheadsfile = 'git-synced-hgheads'
|
|
|
|
gitmapfile = 'git-mapfile'
|
|
|
|
gitmetafiles = set(
|
|
|
|
[gitmapfile, 'git-named-branches', 'git-tags', 'git-remote-refs'])
|
add a command and server-side support to fetch git metadata
Summary:
When a machine is newly set up, it needs to have the git mapfile available. Generating it from scratch is prohibitively slow for large repos like `configerator`, so instead add a command that can download the entire git metadata from a server that has it.
This is a temporary hack while I work on a real fix to upstream to hg-git. A real fix would be
- part of hg-git
- not send the entire git metadata over, just the bits that are needed based on a common/heads computation
- be dependent on bundle2
- (probably) be part of the pull operation, not a separate command
- be configurable with an option
This isn't part of hg-git, even in a private branch, to emphasize its temporary nature. `gitlookup` might also not be the best fit, but I want to avoid adding yet another extension for a temporary hack.
Test Plan:
Ran the following commands. Note that the current version of `hg` deployed to devservers is broken, so we need to deploy an updated hg before enabling this. These commands were tested against 1ced7c762592
(in `fbandroid-hg`, with `gitlookup` enabled on both ends and the remotefilelog fix in D1341059)
hg gitgetmeta ../fbandroid-from-git
Saw that 3 files were written out.
hg gitgetmeta ssh://localhost//data/users/sid0/fbandroid-from-git
Saw that 3 files were written out.
Reviewers: dschleimer, davidsp, akushner, durham, pyd
Reviewed By: pyd
Differential Revision: https://phabricator.fb.com/D1341166
Tasks: 3751836
2014-05-21 09:32:54 +04:00
|
|
|
|
2017-09-14 03:17:55 +03:00
|
|
|
def _getfile(repo, filename):
|
|
|
|
try:
|
|
|
|
return repo.vfs(filename)
|
|
|
|
except (IOError, OSError) as e:
|
|
|
|
if e.errno != errno.ENOENT:
|
|
|
|
repo.ui.warn(_("warning: unable to read %s: %s\n") % (filename, e))
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
2017-09-14 03:17:55 +03:00
|
|
|
def _getcommonheads(repo):
|
|
|
|
commonheads = []
|
|
|
|
f = _getfile(repo, hgheadsfile)
|
|
|
|
if f:
|
|
|
|
commonheads = f.readlines()
|
|
|
|
commonheads = [bin(x.strip()) for x in commonheads]
|
|
|
|
return commonheads
|
|
|
|
|
|
|
|
def _isheadmissing(repo, heads):
|
|
|
|
return not all(repo.known(heads))
|
|
|
|
|
|
|
|
def _getmissinglines(mapfile, missinghashes):
|
|
|
|
missinglines = set()
|
|
|
|
|
|
|
|
# Avoid expensive lookup through the map file if there is no missing hash.
|
|
|
|
if not missinghashes:
|
|
|
|
return missinglines
|
|
|
|
|
|
|
|
hashestofind = missinghashes.copy()
|
|
|
|
for line in mapfile:
|
|
|
|
gitsha, hgsha = line.strip().split(' ', 1)
|
|
|
|
if hgsha in hashestofind:
|
|
|
|
missinglines.add(line)
|
|
|
|
|
|
|
|
# Return the missing lines if we found all of them.
|
|
|
|
hashestofind.remove(hgsha)
|
|
|
|
if not hashestofind:
|
|
|
|
return missinglines
|
|
|
|
|
|
|
|
raise error.Abort(_('gitmeta: missing hashes in file %s') % mapfile.name)
|
|
|
|
|
|
|
|
class _githgmappayload(object):
|
|
|
|
def __init__(self, needfullsync, newheads, missinglines):
|
|
|
|
self.needfullsync = needfullsync
|
|
|
|
self.newheads = newheads
|
|
|
|
self.missinglines = missinglines
|
|
|
|
|
|
|
|
def _todict(self):
|
|
|
|
d = {}
|
|
|
|
d['needfullsync'] = self.needfullsync
|
|
|
|
d['newheads'] = list(self.newheads)
|
|
|
|
d['missinglines'] = list(self.missinglines)
|
|
|
|
return d
|
|
|
|
|
|
|
|
def tojson(self):
|
|
|
|
return json.dumps(self._todict())
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def _fromdict(cls, d):
|
|
|
|
needfullsync = d['needfullsync']
|
|
|
|
newheads = set(d['newheads'])
|
|
|
|
missinglines = set(d['missinglines'])
|
|
|
|
return cls(needfullsync, newheads, missinglines)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def fromjson(cls, jsonstr):
|
|
|
|
d = json.loads(jsonstr)
|
|
|
|
return cls._fromdict(d)
|
|
|
|
|
|
|
|
@exchange.getbundle2partsgenerator('b2x:fb:gitmeta:githgmap')
|
|
|
|
def _getbundlegithgmappart(bundler, repo, source, bundlecaps=None, **kwargs):
|
|
|
|
'''send missing git to hg map data via bundle2'''
|
|
|
|
if 'fb_gitmeta' in bundlecaps:
|
|
|
|
# Do nothing if the config indicates serving the complete git-hg map
|
|
|
|
# file. _getbundlegitmetapart will handle serving the complete file in
|
|
|
|
# this case.
|
|
|
|
if not repo.ui.configbool('gitlookup', 'onlymapdelta', False):
|
|
|
|
return
|
|
|
|
|
|
|
|
mapfile = _getfile(repo, gitmapfile)
|
|
|
|
if not mapfile:
|
|
|
|
return
|
|
|
|
|
|
|
|
commonheads = kwargs['common']
|
|
|
|
|
|
|
|
# If there are missing heads, we will sync everything.
|
|
|
|
if _isheadmissing(repo, commonheads):
|
|
|
|
commonheads = []
|
|
|
|
|
|
|
|
needfullsync = (len(commonheads) == 0)
|
|
|
|
|
|
|
|
heads = repo.heads()
|
|
|
|
newheads = set(hex(head) for head in heads)
|
|
|
|
|
|
|
|
missingcommits = repo.changelog.findmissing(commonheads, heads)
|
|
|
|
missinghashes = set(hex(commit) for commit in missingcommits)
|
|
|
|
missinglines = _getmissinglines(mapfile, missinghashes)
|
|
|
|
|
|
|
|
payload = _githgmappayload(needfullsync, newheads, missinglines)
|
|
|
|
serializedpayload = payload.tojson()
|
|
|
|
part = bundle2.bundlepart(
|
|
|
|
'b2x:fb:gitmeta:githgmap',
|
|
|
|
[('filename', gitmapfile)],
|
|
|
|
data = serializedpayload
|
|
|
|
)
|
|
|
|
|
|
|
|
bundler.addpart(part)
|
|
|
|
|
2015-04-23 00:49:20 +03:00
|
|
|
@exchange.getbundle2partsgenerator('b2x:fb:gitmeta')
|
2014-10-08 05:19:17 +04:00
|
|
|
def _getbundlegitmetapart(bundler, repo, source, bundlecaps=None, **kwargs):
|
add a command and server-side support to fetch git metadata
Summary:
When a machine is newly set up, it needs to have the git mapfile available. Generating it from scratch is prohibitively slow for large repos like `configerator`, so instead add a command that can download the entire git metadata from a server that has it.
This is a temporary hack while I work on a real fix to upstream to hg-git. A real fix would be
- part of hg-git
- not send the entire git metadata over, just the bits that are needed based on a common/heads computation
- be dependent on bundle2
- (probably) be part of the pull operation, not a separate command
- be configurable with an option
This isn't part of hg-git, even in a private branch, to emphasize its temporary nature. `gitlookup` might also not be the best fit, but I want to avoid adding yet another extension for a temporary hack.
Test Plan:
Ran the following commands. Note that the current version of `hg` deployed to devservers is broken, so we need to deploy an updated hg before enabling this. These commands were tested against 1ced7c762592
(in `fbandroid-hg`, with `gitlookup` enabled on both ends and the remotefilelog fix in D1341059)
hg gitgetmeta ../fbandroid-from-git
Saw that 3 files were written out.
hg gitgetmeta ssh://localhost//data/users/sid0/fbandroid-from-git
Saw that 3 files were written out.
Reviewers: dschleimer, davidsp, akushner, durham, pyd
Reviewed By: pyd
Differential Revision: https://phabricator.fb.com/D1341166
Tasks: 3751836
2014-05-21 09:32:54 +04:00
|
|
|
'''send git metadata via bundle2'''
|
2014-10-08 05:19:17 +04:00
|
|
|
if 'fb_gitmeta' in bundlecaps:
|
2017-09-14 03:17:55 +03:00
|
|
|
filestooverwrite = gitmetafiles
|
|
|
|
|
|
|
|
# Exclude the git-hg map file if the config indicates that the server
|
|
|
|
# should only be serving the missing map data. _getbundle2partsgenerator
|
|
|
|
# will serve the missing map data in this case.
|
|
|
|
if repo.ui.configbool('gitlookup', 'onlymapdelta', False):
|
|
|
|
filestooverwrite = filestooverwrite - set([gitmapfile])
|
|
|
|
|
|
|
|
for fname in sorted(filestooverwrite):
|
2017-09-14 03:17:55 +03:00
|
|
|
f = _getfile(repo, fname)
|
|
|
|
if not f:
|
add a command and server-side support to fetch git metadata
Summary:
When a machine is newly set up, it needs to have the git mapfile available. Generating it from scratch is prohibitively slow for large repos like `configerator`, so instead add a command that can download the entire git metadata from a server that has it.
This is a temporary hack while I work on a real fix to upstream to hg-git. A real fix would be
- part of hg-git
- not send the entire git metadata over, just the bits that are needed based on a common/heads computation
- be dependent on bundle2
- (probably) be part of the pull operation, not a separate command
- be configurable with an option
This isn't part of hg-git, even in a private branch, to emphasize its temporary nature. `gitlookup` might also not be the best fit, but I want to avoid adding yet another extension for a temporary hack.
Test Plan:
Ran the following commands. Note that the current version of `hg` deployed to devservers is broken, so we need to deploy an updated hg before enabling this. These commands were tested against 1ced7c762592
(in `fbandroid-hg`, with `gitlookup` enabled on both ends and the remotefilelog fix in D1341059)
hg gitgetmeta ../fbandroid-from-git
Saw that 3 files were written out.
hg gitgetmeta ssh://localhost//data/users/sid0/fbandroid-from-git
Saw that 3 files were written out.
Reviewers: dschleimer, davidsp, akushner, durham, pyd
Reviewed By: pyd
Differential Revision: https://phabricator.fb.com/D1341166
Tasks: 3751836
2014-05-21 09:32:54 +04:00
|
|
|
continue
|
2017-09-14 03:17:55 +03:00
|
|
|
|
2015-04-23 00:49:20 +03:00
|
|
|
part = bundle2.bundlepart('b2x:fb:gitmeta',
|
add a command and server-side support to fetch git metadata
Summary:
When a machine is newly set up, it needs to have the git mapfile available. Generating it from scratch is prohibitively slow for large repos like `configerator`, so instead add a command that can download the entire git metadata from a server that has it.
This is a temporary hack while I work on a real fix to upstream to hg-git. A real fix would be
- part of hg-git
- not send the entire git metadata over, just the bits that are needed based on a common/heads computation
- be dependent on bundle2
- (probably) be part of the pull operation, not a separate command
- be configurable with an option
This isn't part of hg-git, even in a private branch, to emphasize its temporary nature. `gitlookup` might also not be the best fit, but I want to avoid adding yet another extension for a temporary hack.
Test Plan:
Ran the following commands. Note that the current version of `hg` deployed to devservers is broken, so we need to deploy an updated hg before enabling this. These commands were tested against 1ced7c762592
(in `fbandroid-hg`, with `gitlookup` enabled on both ends and the remotefilelog fix in D1341059)
hg gitgetmeta ../fbandroid-from-git
Saw that 3 files were written out.
hg gitgetmeta ssh://localhost//data/users/sid0/fbandroid-from-git
Saw that 3 files were written out.
Reviewers: dschleimer, davidsp, akushner, durham, pyd
Reviewed By: pyd
Differential Revision: https://phabricator.fb.com/D1341166
Tasks: 3751836
2014-05-21 09:32:54 +04:00
|
|
|
[('filename', fname)],
|
|
|
|
data=f.read())
|
|
|
|
bundler.addpart(part)
|
|
|
|
|
2017-09-14 03:17:55 +03:00
|
|
|
def _writefile(op, filename, data):
|
|
|
|
with op.repo.vfs(filename, 'w+', atomictemp=True) as f:
|
|
|
|
op.repo.ui.note(_('writing .hg/%s\n') % filename)
|
|
|
|
f.write(data)
|
|
|
|
op.records.add('fb:gitmeta:writebytes', len(data))
|
|
|
|
|
|
|
|
def _validatepartparams(op, params):
|
|
|
|
if 'filename' not in params:
|
|
|
|
raise error.Abort(_("gitmeta: 'filename' missing"))
|
|
|
|
|
|
|
|
fname = params['filename']
|
|
|
|
if fname not in gitmetafiles:
|
|
|
|
op.repo.ui.warn(
|
|
|
|
_("warning: gitmeta: unknown file '%s' skipped\n") % fname)
|
|
|
|
return False
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
2017-09-14 03:17:55 +03:00
|
|
|
@bundle2.parthandler('b2x:fb:gitmeta:githgmap', ('filename',))
|
|
|
|
@bundle2.parthandler('fb:gitmeta:githgmap', ('filename',))
|
|
|
|
def bundle2getgithgmap(op, part):
|
|
|
|
params = dict(part.mandatoryparams)
|
|
|
|
if _validatepartparams(op, params):
|
|
|
|
filename = params['filename']
|
|
|
|
with op.repo.wlock():
|
|
|
|
data = _githgmappayload.fromjson(part.read())
|
|
|
|
missinglines = data.missinglines
|
|
|
|
|
|
|
|
# No need to update anything if already in sync.
|
|
|
|
if not missinglines:
|
|
|
|
return
|
|
|
|
|
|
|
|
if data.needfullsync:
|
|
|
|
newlines = missinglines
|
|
|
|
else:
|
|
|
|
mapfile = _getfile(op.repo, filename)
|
|
|
|
if mapfile:
|
|
|
|
currentlines = set(mapfile.readlines())
|
|
|
|
if currentlines & missinglines:
|
|
|
|
msg = 'warning: gitmeta: unexpected lines in .hg/%s\n'
|
|
|
|
op.repo.ui.warn(_(msg) % filename)
|
|
|
|
|
|
|
|
currentlines.update(missinglines)
|
|
|
|
newlines = currentlines
|
|
|
|
else:
|
|
|
|
raise error.Abort(
|
|
|
|
_('gitmeta: could not read from .hg/%s') % filename)
|
|
|
|
|
|
|
|
_writefile(op, filename, ''.join(newlines))
|
|
|
|
_writefile(op, hgheadsfile, '\n'.join(data.newheads))
|
|
|
|
|
2015-04-23 00:49:20 +03:00
|
|
|
@bundle2.parthandler('b2x:fb:gitmeta', ('filename',))
|
2015-04-18 00:20:20 +03:00
|
|
|
@bundle2.parthandler('fb:gitmeta', ('filename',))
|
add a command and server-side support to fetch git metadata
Summary:
When a machine is newly set up, it needs to have the git mapfile available. Generating it from scratch is prohibitively slow for large repos like `configerator`, so instead add a command that can download the entire git metadata from a server that has it.
This is a temporary hack while I work on a real fix to upstream to hg-git. A real fix would be
- part of hg-git
- not send the entire git metadata over, just the bits that are needed based on a common/heads computation
- be dependent on bundle2
- (probably) be part of the pull operation, not a separate command
- be configurable with an option
This isn't part of hg-git, even in a private branch, to emphasize its temporary nature. `gitlookup` might also not be the best fit, but I want to avoid adding yet another extension for a temporary hack.
Test Plan:
Ran the following commands. Note that the current version of `hg` deployed to devservers is broken, so we need to deploy an updated hg before enabling this. These commands were tested against 1ced7c762592
(in `fbandroid-hg`, with `gitlookup` enabled on both ends and the remotefilelog fix in D1341059)
hg gitgetmeta ../fbandroid-from-git
Saw that 3 files were written out.
hg gitgetmeta ssh://localhost//data/users/sid0/fbandroid-from-git
Saw that 3 files were written out.
Reviewers: dschleimer, davidsp, akushner, durham, pyd
Reviewed By: pyd
Differential Revision: https://phabricator.fb.com/D1341166
Tasks: 3751836
2014-05-21 09:32:54 +04:00
|
|
|
def bundle2getgitmeta(op, part):
|
|
|
|
'''unbundle a bundle2 containing git metadata on the client'''
|
|
|
|
params = dict(part.mandatoryparams)
|
2017-09-14 03:17:55 +03:00
|
|
|
if _validatepartparams(op, params):
|
|
|
|
filename = params['filename']
|
|
|
|
with op.repo.wlock():
|
|
|
|
data = part.read()
|
|
|
|
_writefile(op, filename, data)
|
add a command and server-side support to fetch git metadata
Summary:
When a machine is newly set up, it needs to have the git mapfile available. Generating it from scratch is prohibitively slow for large repos like `configerator`, so instead add a command that can download the entire git metadata from a server that has it.
This is a temporary hack while I work on a real fix to upstream to hg-git. A real fix would be
- part of hg-git
- not send the entire git metadata over, just the bits that are needed based on a common/heads computation
- be dependent on bundle2
- (probably) be part of the pull operation, not a separate command
- be configurable with an option
This isn't part of hg-git, even in a private branch, to emphasize its temporary nature. `gitlookup` might also not be the best fit, but I want to avoid adding yet another extension for a temporary hack.
Test Plan:
Ran the following commands. Note that the current version of `hg` deployed to devservers is broken, so we need to deploy an updated hg before enabling this. These commands were tested against 1ced7c762592
(in `fbandroid-hg`, with `gitlookup` enabled on both ends and the remotefilelog fix in D1341059)
hg gitgetmeta ../fbandroid-from-git
Saw that 3 files were written out.
hg gitgetmeta ssh://localhost//data/users/sid0/fbandroid-from-git
Saw that 3 files were written out.
Reviewers: dschleimer, davidsp, akushner, durham, pyd
Reviewed By: pyd
Differential Revision: https://phabricator.fb.com/D1341166
Tasks: 3751836
2014-05-21 09:32:54 +04:00
|
|
|
|
add an extension that allows server-side hg->git and git->hg lookups
Summary:
This is a massive hack until Dewey becomes capable of answering these questions.
The plan is to use these commands in `arc diff` and `arc patch` to send the Git versions of the base commit over, so that the diff and land infra reaches parity with Git.
This should also unblock configerator-hg and allow the landing strip to work.
Test Plan:
In my `fbandroid-from-git` repo, enabled this extension, and then added the config:
```
[gitlookup]
mapfile = git-mapfile
```
Then, ran
```
hg id -r _gitlookup_hg_1fe73e73af4acadf1865a41e3aaa518a70cc2302 ssh://localhost//data/users/sid0/fbandroid-from-git -i --debug
```
Saw that the last line printed out was `76327beadc98c7c0559cd8aa36f0a25d93d781a5`, the Git equivalent of that commit.
After this, ran
```
hg id -r _gitlookup_git_76327beadc98c7c0559cd8aa36f0a25d93d781a5 ssh://localhost/data/users/sid0/fbandroid-from-git -i --debug
```
Saw that the last line printed out was `1fe73e73af4acadf1865a41e3aaa518a70cc2302`, as expected.
Reviewers: dschleimer, akushner, davidsp, pyd, mpm, durham
Reviewed By: durham
Subscribers: pradvenkat, akshay, thawan
Differential Revision: https://phabricator.fb.com/D1330813
Tasks: 3751836
2014-05-15 03:17:25 +04:00
|
|
|
def extsetup(ui):
|
|
|
|
wrapwireprotocommand('lookup', remotelookup)
|
2017-03-29 17:13:41 +03:00
|
|
|
extensions.wrapfunction(localrepo.localrepository, 'lookup', locallookup)
|