Diff
Not logged in

Differences From:

File src/checkin.c part of check-in [f6790b7c3c] - Fix a memory leak that was preventing massive check-ins. by drh on 2009-02-26 01:21:04. [view]

To:

File src/checkin.c part of check-in [7a2c37063a] - merge trunk into creole branch by bob on 2009-09-22 07:49:39. Also file src/checkin.c part of check-in [a2749215b7] - Add the --dotfiles option to the "extra" and "clean" commands. Ticket 4de876322f066. by drh on 2009-09-19 15:32:14. [view]

@@ -164,24 +164,28 @@
   db_finalize(&q);
 }
 
 /*
-** COMMAND: extra
-** Usage: %fossil extra
+** COMMAND: extras
+** Usage: %fossil extras ?--dotfiles?
 **
 ** Print a list of all files in the source tree that are not part of
 ** the current checkout.  See also the "clean" command.
+**
+** Files and subdirectories whose names begin with "." are normally
+** ignored but can be included by adding the --dotfiles option.
 */
 void extra_cmd(void){
   Blob path;
   Blob repo;
   Stmt q;
   int n;
+  int allFlag = find_option("dotfiles",0,0)!=0;
   db_must_be_within_tree();
   db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
   n = strlen(g.zLocalRoot);
   blob_init(&path, g.zLocalRoot, n-1);
-  vfile_scan(0, &path, blob_size(&path));
+  vfile_scan(0, &path, blob_size(&path), allFlag);
   db_prepare(&q,
       "SELECT x FROM sfile"
       " WHERE x NOT IN ('manifest','manifest.uuid','_FOSSIL_')"
       " ORDER BY 1");
@@ -195,29 +199,35 @@
 }
 
 /*
 ** COMMAND: clean
-** Usage: %fossil clean ?-all?
+** Usage: %fossil clean ?--force? ?--dotfiles?
 **
 ** Delete all "extra" files in the source tree.  "Extra" files are
 ** files that are not officially part of the checkout.  See also
 ** the "extra" command. This operation cannot be undone.
 **
 ** You will be prompted before removing each file. If you are
 ** sure you wish to remove all "extra" files you can specify the
-** optional -all flag.
+** optional --force flag and no prmpts will be issued.
+**
+** Files and subdirectories whose names begin with "." are
+** normally ignored.  They are included if the "--dotfiles" option
+** is used.
 */
 void clean_cmd(void){
   int allFlag;
+  int dotfilesFlag;
   Blob path, repo;
   Stmt q;
   int n;
   allFlag = find_option("all","a",0)!=0;
+  dotfilesFlag = find_option("dotfiles",0,0)!=0;
   db_must_be_within_tree();
   db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
   n = strlen(g.zLocalRoot);
   blob_init(&path, g.zLocalRoot, n-1);
-  vfile_scan(0, &path, blob_size(&path));
+  vfile_scan(0, &path, blob_size(&path), dotfilesFlag);
   db_prepare(&q,
       "SELECT %Q || x FROM sfile"
       " WHERE x NOT IN ('manifest','manifest.uuid','_FOSSIL_')"
       " ORDER BY 1", g.zLocalRoot);
@@ -261,8 +271,15 @@
     "# Enter comments on this check-in.  Lines beginning with # are ignored.\n"
     "# The check-in comment follows wiki formatting rules.\n"
     "#\n"
   );
