--- a/doc/hg.1.txt Thu Sep 08 00:13:52 2005 -0700
+++ b/doc/hg.1.txt Thu Sep 08 01:27:25 2005 -0700
@@ -106,6 +106,21 @@
-c, --changeset list the changeset
-n, --number list the revision number (default)
+bundle <file> <other>::
+ (EXPERIMENTAL)
+
+ Generate a compressed changegroup file collecting all changesets
+ not found in the other repository.
+
+ This file can then be transferred using conventional means and
+ applied to another repository with the unbundle command. This is
+ useful when native push and pull are not available or when
+ exporting an entire repository is undesirable. The standard file
+ extension is ".hg".
+
+ Unlike import/export, this exactly preserves all changeset
+ contents including permissions, rename data, and revision history.
+
cat <file> [revision]::
Output to stdout the given revision for the specified file.
@@ -512,6 +527,12 @@
tip::
Show the tip revision.
+unbundle <file>::
+ (EXPERIMENTAL)
+
+ Apply a compressed changegroup file generated by the bundle
+ command.
+
undo::
Undo the last commit or pull transaction.
--- a/mercurial/commands.py Thu Sep 08 00:13:52 2005 -0700
+++ b/mercurial/commands.py Thu Sep 08 01:27:25 2005 -0700
@@ -7,10 +7,10 @@
from demandload import demandload
from node import *
-demandload(globals(), "os re sys signal shutil imp")
+demandload(globals(), "os re sys signal shutil imp urllib")
demandload(globals(), "fancyopts ui hg util lock revlog")
demandload(globals(), "fnmatch hgweb mdiff random signal time traceback")
-demandload(globals(), "errno socket version struct atexit sets")
+demandload(globals(), "errno socket version struct atexit sets bz2")
class UnknownCommand(Exception):
"""Exception raised if command is not in the command table."""
@@ -549,6 +549,26 @@
for p, l in zip(zip(*pieces), lines):
ui.write("%s: %s" % (" ".join(p), l[1]))
+def bundle(ui, repo, fname, dest="default-push", **opts):
+ """create a changegroup file"""
+ f = open(fname, "wb")
+ dest = ui.expandpath(dest)
+ other = hg.repository(ui, dest)
+ o = repo.findoutgoing(other)
+ cg = repo.changegroup(o)
+
+ try:
+ f.write("HG10")
+ z = bz2.BZ2Compressor(9)
+ while 1:
+ chunk = cg.read(4096)
+ if not chunk:
+ break
+ f.write(z.compress(chunk))
+ f.write(z.flush())
+ except:
+ os.unlink(fname)
+
def cat(ui, repo, file1, rev=None, **opts):
"""output the latest or given revision of a file"""
r = repo.file(relpath(repo, [file1])[0])
@@ -1534,6 +1554,30 @@
n = repo.changelog.tip()
show_changeset(ui, repo, changenode=n)
+def unbundle(ui, repo, fname):
+ f = urllib.urlopen(fname)
+
+ if f.read(4) != "HG10":
+ ui.warn("abort: not a Mercurial bundle file!\n")
+ return -1
+
+ class bzread:
+ def __init__(self, f):
+ self.zd = bz2.BZ2Decompressor()
+ self.f = f
+ self.buf = ""
+ def read(self, l):
+ while l > len(self.buf):
+ r = self.f.read(4096)
+ if r:
+ self.buf += self.zd.decompress(r)
+ else:
+ break
+ d, self.buf = self.buf[:l], self.buf[l:]
+ return d
+
+ repo.addchangegroup(bzread(f))
+
def undo(ui, repo):
"""undo the last commit or pull
@@ -1610,6 +1654,10 @@
('I', 'include', [], 'include path in search'),
('X', 'exclude', [], 'exclude path from search')],
'hg annotate [OPTION]... FILE...'),
+ "bundle":
+ (bundle,
+ [],
+ 'hg bundle FILE DEST'),
"cat":
(cat,
[('o', 'output', "", 'output to file')],
@@ -1776,6 +1824,10 @@
'hg tag [OPTION]... NAME [REV]'),
"tags": (tags, [], 'hg tags'),
"tip": (tip, [], 'hg tip'),
+ "unbundle":
+ (unbundle,
+ [],
+ 'hg unbundle FILE'),
"undo": (undo, [], 'hg undo'),
"^update|up|checkout|co":
(update,