diff --git a/piuparts.1.txt b/piuparts.1.txt
index f629546..b0abb03 100644
--- a/piuparts.1.txt
+++ b/piuparts.1.txt
@@ -71,6 +71,11 @@ The tarball can be created with the '-s' option, or you can use one that *pbuild
 *--extra-old-packages*='pkg1[,pkg2]...'::
   Install additional old packages before upgrading.  Allows testing package renames/merges where the old package is no longer available in the new distribution and the new one utilizes Conflicts/Replaces.  The argument is a comma separated list of package names and the option can be given multiple times.
 
+*-e* 'dirname', *--existing-chroot*='dirname'::
+  Use the specified directory as source for the new chroot, instead of building
+  a new one with debootstrap. This is similar to '--basetgz', but the contents
+  are not archived.
+
 *-i* 'filename', *--ignore*='filename'::
   Add a filename to the list of filenames to be ignored when comparing changes before and after installation. By default, piuparts ignores files that always change during a package installation and uninstallation, such as *dpkg* status files. The filename should be relative to the root of the chroot (e.g., _var/lib/dpkg/status_). This option can be used as many times as necessary.
 
diff --git a/piuparts.py b/piuparts.py
index 9015aa4..cb56963 100644
--- a/piuparts.py
+++ b/piuparts.py
@@ -146,6 +146,7 @@ class Settings:
         self.basetgz = None
         self.savetgz = None
         self.lvm_volume = None
+        self.existing_chroot = None
         self.end_meta = None
         self.save_end_meta = None
         self.skip_minimize = True
@@ -731,6 +732,8 @@ class Chroot:
             self.unpack_from_tgz(settings.basetgz)
         elif settings.lvm_volume:
             self.setup_from_lvm(settings.lvm_volume)
+        elif settings.existing_chroot:
+            self.setup_from_dir(settings.existing_chroot)
         else:
             self.setup_minimal_chroot()
 
@@ -815,6 +818,16 @@ class Chroot:
         logging.info("Mounting LVM snapshot to %s" % self.name); 
         run(['mount', self.lvm_snapshot, self.name])
 
+    def setup_from_dir(self, dirname):
+        """Create chroot from an existing one."""
+        logging.debug("Copying %s into %s" % (dirname, self.name))
+        for name in os.listdir(dirname):
+            src = os.path.join(dirname, name)
+            dst = os.path.join(self.name, name)
+            run(["cp", "-ax", src, dst])
+            # copytree does not work with sockets
+            #shutil.copytree(src, dst, symlinks=True)
+
     def run(self, command, ignore_errors=False):
         prefix = []
         if settings.eatmydata and os.path.isfile(os.path.join(self.name,
@@ -2238,6 +2251,11 @@ def parse_command_line():
                       action='store_true',
                       help="Do not verify signatures from the Release files when running debootstrap.")
 
+    parser.add_option("-e", "--existing-chroot", metavar="DIR",
+                      help="Use DIR as the contents of the initial " +
+                           "chroot, instead of building a new one with " +
+                           "debootstrap")
+
     parser.add_option("-i", "--ignore", action="append", metavar="FILENAME",
                       default=[],
                       help="Add FILENAME to list of filenames to be " +
@@ -2415,6 +2433,7 @@ def parse_command_line():
     settings.savetgz = opts.save
     settings.lvm_volume = opts.lvm_volume
     settings.lvm_snapshot_size = opts.lvm_snapshot_size
+    settings.existing_chroot = opts.existing_chroot
     settings.end_meta = opts.end_meta
     settings.save_end_meta = opts.save_end_meta
     settings.skip_minimize = opts.skip_minimize
