Check-in [76f169fca6]
Not logged in
Overview

SHA1 Hash:76f169fca6c040496b14bd37a9e2c5e00f0a797b
Date: 2009-12-18 00:29:51
User: drh
Comment:Detect when the check-out contains missing files and filesystem objects that ought to be files but are not. Issue reasonable warnings.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/checkin.c from [50415ea96d] to [43b7742fd6].

@@ -31,14 +31,22 @@
 /*
 ** Generate text describing all changes.  Prepend zPrefix to each line
 ** of output.
 **
 ** We assume that vfile_check_signature has been run.
+**
+** If missingIsFatal is true, then any files that are missing or which
+** are not true files results in a fatal error.
 */
-static void status_report(Blob *report, const char *zPrefix){
+static void status_report(
+  Blob *report,          /* Append the status report here */
+  const char *zPrefix,   /* Prefix on each line of the report */
+  int missingIsFatal     /* MISSING and NOT_A_FILE are fatal errors */
+){
   Stmt q;
   int nPrefix = strlen(zPrefix);
+  int nErr = 0;
   db_prepare(&q,
     "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
     "  FROM vfile "
     " WHERE file_is_selected(id)"
     "   AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1"
@@ -50,25 +58,37 @@
     int isNew = db_column_int(&q,3)==0;
     int isRenamed = db_column_int(&q,4);
     char *zFullName = mprintf("%s/%s", g.zLocalRoot, zPathname);
     blob_append(report, zPrefix, nPrefix);
     if( isDeleted ){
-      blob_appendf(report, "DELETED  %s\n", zPathname);
-    }else if( access(zFullName, 0) ){
-      blob_appendf(report, "MISSING  %s\n", zPathname);
+      blob_appendf(report, "DELETED    %s\n", zPathname);
+    }else if( !file_isfile(zFullName) ){
+      if( access(zFullName, 0)==0 ){
+        blob_appendf(report, "NOT_A_FILE %s\n", zPathname);
+        if( missingIsFatal ){
+          fossil_warning("not a file: %s", zPathname);
+          nErr++;
+        }
+      }else{
+        blob_appendf(report, "MISSING    %s\n", zPathname);
+        if( missingIsFatal ){
+          fossil_warning("missing file: %s", zPathname);
+          nErr++;
+        }
+      }
     }else if( isNew ){
-      blob_appendf(report, "ADDED    %s\n", zPathname);
+      blob_appendf(report, "ADDED      %s\n", zPathname);
     }else if( isDeleted ){
-      blob_appendf(report, "DELETED  %s\n", zPathname);
+      blob_appendf(report, "DELETED    %s\n", zPathname);
     }else if( isChnged==2 ){
       blob_appendf(report, "UPDATED_BY_MERGE %s\n", zPathname);
     }else if( isChnged==3 ){
       blob_appendf(report, "ADDED_BY_MERGE %s\n", zPathname);
     }else if( isChnged==1 ){
-      blob_appendf(report, "EDITED   %s\n", zPathname);
+      blob_appendf(report, "EDITED     %s\n", zPathname);
     }else if( isRenamed ){
-      blob_appendf(report, "RENAMED  %s\n", zPathname);
+      blob_appendf(report, "RENAMED    %s\n", zPathname);
     }
     free(zFullName);
   }
   db_finalize(&q);
   db_prepare(&q, "SELECT uuid FROM vmerge JOIN blob ON merge=rid"
@@ -76,10 +96,13 @@
   while( db_step(&q)==SQLITE_ROW ){
     blob_append(report, zPrefix, nPrefix);
     blob_appendf(report, "MERGED_WITH %s\n", db_column_text(&q, 0));
   }
   db_finalize(&q);
+  if( nErr ){
+    fossil_fatal("aborting due to prior errors");
+  }
 }
 
 /*
 ** COMMAND: changes
 **
@@ -92,12 +115,12 @@
   Blob report;
   int vid;
   db_must_be_within_tree();
   blob_zero(&report);
   vid = db_lget_int("checkout", 0);
-  vfile_check_signature(vid);
-  status_report(&report, "");
+  vfile_check_signature(vid, 0);
+  status_report(&report, "", 0);
   blob_write_to_file(&report, "-");
 }
 
 /*
 ** COMMAND: status
@@ -134,11 +157,11 @@
   int isBrief;
 
   isBrief = find_option("l","l", 0)==0;
   db_must_be_within_tree();
   vid = db_lget_int("checkout", 0);
-  vfile_check_signature(vid);
+  vfile_check_signature(vid, 0);
   db_prepare(&q,
      "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
      "  FROM vfile"
      " ORDER BY 1"
   );
@@ -150,21 +173,25 @@
     int renamed = db_column_int(&q,4);
     char *zFullName = mprintf("%s/%s", g.zLocalRoot, zPathname);
     if( isBrief ){
       printf("%s\n", zPathname);
     }else if( isNew ){
-      printf("ADDED     %s\n", zPathname);
-    }else if( access(zFullName, 0) ){
-      printf("MISSING   %s\n", zPathname);
+      printf("ADDED      %s\n", zPathname);
+    }else if( !file_isfile(zFullName) ){
+      if( access(zFullName, 0)==0 ){
+        printf("NOT_A_FILE %s\n", zPathname);
+      }else{
+        printf("MISSING    %s\n", zPathname);
+      }
     }else if( isDeleted ){
-      printf("DELETED   %s\n", zPathname);
+      printf("DELETED    %s\n", zPathname);
     }else if( chnged ){
-      printf("EDITED    %s\n", zPathname);
+      printf("EDITED     %s\n", zPathname);
     }else if( renamed ){
-      printf("RENAMED   %s\n", zPathname);
+      printf("RENAMED    %s\n", zPathname);
     }else{
-      printf("UNCHANGED %s\n", zPathname);
+      printf("UNCHANGED  %s\n", zPathname);
     }
     free(zFullName);
   }
   db_finalize(&q);
 }
@@ -303,11 +330,11 @@
       "# PRIVATE BRANCH: This check-in will be private and will not sync to\n"
       "# repositories.\n"
       "#\n", -1
     );
   }
-  status_report(&text, "# ");
+  status_report(&text, "# ", 1);
   zEditor = db_get("editor", 0);
   if( zEditor==0 ){
     zEditor = getenv("VISUAL");
   }
   if( zEditor==0 ){

Modified src/checkout.c from [093dea6b92] to [93e8f5c3cb].

@@ -39,11 +39,11 @@
 int unsaved_changes(void){
   int vid;
   db_must_be_within_tree();
   vid = db_lget_int("checkout",0);
   if( vid==0 ) return 2;
-  vfile_check_signature(vid);
+  vfile_check_signature(vid, 1);
   return db_exists("SELECT 1 FROM vfile WHERE chnged"
                    " OR coalesce(origname!=pathname,0)");
 }
 
 /*

Modified src/diffcmd.c from [88a94ee318] to [6b2be81037].

@@ -207,11 +207,11 @@
   int vid;
   Blob sql;
   Stmt q;
 
   vid = db_lget_int("checkout", 0);
-  vfile_check_signature(vid);
+  vfile_check_signature(vid, 1);
   blob_zero(&sql);
   db_begin_transaction();
   if( zFrom ){
     int rid = name_to_rid(zFrom);
     if( !is_a_version(rid) ){

Modified src/merge.c from [5979683d08] to [1bca64b642].

@@ -77,11 +77,11 @@
                  "checkout and %s", g.argv[2]);
   }
   if( pid>1 && !db_exists("SELECT 1 FROM plink WHERE cid=%d", pid) ){
     fossil_panic("not a version: record #%d", mid);
   }
-  vfile_check_signature(vid);
+  vfile_check_signature(vid, 1);
   db_begin_transaction();
   undo_begin();
   load_vfile_from_rid(mid);
   load_vfile_from_rid(pid);
 

Modified src/update.c from [68eb293803] to [cbdf43d095].

@@ -118,11 +118,11 @@
                     " WHERE event.objid=leaves.rid"
                     " ORDER BY event.mtime DESC");
   }
 
   db_begin_transaction();
-  vfile_check_signature(vid);
+  vfile_check_signature(vid, 1);
   undo_begin();
   load_vfile_from_rid(tid);
 
   /*
   ** The record.fn field is used to match files against each other.  The

Modified src/vfile.c from [976e15ff22] to [882972137d].

@@ -142,11 +142,11 @@
 ** that has changed.
 **
 ** If VFILE.DELETED is null or if VFILE.RID is zero, then we can assume
 ** the file has changed without having the check the on-disk image.
 */
-void vfile_check_signature(int vid){
+void vfile_check_signature(int vid, int notFileIsFatal){
   int nErr = 0;
   Stmt q;
   Blob fileCksum, origCksum;
   int checkMtime = db_get_boolean("mtime-changes", 0);
 
@@ -168,15 +168,16 @@
     rid = db_column_int(&q, 2);
     isDeleted = db_column_int(&q, 3);
     oldChnged = db_column_int(&q, 4);
     oldMtime = db_column_int64(&q, 6);
     if( !file_isfile(zName) && file_size(zName)>=0 ){
-      fossil_warning("not a ordinary file: %s", zName);
-      nErr++;
-      continue;
-    }
-    if( oldChnged>=2 ){
+      if( notFileIsFatal ){
+        fossil_warning("not a ordinary file: %s", zName);
+        nErr++;
+      }
+      chnged = 1;
+    }else if( oldChnged>=2 ){
       chnged = oldChnged;
     }else if( isDeleted || rid==0 ){
       chnged = 1;
     }
     if( chnged!=1 ){