--- rebuild.c
+++ rebuild.c
@@ -506,17 +506,120 @@
   /* Skip the verify_before_commit() step on a reconstruct.  Most artifacts
   ** will have been changed and verification therefore takes a really, really
   ** long time.
   */
   verify_cancel();
-  
+
+  db_end_transaction(0);
+  printf("project-id: %s\n", db_get("project-code", 0));
+  printf("server-id: %s\n", db_get("server-code", 0));
+  zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
+  printf("admin-user: %s (initial password is \"%s\")\n", g.zLogin, zPassword);
+}
+
+#include "sqlite3.h"
+#include <zlib.h>
+
+/*
+** COMMAND: reconstruct-sql
+**
+** Usage: %fossil reconstruct-sql REPOSITORY CONTENT-DATABASE
+**
+** This command imports artificats from the sqlite3 database
+** CONTENT-DATABASE and reconstructs the fossil record from them.
+** It places the new fossil repository in REPOSITORY.
+**
+** CONTENT-DATABASE is expected to have a non-empty table "content"
+** with columns "content" and "size". "content" is the zlib-compressed
+** artifact and "size" the uncompressed size.
+**
+*/
+void reconstruct_sql_cmd(void) {
+  Blob aContent;
+  sqlite3 *db;
+  sqlite3_stmt *stmt;
+  int rv;
+  int count, total;
+  char *zPassword;
+  if( g.argc!=4 ){
+    usage("REPOSITORY CONTENT-DATABASE");
+  }
+
+  if( sqlite3_open_v2(g.argv[3], &db, SQLITE_OPEN_READONLY,  NULL) ){
+    fprintf(stderr, "database open failed: %s\n", sqlite3_errmsg(db));
+    exit(1);
+  }
+
+  if( sqlite3_prepare(db, "SELECT COUNT(*) FROM content", -1, &stmt, NULL) ){
+    fprintf(stderr, "prepare failed\n");
+    exit(1);
+  }
+  if( sqlite3_step(stmt) != SQLITE_ROW ){
+    fprintf(stderr, "step failed\n");
+    exit(1);
+  }
+  total = sqlite3_column_int(stmt, 0);
+  sqlite3_finalize(stmt);
+
+  if( !total ){
+    fprintf(stderr, "database contains no artifacts\n");
+    exit(1);
+  }
+
+  if( sqlite3_prepare(db, "SELECT content,size FROM content", -1, &stmt, NULL) ){
+    fprintf(stderr, "prepare failed\n");
+    exit(1);
+  }
+
+  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);
+
+  count = 0;
+  while( (rv = sqlite3_step(stmt)) == SQLITE_ROW ){
+    uLongf sz;
+    int rv;
+    blob_init(&aContent, 0, 0);
+    sz = sqlite3_column_int(stmt, 1);
+    blob_resize(&aContent, sz);
+    rv= uncompress((unsigned char *)blob_buffer(&aContent), &sz,
+	sqlite3_column_blob(stmt, 0), sqlite3_column_bytes(stmt, 0));
+    if( rv != Z_OK || sz != sqlite3_column_int(stmt,1)){
+      fprintf(stderr, "Decompression failed\n");
+      exit(1);
+    }
+    content_put(&aContent, 0, 0);
+    blob_reset(&aContent);
+    ++count;
+    printf("%d (%d%%)...\r", count, (count * 100) / total);
+    fflush(stdout);
+  }
+  printf("\n");
+
+  sqlite3_finalize(stmt);
+  sqlite3_close(db);
+
+  rebuild_db(0, 1);
+
+  /* Skip the verify_before_commit() step on a reconstruct.  Most artifacts
+  ** will have been changed and verification therefore takes a really, really
+  ** long time.
+  */
+  verify_cancel();
+
   db_end_transaction(0);
+  printf("Running VACUUM...\n");
+  db_multi_exec("VACUUM;");
+
   printf("project-id: %s\n", db_get("project-code", 0));
   printf("server-id: %s\n", db_get("server-code", 0));
   zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
   printf("admin-user: %s (initial password is \"%s\")\n", g.zLogin, zPassword);
 }
+
 
 /*
 ** COMMAND: deconstruct
 **
 ** Usage %fossil deconstruct ?-R|--repository REPOSITORY? ?-L|--prefixlength N? DESTINATION

