comparison mercurial/changegroup.py @ 28666:ae53ecc47414

bundle: move writebundle() from changegroup.py to bundle2.py (API) writebundle() writes a bundle2 bundle or a plain changegroup1. Imagine away the "2" in "bundle2.py" for a moment and this change should makes sense. The bundle wraps the changegroup, so it makes sense that it knows about it. Another sign that this is correct is that the delayed import of bundle2 in changegroup goes away. I'll leave it for another time to remove the "2" in "bundle2.py" (alternatively, extract a new bundle.py from it).
author Martin von Zweigbergk <martinvonz@google.com>
date Mon, 28 Mar 2016 14:41:29 -0700
parents 1f94ef2bd88d
children 1b7d907ec18a
comparison
equal deleted inserted replaced
28655:0e330d7d9f53 28666:ae53ecc47414
77 if changedheads > 0: 77 if changedheads > 0:
78 result = 1 + changedheads 78 result = 1 + changedheads
79 elif changedheads < 0: 79 elif changedheads < 0:
80 result = -1 + changedheads 80 result = -1 + changedheads
81 return result 81 return result
82
83 bundletypes = {
84 "": ("", None), # only when using unbundle on ssh and old http servers
85 # since the unification ssh accepts a header but there
86 # is no capability signaling it.
87 "HG20": (), # special-cased below
88 "HG10UN": ("HG10UN", None),
89 "HG10BZ": ("HG10", 'BZ'),
90 "HG10GZ": ("HG10GZ", 'GZ'),
91 }
92
93 # hgweb uses this list to communicate its preferred type
94 bundlepriority = ['HG10GZ', 'HG10BZ', 'HG10UN']
95 82
96 def writechunks(ui, chunks, filename, vfs=None): 83 def writechunks(ui, chunks, filename, vfs=None):
97 """Write chunks to a file and return its filename. 84 """Write chunks to a file and return its filename.
98 85
99 The stream is assumed to be a bundle file. 86 The stream is assumed to be a bundle file.
122 if cleanup is not None: 109 if cleanup is not None:
123 if filename and vfs: 110 if filename and vfs:
124 vfs.unlink(cleanup) 111 vfs.unlink(cleanup)
125 else: 112 else:
126 os.unlink(cleanup) 113 os.unlink(cleanup)
127
128 def writebundle(ui, cg, filename, bundletype, vfs=None, compression=None):
129 """Write a bundle file and return its filename.
130
131 Existing files will not be overwritten.
132 If no filename is specified, a temporary file is created.
133 bz2 compression can be turned off.
134 The bundle file will be deleted in case of errors.
135 """
136
137 if bundletype == "HG20":
138 from . import bundle2
139 bundle = bundle2.bundle20(ui)
140 bundle.setcompression(compression)
141 part = bundle.newpart('changegroup', data=cg.getchunks())
142 part.addparam('version', cg.version)
143 chunkiter = bundle.getchunks()
144 else:
145 # compression argument is only for the bundle2 case
146 assert compression is None
147 if cg.version != '01':
148 raise error.Abort(_('old bundle types only supports v1 '
149 'changegroups'))
150 header, comp = bundletypes[bundletype]
151 if comp not in util.compressors:
152 raise error.Abort(_('unknown stream compression type: %s')
153 % comp)
154 z = util.compressors[comp]()
155 subchunkiter = cg.getchunks()
156 def chunkiter():
157 yield header
158 for chunk in subchunkiter:
159 yield z.compress(chunk)
160 yield z.flush()
161 chunkiter = chunkiter()
162
163 # parse the changegroup data, otherwise we will block
164 # in case of sshrepo because we don't know the end of the stream
165
166 # an empty chunkgroup is the end of the changegroup
167 # a changegroup has at least 2 chunkgroups (changelog and manifest).
168 # after that, an empty chunkgroup is the end of the changegroup
169 return writechunks(ui, chunkiter, filename, vfs=vfs)
170 114
171 class cg1unpacker(object): 115 class cg1unpacker(object):
172 """Unpacker for cg1 changegroup streams. 116 """Unpacker for cg1 changegroup streams.
173 117
174 A changegroup unpacker handles the framing of the revision data in 118 A changegroup unpacker handles the framing of the revision data in