Index: src/clone.c
==================================================================
--- src/clone.c
+++ src/clone.c
@@ -141,11 +141,11 @@
   }else{
     db_create_repository(g.argv[3]);
     db_open_repository(g.argv[3]);
     db_begin_transaction();
     db_record_repository_filename(g.argv[3]);
-    db_initial_setup(0, zDefaultUser, 0);
+    db_initial_setup(0, 0, zDefaultUser, 0);
     user_select();
     db_set("content-schema", CONTENT_SCHEMA, 0);
     db_set("aux-schema", AUX_SCHEMA, 0);
     db_set("last-sync-url", g.argv[2], 0);
     if( g.zSSLIdentity!=0 ){

Index: src/configure.c
==================================================================
--- src/configure.c
+++ src/configure.c
@@ -157,10 +157,32 @@
       }
     }
   }
   return 0;
 }
+
+/*
+** Return a pointer to a string that contains the RHS of an IN operator
+** that will select CONFIG table names that are part of the configuration
+** that matchines iMatch.
+*/
+const char *configure_inop_rhs(int iMask){
+  Blob x;
+  int i;
+  const char *zSep = "";
+
+  blob_zero(&x);
+  blob_append(&x, "(", 1);
+  for(i=0; i<count(aConfig); i++){
+    if( (aConfig[i].groupMask & iMask)==0 ) continue;
+    if( aConfig[i].zName[0]=='@' ) continue;
+    blob_appendf(&x, "%s'%s'", zSep, aConfig[i].zName);
+    zSep = ",";
+  }
+  blob_append(&x, ")", 1);
+  return blob_str(&x);
+}
 
 /*
 ** Return the mask for the named configuration parameter if it can be
 ** safely exported.  Return 0 if the parameter is not safe to export.
 **

Index: src/db.c
==================================================================
--- src/db.c
+++ src/db.c
@@ -701,10 +701,25 @@
   sqlite3_wal_autocheckpoint(db, 1);  /* Set to checkpoint frequently */
   sqlite3_create_function(db, "now", 0, SQLITE_ANY, 0, db_now_function, 0, 0);
   return db;
 }
 
+
+/*
+** Detaches the zLabel database.
+*/
+void db_detach(const char *zLabel){
+  db_multi_exec("DETACH DATABASE %s", zLabel);
+}
+
+/*
+** zDbName is the name of a database file.  Attach zDbName using
+** the name zLabel.
+*/
+void db_attach(const char *zDbName, const char *zLabel){
+  db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel);
+}
 
 /*
 ** zDbName is the name of a database file.  If no other database
 ** file is open, then open this one.  If another database file is
 ** already open, then attach zDbName using the name zLabel.
@@ -713,11 +728,11 @@
   if( !g.db ){
     g.db = openDatabase(zDbName);
     g.zMainDbType = zLabel;
     db_connection_init();
   }else{
-    db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel);
+    db_attach(zDbName, zLabel);
   }
 }
 
 /*
 ** Open the user database in "~/.fossil".  Create the database anew if
@@ -1206,23 +1221,51 @@
        "INSERT INTO user(login,pw,cap,info)"
        "   VALUES('reader','','kptw','Reader');"
     );
   }
 }
+
+/*
+** Return a pointer to a string that contains the RHS of an IN operator
+** that will select CONFIG table names that are in the list of control
+** settings.
+*/
+const char *db_setting_inop_rhs(){
+  Blob x;
+  int i;
+  const char *zSep = "";
+
+  blob_zero(&x);
+  blob_append(&x, "(", 1);
+  for(i=0; ctrlSettings[i].name; i++){
+    blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name);
+    zSep = ",";
+  }
+  blob_append(&x, ")", 1);
+  return blob_str(&x);
+}
 
 /*
 ** Fill an empty repository database with the basic information for a
 ** repository. This function is shared between 'create_repository_cmd'
 ** ('new') and 'reconstruct_cmd' ('reconstruct'), both of which create
 ** new repositories.
+**
+** The zTemplate parameter determines if the settings for the repository
+** should be copied from another repository.  If zTemplate is 0 then the
+** settings will have their normal default values.  If zTemplate is
+** non-zero, it is assumed that the caller of this function has already
+** attached a database using the label "settingSrc".  If not, the call to
+** this function will fail.
 **
 ** The zInitialDate parameter determines the date of the initial check-in
 ** that is automatically created.  If zInitialDate is 0 then no initial
 ** check-in is created. The makeServerCodes flag determines whether or
 ** not server and project codes are invented for this repository.
 */
 void db_initial_setup(
+  const char *zTemplate,       /* Repository from which to copy settings. */
   const char *zInitialDate,    /* Initial date of repository. (ex: "now") */
   const char *zDefaultUser,    /* Default user for the repository */
   int makeServerCodes          /* True to make new server & project codes */
 ){
   char *zDate;
@@ -1241,10 +1284,47 @@
   }
   if( !db_is_global("autosync") ) db_set_int("autosync", 1, 0);
   if( !db_is_global("localauth") ) db_set_int("localauth", 0, 0);
   db_create_default_users(0, zDefaultUser);
   user_select();
