Check-in [915bfd99fe]
Not logged in
Overview

SHA1 Hash:915bfd99fec69f978f199412bdb2c3da54a24156
Date: 2009-05-28 02:44:39
User: drh
Comment:Add the --keep option to the "open" and "checkout" commands. Added the --latest option to "checkout". These changes allow one to shift the baseline version and repository of a checkout without changing any files in the checkout.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/checkout.c from [24593c59e3] to [31cde9d18f].

@@ -135,62 +135,103 @@
 
 /*
 ** COMMAND: checkout
 ** COMMAND: co
 **
-** Usage: %fossil checkout VERSION ?-f|--force?
+** Usage: %fossil checkout VERSION ?-f|--force? ?--keep?
 **
 ** Check out a version specified on the command-line.  This command
-** will not overwrite edited files in the current checkout unless
-** the --force option appears on the command-line.
+** will abort if there are edited files in the current checkout unless
+** the --force option appears on the command-line.  The --keep option
+** leaves files on disk unchanged, except the manifest and manifest.uuid
+** files.
+**
+** The --latest flag can be used in place of VERSION to checkout the
+** latest version in the repository.
 **
 ** See also the "update" command.
 */
 void checkout_cmd(void){
-  int forceFlag;
-  int noWrite;
+  int forceFlag;                 /* Force checkout even if edits exist */
+  int keepFlag;                  /* Do not change any files on disk */
+  int latestFlag;                /* Checkout the latest version */
+  char *zVers;                   /* Version to checkout */
   int vid, prior;
   Blob cksum1, cksum1b, cksum2;
 
   db_must_be_within_tree();
   db_begin_transaction();
   forceFlag = find_option("force","f",0)!=0;
-  noWrite = find_option("dontwrite",0,0)!=0;
-  if( g.argc!=3 ) usage("?--force? VERSION");
+  keepFlag = find_option("keep",0,0)!=0;
+  latestFlag = find_option("latest",0,0)!=0;
+  if( (latestFlag!=0 && g.argc!=2) || (latestFlag==0 && g.argc!=3) ){
+     usage("VERSION|--latest ?--force? ?--keep?");
+  }
   if( !forceFlag && unsaved_changes()==1 ){
     fossil_fatal("there are unsaved changes in the current checkout");
   }
   if( forceFlag ){
     db_multi_exec("DELETE FROM vfile");
     prior = 0;
   }else{
     prior = db_lget_int("checkout",0);
   }
-  vid = load_vfile(g.argv[2]);
+  if( latestFlag ){
+    compute_leaves(db_lget_int("checkout",0), 1);
+    zVers = db_text(0, "SELECT uuid FROM leaves, event, blob"
+                       " WHERE event.objid=leaves.rid AND blob.rid=leaves.rid"
+                       " ORDER BY event.mtime DESC");
+    if( zVers==0 ){
+      fossil_fatal("cannot local \"latest\" checkout");
+    }
+  }else{
+    zVers = g.argv[2];
+  }
+  vid = load_vfile(zVers);
   if( prior==vid ){
     return;
   }
-  if( !noWrite ){
+  if( !keepFlag ){
     uncheckout(prior);
   }
   db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid);
-  if( !noWrite ){
+  if( !keepFlag ){
     vfile_to_disk(vid, 0, 1);
-    manifest_to_disk(vid);
-    db_lset_int("checkout", vid);
-    undo_reset();
   }
+  manifest_to_disk(vid);
+  db_lset_int("checkout", vid);
+  undo_reset();
   db_multi_exec("DELETE FROM vmerge");
-  vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
-  vfile_aggregate_checksum_disk(vid, &cksum2);
-  if( blob_compare(&cksum1, &cksum2) ){
-    printf("WARNING: manifest checksum does not agree with disk\n");
-  }
-  if( blob_compare(&cksum1, &cksum1b) ){
-    printf("WARNING: manifest checksum does not agree with manifest\n");
+  if( !keepFlag ){
+    vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
+    vfile_aggregate_checksum_disk(vid, &cksum2);
+    if( blob_compare(&cksum1, &cksum2) ){
+      printf("WARNING: manifest checksum does not agree with disk\n");
+    }
+    if( blob_compare(&cksum1, &cksum1b) ){
+      printf("WARNING: manifest checksum does not agree with manifest\n");
+    }
   }
   db_end_transaction(0);
+}
+
+/*
+** Unlink the local database file
+*/
+void unlink_local_database(void){
+  static const char *azFile[] = {
+     "%s_FOSSIL_",
+     "%s_FOSSIL_-journal",
+     "%s.fos",
+     "%s.fos-journal",
+  };
+  int i;
+  for(i=0; i<sizeof(azFile)/sizeof(azFile[0]); i++){
+    char *z = mprintf(azFile[i], g.zLocalRoot);
+    unlink(z);
+    free(z);
+  }
 }
 
 /*
 ** COMMAND: close
 **
@@ -205,8 +246,7 @@
   db_must_be_within_tree();
   if( !forceFlag && unsaved_changes()==1 ){
     fossil_fatal("there are unsaved changes in the current checkout");
   }
   db_close();
-  unlink(mprintf("%s_FOSSIL_", g.zLocalRoot));
-  unlink(mprintf("%s_FOSSIL_-journal", g.zLocalRoot));
+  unlink_local_database();
 }

Modified src/db.c from [6f78bab6b5] to [a1f15c6b0b].

@@ -1243,23 +1243,29 @@
 }
 
 /*
 ** COMMAND: open
 **
-** Usage: %fossil open FILENAME
+** Usage: %fossil open FILENAME ?VERSION? ?--keep?
 **
 ** Open a connection to the local repository in FILENAME.  A checkout
 ** for the repository is created with its root at the working directory.
+** If VERSION is specified then that version is checked out.  Otherwise
+** the latest version is checked out.  No files other than "manifest"
+** and "manifest.uuid" are modified if the --keep option is present.
+**
 ** See also the "close" command.
 */
 void cmd_open(void){
   Blob path;
   int vid;
-  static char *azNewArgv[] = { 0, "update", "--latest", 0 };
+  int keepFlag;
+  static char *azNewArgv[] = { 0, "checkout", "--latest", 0, 0, 0 };
   url_proxy_options();
-  if( g.argc!=3 ){
-    usage("REPOSITORY-FILENAME");
+  keepFlag = find_option("keep",0,0)!=0;
+  if( g.argc!=3 && g.argc!=4 ){
+    usage("REPOSITORY-FILENAME ?VERSION?");
   }
   if( db_open_local() ){
     fossil_panic("already within an open tree rooted at %s", g.zLocalRoot);
   }
   file_canonical_name(g.argv[2], &path);
@@ -1271,14 +1277,23 @@
   vid = db_int(0, "SELECT pid FROM plink y"
                   " WHERE NOT EXISTS(SELECT 1 FROM plink x WHERE x.cid=y.pid)");
   if( vid==0 ){
     db_lset_int("checkout", 1);
   }else{
+    char **oldArgv = g.argv;
+    int oldArgc = g.argc;
     db_lset_int("checkout", vid);
+    azNewArgv[0] = g.argv[0];
     g.argv = azNewArgv;
     g.argc = 3;
-    update_cmd();
+    if( oldArgc==4 ){
+      azNewArgv[g.argc-1] = oldArgv[3];
+    }
+    if( keepFlag ){
+      azNewArgv[g.argc++] = "--keep";
+    }
+    checkout_cmd();
     g.argc = 2;
     info_cmd();
   }
 }