# HG changeset patch # User Matt Mackall # Date 1285014708 18000 # Node ID 5f6231861e0957292ddca198b16f0322bbc5e38b # Parent f00953d9533c30bcc40e7d5ae2635db5f2c88c8e# Parent b701610f6c566c74f0c2c2287fe5d4f8c38dcfc8 merge with abuehl diff -r b701610f6c56 -r 5f6231861e09 mercurial/archival.py --- a/mercurial/archival.py Sun Sep 19 23:42:18 2010 +0200 +++ b/mercurial/archival.py Mon Sep 20 15:31:48 2010 -0500 @@ -150,6 +150,13 @@ self.z = zipfile.ZipFile(dest, 'w', compress and zipfile.ZIP_DEFLATED or zipfile.ZIP_STORED) + + # Python's zipfile module emits deprecation warnings if we try + # to store files with a date before 1980. + epoch = 315532800 # calendar.timegm((1980, 1, 1, 0, 0, 0, 1, 1, 0)) + if mtime < epoch: + mtime = epoch + self.date_time = time.gmtime(mtime)[:6] def addfile(self, name, mode, islink, data): @@ -198,7 +205,7 @@ } def archive(repo, dest, node, kind, decode=True, matchfn=None, - prefix=None, mtime=None): + prefix=None, mtime=None, subrepos=False): '''create archive of repo as it was at node. dest can be name of directory, name of archive file, or file @@ -256,4 +263,10 @@ for f in ctx: ff = ctx.flags(f) write(f, 'x' in ff and 0755 or 0644, 'l' in ff, ctx[f].data) + + if subrepos: + for subpath in ctx.substate: + sub = ctx.sub(subpath) + sub.archive(archiver, prefix) + archiver.done() diff -r b701610f6c56 -r 5f6231861e09 mercurial/commands.py --- a/mercurial/commands.py Sun Sep 19 23:42:18 2010 +0200 +++ b/mercurial/commands.py Mon Sep 20 15:31:48 2010 -0500 @@ -199,7 +199,7 @@ prefix = cmdutil.make_filename(repo, prefix, node) matchfn = cmdutil.match(repo, [], opts) archival.archive(repo, dest, node, kind, not opts.get('no_decode'), - matchfn, prefix) + matchfn, prefix, subrepos=opts.get('subrepos')) def backout(ui, repo, node=None, rev=None, **opts): '''reverse effect of earlier changeset @@ -3963,7 +3963,7 @@ _('revision to distribute'), _('REV')), ('t', 'type', '', _('type of distribution to create'), _('TYPE')), - ] + walkopts, + ] + subrepoopts + walkopts, _('[OPTION]... DEST')), "backout": (backout, diff -r b701610f6c56 -r 5f6231861e09 mercurial/revset.py --- a/mercurial/revset.py Sun Sep 19 23:42:18 2010 +0200 +++ b/mercurial/revset.py Mon Sep 20 15:31:48 2010 -0500 @@ -276,7 +276,10 @@ return l def grep(repo, subset, x): - gr = re.compile(getstring(x, _("grep wants a string"))) + try: + gr = re.compile(getstring(x, _("grep wants a string"))) + except re.error, e: + raise error.ParseError(_('invalid match pattern: %s') % e) l = [] for r in subset: c = repo[r] diff -r b701610f6c56 -r 5f6231861e09 mercurial/subrepo.py --- a/mercurial/subrepo.py Sun Sep 19 23:42:18 2010 +0200 +++ b/mercurial/subrepo.py Mon Sep 20 15:31:48 2010 -0500 @@ -270,6 +270,27 @@ def incoming(self, ui, source, opts): return 1 + def files(self): + """return filename iterator""" + raise NotImplementedError + + def filedata(self, name): + """return file data""" + raise NotImplementedError + + def fileflags(self, name): + """return file flags""" + return '' + + def archive(self, archiver, prefix): + for name in self.files(): + flags = self.fileflags(name) + mode = 'x' in flags and 0755 or 0644 + symlink = 'l' in flags + archiver.addfile(os.path.join(prefix, self._path, name), + mode, symlink, self.filedata(name)) + + class hgsubrepo(abstractsubrepo): def __init__(self, ctx, path, state): self._path = path @@ -329,6 +350,15 @@ self._repo.ui.warn(_("warning: %s in %s\n") % (inst, relpath(self))) + def archive(self, archiver, prefix): + abstractsubrepo.archive(self, archiver, prefix) + + rev = self._state[1] + ctx = self._repo[rev] + for subpath in ctx.substate: + s = subrepo(ctx, subpath) + s.archive(archiver, os.path.join(prefix, self._path)) + def dirty(self): r = self._state[1] if r == '': @@ -406,6 +436,21 @@ def incoming(self, ui, source, opts): return hg.incoming(ui, self._repo, _abssource(self._repo, False), opts) + def files(self): + rev = self._state[1] + ctx = self._repo[rev] + return ctx.manifest() + + def filedata(self, name): + rev = self._state[1] + return self._repo[rev][name].data() + + def fileflags(self, name): + rev = self._state[1] + ctx = self._repo[rev] + return ctx.flags(name) + + class svnsubrepo(abstractsubrepo): def __init__(self, ctx, path, state): self._path = path @@ -508,6 +553,15 @@ # push is a no-op for SVN return True + def files(self): + output = self._svncommand(['list']) + # This works because svn forbids \n in filenames. + return output.splitlines() + + def filedata(self, name): + return self._svncommand(['cat'], name) + + types = { 'hg': hgsubrepo, 'svn': svnsubrepo, diff -r b701610f6c56 -r 5f6231861e09 tests/test-archive.t --- a/tests/test-archive.t Sun Sep 19 23:42:18 2010 +0200 +++ b/tests/test-archive.t Mon Sep 20 15:31:48 2010 -0500 @@ -219,5 +219,19 @@ $ hg archive ../test-empty abort: no working directory: please specify a revision [255] +old file -- date clamped to 1980 + + $ touch -d 1975-01-01 old + $ hg add old + $ hg commit -m old + $ hg archive ../old.zip + $ unzip -l ../old.zip + Archive: ../old.zip + Length Date Time Name + --------- ---------- ----- ---- + 147 1980-01-01 00:00 old/.hg_archival.txt + 0 1980-01-01 00:00 old/old + --------- ------- + 147 2 files $ exit 0 diff -r b701610f6c56 -r 5f6231861e09 tests/test-revset.t --- a/tests/test-revset.t Sun Sep 19 23:42:18 2010 +0200 +++ b/tests/test-revset.t Mon Sep 20 15:31:48 2010 -0500 @@ -211,6 +211,10 @@ 9 $ log 'grep("issue\d+")' 6 + $ try 'grep("(")' # invalid regular expression + ('func', ('symbol', 'grep'), ('string', '(')) + hg: parse error: invalid match pattern: unbalanced parenthesis + [255] $ log 'head()' 0 1 diff -r b701610f6c56 -r 5f6231861e09 tests/test-subrepo-recursion.t --- a/tests/test-subrepo-recursion.t Sun Sep 19 23:42:18 2010 +0200 +++ b/tests/test-subrepo-recursion.t Mon Sep 20 15:31:48 2010 -0500 @@ -227,6 +227,40 @@ z1 +z2 +Test archiving to a directory tree: + + $ hg archive --subrepos ../archive + $ find ../archive + ../archive + ../archive/foo + ../archive/foo/bar + ../archive/foo/bar/z.txt + ../archive/foo/.hgsubstate + ../archive/foo/.hgsub + ../archive/foo/y.txt + ../archive/x.txt + ../archive/.hgsubstate + ../archive/.hgsub + ../archive/.hg_archival.txt + +Test archiving to zip file: + + $ hg archive --subrepos ../archive.zip + $ unzip -l ../archive.zip + Archive: ../archive.zip + Length Date Time Name + --------- ---------- ----- ---- + 147 1980-01-01 00:00 archive/.hg_archival.txt + 10 1980-01-01 00:00 archive/.hgsub + 45 1980-01-01 00:00 archive/.hgsubstate + 3 1980-01-01 00:00 archive/x.txt + 9 1980-01-01 00:00 archive/foo/y.txt + 10 1980-01-01 00:00 archive/foo/.hgsub + 45 1980-01-01 00:00 archive/foo/.hgsubstate + 9 1980-01-01 00:00 archive/foo/bar/z.txt + --------- ------- + 278 8 files + Clone and test outgoing: $ cd ..