diff -ur mock-0.4/mock.py mock-0.4.autocache/mock.py
--- mock-0.4/mock.py	2006-03-21 15:44:24.000000000 -0600
+++ mock-0.4.autocache/mock.py	2006-05-20 21:11:58.000000000 -0500
@@ -24,6 +24,8 @@
 import shutil
 import types
 import grp
+import stat
+import time
 from exceptions import Exception
 
 from optparse import OptionParser
@@ -112,6 +114,8 @@
         self.rootdir = os.path.join(self.basedir, 'root')
         self.homedir = self.config['chroothome']
         self.builddir = os.path.join(self.homedir, 'build')
+        self.cache_file = os.path.join(self.config['basedir'], 
+                self.config['cache_topdir'], self.config['root'] + self.config['cache_ext'])
         if not self.config.has_key('resultdir'):
             self.resultdir = os.path.join(self.basedir, 'result')
         else:
@@ -202,20 +206,53 @@
             self.log(curstate)
         else:
             return self._state
-    
+
+    def unpack(self):
+        self.state('unpack cache')
+        cmd = '%s %s %s' % (self.config['unpack_cmd'], self.basedir, self.cache_file)
+        self.do(cmd)
+
+    def pack(self):
+        self.state('create cache')
+        self._ensure_dir(os.path.join(self.config['basedir'], self.config['cache_topdir']))
+        cmd = '%s %s %s root' % (self.config['pack_cmd'], self.basedir, self.cache_file)
+        self.do(cmd)
+
     def prep(self):
         self.state("prep")
         self.log("This may take a while")
-        
-        self._prep_install()
-        if self.config['clean']:
-            cmd = 'groupinstall %s' % self.config['buildgroup']
+
+        create_cache=0
+        if self.config['use_cache']:
+            cache_exists = os.path.exists( self.cache_file )
+            if cache_exists:
+                cache_mtime = os.stat(self.cache_file)[stat.ST_MTIME]
+                cache_age_days = (time.time() - cache_mtime) / (60 * 60 * 24)
+                if cache_age_days > self.config['max_cache_age_days']:
+                    self.config["rebuild_cache"] = True
+
+            if cache_exists and not self.config['rebuild_cache']:
+                if self.config['clean']:
+                    self.unpack()
+                cmd = 'update'
+            else:
+                self._prep_install()
+                cmd = '%s' % self.config['chroot_setup_cmd']
+                create_cache = 1
         else:
-            cmd = 'update'
+            self._prep_install()
+            if self.config['clean']:
+                cmd = '%s' % self.config['chroot_setup_cmd']
+            else:
+                cmd = 'update'
 
         self.yum(cmd)
         self._prep_build()
-        
+
+        if create_cache:
+            self._umount_by_file()
+            self.pack()
+            self._mount()
 
     def yum(self, cmd):
         """use yum to install packages/package groups into the chroot"""
@@ -642,8 +679,8 @@
     parser.add_option("-r", action="store", type="string", dest="chroot",
             help="chroot name/config file name default: %default", 
             default='default')
-    parser.add_option("--no-clean", action ="store_true", dest="dirty", 
-            help="do not clean chroot before building")
+    parser.add_option("--no-clean", action ="store_false", dest="clean", 
+            help="do not clean chroot before building", default=True)
     parser.add_option("--arch", action ="store", dest="arch", 
             default=None, help="target build arch")
     parser.add_option("--debug", action ="store_true", dest="debug", 
@@ -658,6 +695,10 @@
                       help="Change where config files are found")
     parser.add_option("--quiet", action ="store_true", dest="quiet", 
             default=False, help="quiet down output")
+    parser.add_option("--autocache", action ="store_true", dest="use_cache",
+            default=False, help="Turn on build-root caching")
+    parser.add_option("--rebuildcache", action ="store_true", dest="rebuild_cache",
+            default=False, help="Force rebuild of build-root cache")
 
     return parser.parse_args()
     
@@ -714,6 +755,16 @@
     
     config_opts['files']['/etc/resolv.conf'] = "nameserver 192.168.1.1\n"
     config_opts['files']['/etc/hosts'] = "127.0.0.1 localhost localhost.localdomain\n"
