Backed out changeset b4a7055ecf04

This commit is contained in:
Durham Goode 2015-10-16 12:30:38 -07:00
parent 7ebb123c54
commit fd063c11c1
2 changed files with 315 additions and 0 deletions

175
tests/test-writecg2.t Normal file
View File

@ -0,0 +1,175 @@
$ cat >> $HGRCPATH <<EOF
> [extensions]
> strip =
> writecg2 = $TESTDIR/../writecg2.py
> EOF
$ hg init repo
$ cd repo
$ touch a && hg add a && hg ci -ma
$ touch b && hg add b && hg ci -mb
$ touch c && hg add c && hg ci -mc
$ hg log -T compact --graph
@ 2[tip] 991a3460af53 1970-01-01 00:00 +0000 test
| c
|
o 1 0e067c57feba 1970-01-01 00:00 +0000 test
| b
|
o 0 3903775176ed 1970-01-01 00:00 +0000 test
a
unbundle should barf appropriately on not-a-bundle
$ echo GIT123 > ../notabundle
$ hg unbundle ../notabundle
abort: ../notabundle: not a Mercurial bundle
[255]
bundle by itself shouldn't be changegroup2
$ hg bundle --base 0 --rev 2 ../bundle.bundle
2 changesets found
$ head -c 6 ../bundle.bundle
HG10BZ (no-eol)
a strip bundle should be changegroup2
$ hg strip 1
0 files updated, 0 files merged, 2 files removed, 0 files unresolved
saved backup bundle to $TESTTMP/repo/.hg/strip-backup/0e067c57feba-3c242e3d-backup.hg (glob)
$ head -c 6 .hg/strip-backup/0e067c57feba-3c242e3d-backup.hg
HG2CBZ (no-eol)
applying bundle1 should continue to work
$ hg unbundle ../bundle.bundle
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 2 files
(run 'hg update' to get a working copy)
$ hg log -T compact --graph
o 2[tip] 991a3460af53 1970-01-01 00:00 +0000 test
| c
|
o 1 0e067c57feba 1970-01-01 00:00 +0000 test
| b
|
@ 0 3903775176ed 1970-01-01 00:00 +0000 test
a
... and via pull
$ hg strip 1
saved backup bundle to $TESTTMP/repo/.hg/strip-backup/0e067c57feba-3c242e3d-backup.hg (glob)
$ hg pull ../bundle.bundle
pulling from ../bundle.bundle
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 2 files
(run 'hg update' to get a working copy)
$ hg strip 1
saved backup bundle to $TESTTMP/repo/.hg/strip-backup/0e067c57feba-3c242e3d-backup.hg (glob)
$ head -c 6 .hg/strip-backup/0e067c57feba-3c242e3d-backup.hg
HG2CBZ (no-eol)
hg incoming on a changegroup2 should work
$ hg incoming .hg/strip-backup/0e067c57feba-3c242e3d-backup.hg --traceback
comparing with .hg/strip-backup/0e067c57feba-3c242e3d-backup.hg
searching for changes
changeset: 1:0e067c57feba
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: b
changeset: 2:991a3460af53
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: c
applying a changegroup2 should work via unbundle
$ hg unbundle .hg/strip-backup/0e067c57feba-3c242e3d-backup.hg
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 2 files
(run 'hg update' to get a working copy)
... and via pull
$ hg strip 1
saved backup bundle to $TESTTMP/repo/.hg/strip-backup/0e067c57feba-3c242e3d-backup.hg (glob)
$ head -c 6 .hg/strip-backup/0e067c57feba-3c242e3d-backup.hg
HG2CBZ (no-eol)
$ hg pull .hg/strip-backup/0e067c57feba-3c242e3d-backup.hg
pulling from .hg/strip-backup/0e067c57feba-3c242e3d-backup.hg
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 2 files
(run 'hg update' to get a working copy)
amends should also be cg2
$ hg up 2
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ touch d && hg add d && hg ci --amend -mcd
saved backup bundle to $TESTTMP/repo/.hg/strip-backup/991a3460af53-046ba7e5-amend-backup.hg (glob)
$ head -c 6 .hg/strip-backup/991a3460af53-046ba7e5-amend-backup.hg
HG2CBZ (no-eol)
turn on bundle2
$ cat >> $HGRCPATH <<EOF
> [experimental]
> bundle2-exp = True
> strip-bundle2-version = 02
> EOF
incoming should still work
$ hg incoming .hg/strip-backup/991a3460af53-046ba7e5-amend-backup.hg
comparing with .hg/strip-backup/991a3460af53-046ba7e5-amend-backup.hg
searching for changes
changeset: 3:991a3460af53
parent: 1:0e067c57feba
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: c
changeset: 4:e5a1db54cb59
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: temporary amend commit for 991a3460af53
strip should produce bundle2
$ hg strip 1
0 files updated, 0 files merged, 3 files removed, 0 files unresolved
saved backup bundle to $TESTTMP/repo/.hg/strip-backup/0e067c57feba-1954568c-backup.hg (glob)
$ hg debugbundle .hg/strip-backup/0e067c57feba-1954568c-backup.hg
Stream params: {}
changegroup -- "{'version': '02'}"
0e067c57feba1a5694ca4844f05588bb1bf82342
b2a74d690cb63a443d20de84bdc9eb5a7ddbedac
$ hg incoming .hg/strip-backup/0e067c57feba-1954568c-backup.hg
comparing with .hg/strip-backup/0e067c57feba-1954568c-backup.hg
searching for changes
changeset: 1:0e067c57feba
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: b
changeset: 2:b2a74d690cb6
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: cd
$ hg pull .hg/strip-backup/0e067c57feba-1954568c-backup.hg
pulling from .hg/strip-backup/0e067c57feba-1954568c-backup.hg
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 3 changes to 3 files
(run 'hg update' to get a working copy)

