diff --git a/mercurial/archival.py b/mercurial/archival.py --- a/mercurial/archival.py +++ b/mercurial/archival.py @@ -13,6 +13,7 @@ import scmutil, util, encoding import cStringIO, os, tarfile, time, zipfile import zlib, gzip import struct +import error # from unzip source code: _UNX_IFREG = 0x8000 @@ -288,20 +289,25 @@ def archive(repo, dest, node, kind, deco files = [f for f in ctx.manifest().keys() if matchfn(f)] else: files = ctx.manifest().keys() - files.sort() total = len(files) - repo.ui.progress(_('archiving'), 0, unit=_('files'), total=total) - for i, f in enumerate(files): - ff = ctx.flags(f) - write(f, 'x' in ff and 0755 or 0644, 'l' in ff, ctx[f].data) - repo.ui.progress(_('archiving'), i + 1, item=f, - unit=_('files'), total=total) - repo.ui.progress(_('archiving'), None) + if total: + files.sort() + repo.ui.progress(_('archiving'), 0, unit=_('files'), total=total) + for i, f in enumerate(files): + ff = ctx.flags(f) + write(f, 'x' in ff and 0755 or 0644, 'l' in ff, ctx[f].data) + repo.ui.progress(_('archiving'), i + 1, item=f, + unit=_('files'), total=total) + repo.ui.progress(_('archiving'), None) if subrepos: for subpath in sorted(ctx.substate): sub = ctx.sub(subpath) submatch = matchmod.narrowmatcher(subpath, matchfn) - sub.archive(repo.ui, archiver, prefix, submatch) + total += sub.archive(repo.ui, archiver, prefix, submatch) + + if total == 0: + raise error.Abort(_('no files match the archive pattern')) archiver.done() + return total diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -423,6 +423,7 @@ class abstractsubrepo(object): ui.progress(_('archiving (%s)') % relpath, i + 1, unit=_('files'), total=total) ui.progress(_('archiving (%s)') % relpath, None) + return total def walk(self, match): ''' @@ -580,14 +581,15 @@ class hgsubrepo(abstractsubrepo): @annotatesubrepoerror def archive(self, ui, archiver, prefix, match=None): self._get(self._state + ('hg',)) - abstractsubrepo.archive(self, ui, archiver, prefix, match) - + total = abstractsubrepo.archive(self, ui, archiver, prefix, match) rev = self._state[1] ctx = self._repo[rev] for subpath in ctx.substate: s = subrepo(ctx, subpath) submatch = matchmod.narrowmatcher(subpath, match) - s.archive(ui, archiver, os.path.join(prefix, self._path), submatch) + total += s.archive( + ui, archiver, os.path.join(prefix, self._path), submatch) + return total @annotatesubrepoerror def dirty(self, ignoreupdate=False): @@ -1383,9 +1385,10 @@ class gitsubrepo(abstractsubrepo): os.remove(path) def archive(self, ui, archiver, prefix, match=None): + total = 0 source, revision = self._state if not revision: - return + return total self._fetch(source, revision) # Parse git's native archive command. @@ -1406,9 +1409,11 @@ class gitsubrepo(abstractsubrepo): data = tar.extractfile(info).read() archiver.addfile(os.path.join(prefix, self._path, info.name), info.mode, info.issym(), data) + total += 1 ui.progress(_('archiving (%s)') % relpath, i + 1, unit=_('files')) ui.progress(_('archiving (%s)') % relpath, None) + return total @annotatesubrepoerror diff --git a/tests/test-archive.t b/tests/test-archive.t --- a/tests/test-archive.t +++ b/tests/test-archive.t @@ -289,6 +289,16 @@ old file -- date clamped to 1980 *-----* (glob) \s*147\s+2 files (re) +show an error when a provided pattern matches no files + + $ hg archive -I file_that_does_not_exist.foo ../empty.zip + abort: no files match the archive pattern + [255] + + $ hg archive -X * ../empty.zip + abort: no files match the archive pattern + [255] + $ cd .. issue3600: check whether "hg archive" can create archive files which