+
+    # caching-related config options
+    config_opts['rebuild_cache'] = False
+    config_opts['use_cache'] = False
+    config_opts['pack_cmd'] = "/usr/sbin/mock-helper pack"
+    config_opts['unpack_cmd'] = "/usr/sbin/mock-helper unpack"
+    config_opts['cache_ext'] = ".tar.gz"
+    config_opts['cache_topdir'] = "root-cache"
+    config_opts['max_cache_age_days'] = 15
+
     
     # cli option parsing
     (options, args) = command_parse()
@@ -741,13 +792,13 @@
     if options.arch:
         config_opts['target_arch'] = options.arch
     
-    if options.dirty:
-        config_opts['clean'] = False
-    else:
-        config_opts['clean'] = True
-        
+    config_opts['clean'] = options.clean
     config_opts['debug'] = options.debug
     config_opts['quiet'] = options.quiet
+    config_opts['use_cache'] = options.use_cache
+    config_opts['rebuild_cache'] = options.rebuild_cache
+    if config_opts['rebuild_cache']: 
+        config_opts['use_cache'] = True
     
     if options.resultdir:
         config_opts['resultdir'] = options.resultdir
diff -ur mock-0.4/src/mock-helper.c mock-0.4.autocache/src/mock-helper.c
--- mock-0.4/src/mock-helper.c	2005-07-16 11:21:33.000000000 -0500
+++ mock-0.4.autocache/src/mock-helper.c	2006-05-20 20:11:25.000000000 -0500
@@ -14,6 +14,8 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
+#include <grp.h>
+#include <libgen.h>
 
 #ifdef USE_SELINUX
 #include <selinux/selinux.h>
@@ -341,6 +343,84 @@
   do_command ("/bin/mknod", &(argv[1]), 0);
 }
 
+void
+do_unpack(int argc, char *argv[])
+{
+  char *new_argv[5];
+
+  if (argc < 4)
+    error ("not enough arguments");
+  
+  check_dir_allowed (rootsdir, argv[2]);
+
+  if (chdir(argv[2]) != 0)
+    error ("could not change dir");
+
+  new_argv[0] = "tar";
+  new_argv[1] = "--same-owner";
+
+  /* select compression */
+  if (strstr(argv[3], ".bz2"))
+    new_argv[2] = "-jxpf";
+  else if (strstr(argv[3], ".gz"))
+    new_argv[2] = "-zxpf";
+  else
+    new_argv[2] = "-xpf";
+
+  new_argv[3] = argv[3];
+  new_argv[4] = NULL;
+  
+  do_command("/bin/tar", new_argv, 0);
+}
+
+
+void
+do_pack(int argc, char *argv[])
+{
+  char *new_argv[6];
+  char *cache_dir = 0;
+  char *argv_copy = 0;
+  struct group *gr = 0;
+
+  if (argc < 5)
+    error ("not enough arguments");
+  
+  check_dir_allowed (rootsdir, argv[2]);
+
+  if (chdir(argv[2]) != 0)
+    error ("could not change dir");
+
+  /* create root-cache dir with appropriate perms */
+  gr = getgrnam("mock");
+  argv_copy = strdup(argv[3]);
+  cache_dir = dirname(argv_copy);
+
+  check_dir_allowed (rootsdir, cache_dir);
+
+  mkdir(cache_dir, 0750);
+  if (gr)
+    chown(cache_dir, 0, gr->gr_gid);
+  free(argv_copy);
+  argv_copy = 0;
+
+  new_argv[0] = "tar";
+  new_argv[1] = "--one-file-system";
+
+  /* select compression */
+  if (strstr(argv[3], ".bz2"))
+    new_argv[2] = "-jcf";
+  else if (strstr(argv[3], ".gz"))
+    new_argv[2] = "-zcf";
+  else
+    new_argv[2] = "-cf";
+
+  new_argv[3] = argv[3];
+  new_argv[4] = argv[4];
+  new_argv[5] = NULL;
+  
+  do_command("/bin/tar", new_argv, 0);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -363,6 +443,10 @@
     do_mknod (argc, argv);
   else if (strncmp ("yum", argv[1], 3) == 0)
     do_yum (argc, argv);
+  else if (strncmp ("unpack", argv[1], 6) == 0)
+    do_unpack (argc, argv);
+  else if (strncmp ("pack", argv[1], 4) == 0)
+    do_pack (argc, argv);
   else
   {
     error ("Command %s not recognized !\n", argv[1]);