140
writecg2.py Normal file
View File

@ -0,0 +1,140 @@
# writecg2.py -- write changegroup2 to disk
#
# Copyright 2004-present Facebook.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
'''write changegroup2 to disk
For histories with lots of interleaved branches stored with generaldelta,
bundle1 can be extremely slow to generate. This extension modifies Mercurial to
read and write changegroup2s to disk.
'''
from mercurial import bundle2
from mercurial import bundlerepo
from mercurial import changegroup
from mercurial import discovery
from mercurial import error
from mercurial import exchange
from mercurial import extensions
from mercurial import localrepo
from mercurial import phases
from mercurial import util
from mercurial.i18n import _
from mercurial.node import nullid
import os
import tempfile
def overridewritebundle(orig, ui, cg, filename, bundletype, vfs=None):
if (bundletype.startswith('HG10') and
isinstance(cg, changegroup.cg2unpacker)):
bundletype = 'HG2C' + bundletype[4:]
return orig(ui, cg, filename, bundletype, vfs=vfs)
def overridechangegroupsubset(orig, repo, roots, heads, source, version = '01'):
# we only care about performance for strips, not about 'hg bundle' and
# similar
if source != 'strip' or version != '01':
return orig(repo, roots, heads, source, version=version)
# below is all copied from changegroup.py, except with cg1 changed to
# cg2
cl = repo.changelog
if not roots:
roots = [nullid]
discbases = []
for n in roots:
discbases.extend([p for p in cl.parents(n) if p != nullid])
# TODO: remove call to nodesbetween.
csets, roots, heads = cl.nodesbetween(roots, heads)
included = set(csets)
discbases = [n for n in discbases if n not in included]
outgoing = discovery.outgoing(cl, discbases, heads)
# use packermap because other extensions might override it
bundler = changegroup.packermap['02'][0](repo)
gengroup = changegroup.getsubsetraw(repo, outgoing, bundler, source,
fastpath=False)
result = changegroup.cg2unpacker(util.chunkbuffer(gengroup), 'UN')
result.version = '01' # needed to pass writebundle checks
return result
def overridereadbundle(orig, ui, fh, fname, vfs=None):
# copied from exchange.py
header = changegroup.readexactly(fh, 4)
alg = None
if not fname:
fname = "stream"
if not header.startswith('HG') and header.startswith('\0'):
fh = changegroup.headerlessfixup(fh, header)
header = "HG10"
alg = 'UN'
elif vfs:
fname = vfs.join(fname)
magic, version = header[0:2], header[2:4]
if magic != 'HG':
raise util.Abort(_('%s: not a Mercurial bundle') % fname)
if version == '10' or version == '2C':
if alg is None:
alg = changegroup.readexactly(fh, 2)
if version == '10':
return changegroup.cg1unpacker(fh, alg)
else:
return changegroup.cg2unpacker(fh, alg)
elif version == '20':
return bundle2.unbundle20(ui, fh)
else:
raise util.Abort(_('%s: unknown bundle version %s') % (fname, version))
class cg2bundlerepository(bundlerepo.bundlerepository):
def __init__(self, ui, path, bundlename):
self.cg2temp = None
f = util.posixfile(bundlename, "rb")
bundle = exchange.readbundle(ui, f, bundlename)
if bundle.compressed and isinstance(bundle, changegroup.cg2unpacker):
fdtemp, bundlename = tempfile.mkstemp(prefix="hg-bundle-",
suffix=".hgun")
self.cg2temp = bundlename
fptemp = os.fdopen(fdtemp, 'wb')
try:
fptemp.write("HG2CUN")
while True:
chunk = bundle.read(2**18)
if not chunk:
break
fptemp.write(chunk)
finally:
fptemp.close()
pass
f.close()
super(cg2bundlerepository, self).__init__(ui, path, bundlename)
def close(self):
super(cg2bundlerepository, self).close()
if self.cg2temp:
os.unlink(self.cg2temp)
bundlerepo.bundlerepository = cg2bundlerepository
def extsetup(ui):
# add bundle types for changegroup2
bundletypes = changegroup.bundletypes
cg2types = {}
for bundletype, hc in bundletypes.iteritems():
if bundletype.startswith('HG10'):
header, compressor = hc
cg2type = 'HG2C' + bundletype[4:]
cg2header = 'HG2C' + header[4:]
cg2types[cg2type] = (cg2header, compressor)
bundletypes.update(cg2types)
extensions.wrapfunction(changegroup, 'writebundle', overridewritebundle)
extensions.wrapfunction(changegroup, 'changegroupsubset',
overridechangegroupsubset)
extensions.wrapfunction(exchange, 'readbundle', overridereadbundle)