+  if( g.markPrivate ){
+    blob_append(&text,
+      "# PRIVATE BRANCH: This check-in will be private and will not sync to\n"
+      "# repositories.\n"
+      "#\n", -1
+    );
+  }
   status_report(&text, "# ");
   zEditor = db_get("editor", 0);
   if( zEditor==0 ){
     zEditor = getenv("VISUAL");
@@ -284,9 +301,9 @@
 #endif
   blob_write_to_file(&text, zFile);
   zCmd = mprintf("%s \"%s\"", zEditor, zFile);
   printf("%s\n", zCmd);
-  if( system(zCmd) ){
+  if( portable_system(zCmd) ){
     fossil_panic("editor aborted");
   }
   blob_reset(&text);
   blob_read_from_file(&text, zFile);
@@ -386,15 +403,19 @@
 **
 ** A check-in is not permitted to fork unless the --force or -f
 ** option appears.  A check-in is not allowed against a closed check-in.
 **
+** The --private option creates a private check-in that is never synced.
+** Children of private check-ins are automatically private.
+**
 ** Options:
 **
 **    --comment|-m COMMENT-TEXT
 **    --branch NEW-BRANCH-NAME
 **    --bgcolor COLOR
 **    --nosign
 **    --force|-f
+**    --private
 **
 */
 void commit_cmd(void){
   int rc;
@@ -411,8 +432,9 @@
   int nBasename;         /* Length of "g.zLocalRoot/" */
   const char *zBranch;   /* Create a new branch with this name */
   const char *zBgColor;  /* Set background color when branching */
   const char *zDateOvrd; /* Override date string */
+  const char *zUserOvrd; /* Override user name */
   Blob filename;         /* complete filename */
   Blob manifest;
   Blob muuid;            /* Manifest uuid */
   Blob mcksum;           /* Self-checksum on the manifest */
@@ -424,18 +446,32 @@
   zComment = find_option("comment","m",1);
   forceFlag = find_option("force", "f", 0)!=0;
   zBranch = find_option("branch","b",1);
   zBgColor = find_option("bgcolor",0,1);
+  if( find_option("private",0,0) ){
+    g.markPrivate = 1;
+    if( zBranch==0 ) zBranch = "private";
+    if( zBgColor==0 ) zBgColor = "#fec084";  /* Orange */
+  }
   zDateOvrd = find_option("date-override",0,1);
+  zUserOvrd = find_option("user-override",0,1);
   db_must_be_within_tree();
   noSign = db_get_boolean("omitsign", 0)|noSign;
   if( db_get_boolean("clearsign", 1)==0 ){ noSign = 1; }
   verify_all_options();
 
-  /*
-  ** Autosync if requested.
-  */
-  autosync(AUTOSYNC_PULL);
+  /* Get the ID of the parent manifest artifact */
+  vid = db_lget_int("checkout", 0);
+  if( content_is_private(vid) ){
+    g.markPrivate = 1;
+  }
+
+  /*
+  ** Autosync if autosync is enabled and this is not a private check-in.
+  */
+  if( !g.markPrivate ){
+    autosync(AUTOSYNC_PULL);
+  }
 
   /* There are two ways this command may be executed. If there are
   ** no arguments following the word "commit", then all modified files
   ** in the checked out directory are committed. If one or more arguments
@@ -481,15 +517,13 @@
       fossil_panic("file %s has not changed", blob_str(&unmodified));
     }
   }
 
-  vid = db_lget_int("checkout", 0);
-
   /*
   ** Do not allow a commit that will cause a fork unless the --force flag
-  ** is used.
-  */
-  if( zBranch==0 && forceFlag==0 && !is_a_leaf(vid) ){
+  ** is used or unless this is a private check-in.
+  */
+  if( zBranch==0 && forceFlag==0 && g.markPrivate==0 && !is_a_leaf(vid) ){
     fossil_fatal("would fork.  \"update\" first or use -f or --force.");
   }
 
   /*
@@ -557,19 +591,20 @@
   zDate = db_text(0, "SELECT datetime('%q')", zDateOvrd ? zDateOvrd : "now");
   zDate[10] = 'T';
   blob_appendf(&manifest, "D %s\n", zDate);
   db_prepare(&q,
-    "SELECT pathname, uuid, origname"
+    "SELECT pathname, uuid, origname, blob.rid"
     "  FROM vfile JOIN blob ON vfile.mrid=blob.rid"
     " WHERE NOT deleted AND vfile.vid=%d"
     " ORDER BY 1", vid);
   blob_zero(&filename);
-  blob_appendf(&filename, "%s/", g.zLocalRoot);
+  blob_appendf(&filename, "%s", g.zLocalRoot);
   nBasename = blob_size(&filename);
   while( db_step(&q)==SQLITE_ROW ){
     const char *zName = db_column_text(&q, 0);
     const char *zUuid = db_column_text(&q, 1);
     const char *zOrig = db_column_text(&q, 2);
+    int frid = db_column_int(&q, 3);
     const char *zPerm;
     blob_append(&filename, zName, -1);
     if( file_isexe(blob_str(&filename)) ){
       zPerm = " x";
@@ -582,8 +617,9 @@
     }else{
       if( zPerm[0]==0 ){ zPerm = " w"; }
       blob_appendf(&manifest, "F %F %s%s %F\n", zName, zUuid, zPerm, zOrig);
     }
+    if( !g.markPrivate ) content_make_public(frid);
   }
   blob_reset(&filename);
   db_finalize(&q);
   zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
@@ -592,8 +628,9 @@
   db_prepare(&q2, "SELECT merge FROM vmerge WHERE id=:id");
   db_bind_int(&q2, ":id", 0);
   while( db_step(&q2)==SQLITE_ROW ){
     int mid = db_column_int(&q2, 0);
+    if( !g.markPrivate && content_is_private(mid) ) continue;
     zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
     if( zUuid ){
       blob_appendf(&manifest, " %s", zUuid);
       free(zUuid);
@@ -624,13 +661,13 @@
       blob_appendf(&manifest, "T -%F *\n", zTag);
     }
     db_finalize(&q);
   }
-  blob_appendf(&manifest, "U %F\n", g.zLogin);
+  blob_appendf(&manifest, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
   md5sum_blob(&manifest, &mcksum);
   blob_appendf(&manifest, "Z %b\n", &mcksum);
   zManifestFile = mprintf("%smanifest", g.zLocalRoot);
-  if( !noSign && clearsign(&manifest, &manifest) ){
+  if( !noSign && !g.markPrivate && clearsign(&manifest, &manifest) ){
     Blob ans;
     blob_zero(&ans);
     prompt_user("unable to sign manifest.  continue [y/N]? ", &ans);
     if( blob_str(&ans)[0]!='y' ){
@@ -701,9 +738,11 @@
 
   /* Commit */
   db_end_transaction(0);
 
-  autosync(AUTOSYNC_PUSH);
+  if( !g.markPrivate ){
+    autosync(AUTOSYNC_PUSH);
+  }
   if( count_nonbranch_children(vid)>1 ){
     printf("**** warning: a fork has occurred *****\n");
   }
 }