+
+  if( zTemplate ){
+    /*
+    ** Copy all settings from the supplied template repository.
+    */
+    db_multi_exec(
+      "INSERT OR REPLACE INTO config"
+      " SELECT name,value,mtime FROM settingSrc.config"
+      "  WHERE (name IN %s OR name IN %s)"
+      "    AND name NOT GLOB 'project-*';",
+      configure_inop_rhs(CONFIGSET_ALL),
+      db_setting_inop_rhs()
+    );
+    db_multi_exec(
+      "REPLACE INTO reportfmt SELECT * FROM settingSrc.reportfmt;"
+    );
+
+    /*
+    ** Copy the user permissions, contact information, last modified
+    ** time, and photo for all the "system" users from the supplied
+    ** template repository into the one being setup.  The other columns
+    ** are not copied because they contain security information or other
+    ** data specific to the other repository.  The list of columns copied
+    ** by this SQL statement may need to be revised in the future.
+    */
+    db_multi_exec("UPDATE user SET"
+      "  cap = (SELECT u2.cap FROM settingSrc.user u2"
+      "         WHERE u2.login = user.login),"
+      "  info = (SELECT u2.info FROM settingSrc.user u2"
+      "          WHERE u2.login = user.login),"
+      "  mtime = (SELECT u2.mtime FROM settingSrc.user u2"
+      "           WHERE u2.login = user.login),"
+      "  photo = (SELECT u2.photo FROM settingSrc.user u2"
+      "           WHERE u2.login = user.login)"
+      " WHERE user.login IN ('anonymous','nobody','developer','reader');"
+    );
+  }
 
   if( zInitialDate ){
     int rid;
     blob_zero(&manifest);
     blob_appendf(&manifest, "C initial\\sempty\\scheck-in\n");
@@ -1277,33 +1357,47 @@
 **
 ** By default, your current login name is used to create the default
 ** admin user. This can be overridden using the -A|--admin-user
 ** parameter.
 **
+** By default, all settings will be initialized to their default values.
+** This can be overridden using the --template parameter to specify a
+** repository file from which to copy the initial settings.  When a template
+** repository is used, almost all of the settings accessible from the setup
+** page, either directly or indirectly, will be copied.  Normal users and
+** their associated permissions will not be copied; however, the system
+** default users "anonymous", "nobody", "reader", "developer", and their
+** associated permissions will be copied.
+**
 ** Options:
+**    --template      FILE      copy settings from repository file
 **    --admin-user|-A USERNAME  select given USERNAME as admin user
 **    --date-override DATETIME  use DATETIME as time of the initial checkin
 **
 ** See also: clone
 */
 void create_repository_cmd(void){
   char *zPassword;
+  const char *zTemplate;      /* Repository from which to copy settings */
   const char *zDate;          /* Date of the initial check-in */
   const char *zDefaultUser;   /* Optional name of the default user */
 
+  zTemplate = find_option("template",0,1);
   zDate = find_option("date-override",0,1);
   zDefaultUser = find_option("admin-user","A",1);
   if( zDate==0 ) zDate = "now";
   if( g.argc!=3 ){
     usage("REPOSITORY-NAME");
   }
   db_create_repository(g.argv[2]);
   db_open_repository(g.argv[2]);
   db_open_config(0);
+  if( zTemplate ) db_attach(zTemplate, "settingSrc");
   db_begin_transaction();
-  db_initial_setup(zDate, zDefaultUser, 1);
+  db_initial_setup(zTemplate, zDate, zDefaultUser, 1);
   db_end_transaction(0);
+  if( zTemplate ) db_detach("settingSrc");
   fossil_print("project-id: %s\n", db_get("project-code", 0));
   fossil_print("server-id:  %s\n", db_get("server-code", 0));
   zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
   fossil_print("admin-user: %s (initial password is \"%s\")\n", 
                g.zLogin, zPassword);

Index: src/import.c
==================================================================
--- src/import.c
+++ src/import.c
@@ -771,11 +771,11 @@
      "CREATE TEMP TABLE xtag(tname TEXT UNIQUE, tcontent TEXT);"
   );
 
 
   db_begin_transaction();
-  if( !incrFlag ) db_initial_setup(0, 0, 1);
+  if( !incrFlag ) db_initial_setup(0, 0, 0, 1);
   git_fast_import(pIn);
   db_prepare(&q, "SELECT tcontent FROM xtag");
   while( db_step(&q)==SQLITE_ROW ){
     Blob record;
     db_ephemeral_blob(&q, 0, &record);

Index: src/login.c
==================================================================
--- src/login.c
+++ src/login.c
@@ -1444,21 +1444,21 @@
   if( rc ) return;
 
   /* Attach the other repository.  Make sure the username/password is
   ** valid and has Setup permission.
   */
-  db_multi_exec("ATTACH %Q AS other", zRepo);
+  db_attach(zRepo, "other");
   zOtherProjCode = db_text("x", "SELECT value FROM other.config"
                                 " WHERE name='project-code'");
   zPwHash = sha1_shared_secret(zPassword, zLogin, zOtherProjCode);
   if( !db_exists(
     "SELECT 1 FROM other.user"
     " WHERE login=%Q AND cap GLOB '*s*'"
     "   AND (pw=%Q OR pw=%Q)",
     zLogin, zPassword, zPwHash)
   ){
-    db_multi_exec("DETACH other");
+    db_detach("other");
     *pzErrMsg = "The supplied username/password does not correspond to a"
                 " user Setup permission on the other repository.";
     return;
   }
 

Index: src/rebuild.c
==================================================================
--- src/rebuild.c
+++ src/rebuild.c
@@ -886,11 +886,11 @@
   }
   db_create_repository(g.argv[2]);
   db_open_repository(g.argv[2]);
   db_open_config(0);
   db_begin_transaction();
-  db_initial_setup(0, 0, 1);
+  db_initial_setup(0, 0, 0, 1);
 
   fossil_print("Reading files from directory \"%s\"...\n", g.argv[3]);
   recon_read_dir(g.argv[3]);
   fossil_print("\nBuilding the Fossil repository...\n");