Check-in [33c31f73cd]
Not logged in
Overview

SHA1 Hash:33c31f73cde7cb812aa1c2320c114f7076ec33dc
Date: 2008-02-21 14:27:34
User: drh
Comment:Record whether or not files have their execute permission bit set. Set or clear the execute permission bit upon checkout.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/blob.c from [e355ed75f1] to [2269ea6655].

@@ -241,10 +241,11 @@
 ** routine.  blob_str() will make a copy of the p if necessary
 ** to avoid modifying pBig.
 */
 char *blob_terminate(Blob *p){
   blob_is_init(p);
+  if( p->nUsed==0 ) return "";
   p->aData[p->nUsed] = 0;
   return p->aData;
 }
 
 /*

Modified src/checkin.c from [3db074a16d] to [f5120aa9ee].

@@ -327,10 +327,12 @@
   char *zUuid, *zDate;
   int noSign = 0;        /* True to omit signing the manifest using GPG */
   int isAMerge = 0;      /* True if checking in a merge */
   int forceFlag = 0;     /* Force a fork */
   char *zManifestFile;   /* Name of the manifest file */
+  int nBasename;         /* Length of "g.zLocalRoot/" */
+  Blob filename;         /* complete filename */
   Blob manifest;
   Blob muuid;            /* Manifest uuid */
   Blob mcksum;           /* Self-checksum on the manifest */
   Blob cksum1, cksum2;   /* Before and after commit checksums */
   Blob cksum1b;          /* Checksum recorded in the manifest */
@@ -447,15 +449,27 @@
   blob_appendf(&manifest, "D %s\n", zDate);
   db_prepare(&q,
     "SELECT pathname, uuid 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);
+  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);
-    blob_appendf(&manifest, "F %F %s\n", zName, zUuid);
-  }
+    const char *zPerm;
+    blob_append(&filename, zName, -1);
+    if( file_isexe(blob_str(&filename)) ){
+      zPerm = " x";
+    }else{
+      zPerm = "";
+    }
+    blob_resize(&filename, nBasename);
+    blob_appendf(&manifest, "F %F %s%s\n", zName, zUuid, zPerm);
+  }
+  blob_reset(&filename);
   db_finalize(&q);
   zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
   blob_appendf(&manifest, "P %s", zUuid);
 
   db_prepare(&q2, "SELECT merge FROM vmerge WHERE id=:id");

Modified src/checkout.c from [226cbdc63b] to [d833774799].

@@ -98,24 +98,40 @@
 */
 void manifest_to_disk(int vid){
   char *zManFile;
   Blob manifest;
   Blob hash;
+  Blob filename;
+  int baseLen;
+  int i;
+  Manifest m;
 
   blob_zero(&manifest);
   zManFile = mprintf("%smanifest", g.zLocalRoot);
   content_get(vid, &manifest);
   blob_write_to_file(&manifest, zManFile);
   free(zManFile);
   blob_zero(&hash);
   sha1sum_blob(&manifest, &hash);
-  blob_reset(&manifest);
   zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
   blob_append(&hash, "\n", 1);
   blob_write_to_file(&hash, zManFile);
   free(zManFile);
   blob_reset(&hash);
+  manifest_parse(&m, &manifest);
+  blob_zero(&filename);
+  blob_appendf(&filename, "%s/", g.zLocalRoot);
+  baseLen = blob_size(&filename);
+  for(i=0; i<m.nFile; i++){
+    int isExe;
+    blob_append(&filename, m.aFile[i].zName, -1);
+    isExe = m.aFile[i].zPerm && strstr(m.aFile[i].zPerm, "x");
+    file_setexe(blob_str(&filename), isExe);
+    blob_resize(&filename, baseLen);
+  }
+  blob_reset(&filename);
+  manifest_clear(&m);
 }
 
 /*
 ** COMMAND: checkout
 **

Modified src/file.c from [d8c82766a0] to [6f2a64a222].

@@ -65,10 +65,41 @@
   }
   return S_ISREG(buf.st_mode);
 }
 
 /*
+** Return TRUE if the named file is an executable.  Return false
+** for directories, devices, fifos, symlinks, etc.
+*/
+int file_isexe(const char *zFilename){
+  struct stat buf;
+  if( stat(zFilename, &buf)!=0 ){
+    return 0;
+  }
+  return ((S_IXUSR|S_IXGRP|S_IXOTH)&buf.st_mode)!=0;
+}
+
+/*
+** Set or clear the execute bit on a file.
+*/
+void file_setexe(const char *zFilename, int onoff){
+#ifndef __MINGW32__
+  struct stat buf;
+  if( stat(zFilename, &buf)!=0 ) return;
+  if( onoff ){
+    if( (buf.st_mode & 0111)==0 ){
+      chmod(zFilename, buf.st_mode | 0111);
+    }
+  }else{
+    if( (buf.st_mode & 0111)!=0 ){
+      chmod(zFilename, buf.st_mode & ~0111);
+    }
+  }
+#endif
+}
+
+/*
 ** Return 1 if zFilename is a directory.  Return 0 if zFilename
 ** does not exist.  Return 2 if zFilename exists but is something
 ** other than a directory.
 */
 int file_isdir(const char *zFilename){
@@ -75,24 +106,10 @@
   struct stat buf;
   if( stat(zFilename, &buf)!=0 ){
     return 0;
   }
   return S_ISDIR(buf.st_mode) ? 1 : 2;
-}
-
-/*
-** Find both the size and modification time of a file.  Return
-** the number of errors.
-*/
-int file_size_and_mtime(const char *zFilename, i64 *size, i64 *mtime){
-  struct stat buf;
-  if( stat(zFilename, &buf)!=0 ){
-    return 1;
-  }
-  *size = buf.st_size;
-  *mtime = buf.st_mtime;
-  return 0;
 }
 
 /*
 ** Create the directory named in the argument, if it does not already
 ** exist.  If forceFlag is 1, delete any prior non-directory object

Modified src/info.c from [0cbd863b6d] to [97d9ed98da].

@@ -558,11 +558,11 @@
   Stmt q;
   char *zUuid;
 
   login_check_credentials();
   if( !g.okHistory ){ login_needed(); return; }
-  style_header("Baseline Diff");
+  style_header("Baseline Changes");
 
   rid = name_to_rid(PD("name",""));
   if( rid==0 ){
     cgi_redirect("index");
   }
@@ -573,11 +573,11 @@
      "   AND filename.fnid=mlink.fnid"
      " ORDER BY name",
      rid
   );
   zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
-  @ <h2>All Changes In Version
+  @ <h2>All Changes In Baseline
   hyperlink_to_uuid(zUuid);
   @ </h2>
   while( db_step(&q)==SQLITE_ROW ){
     int pid = db_column_int(&q,0);
     int fid = db_column_int(&q,1);

Modified src/manifest.c from [d38866b6bd] to [64e207831c].

@@ -65,10 +65,11 @@
   int nFile;            /* Number of F lines */
   int nFileAlloc;       /* Slots allocated in aFile[] */
   struct {
     char *zName;           /* Name of a file */
     char *zUuid;           /* UUID of the file */
+    char *zPerm;           /* File permissions */
   } *aFile;
   int nParent;          /* Number of parents */
   int nParentAlloc;     /* Slots allocated in azParent[] */
   char **azParent;      /* UUIDs of parents */
   int nCChild;          /* Number of cluster children */
@@ -155,10 +156,11 @@
   blob_zero(pContent);
   pContent = &p->content;
 
   blob_zero(&a1);
   blob_zero(&a2);
+  blob_zero(&a3);
   md5sum_init();
   while( blob_line(pContent, &line) ){
     char *z = blob_buffer(&line);
     lineNo++;
     if( z[0]=='-' ){
@@ -275,24 +277,25 @@
         }
         break;
       }
 
       /*
-      **     F <filename> <uuid>
+      **     F <filename> <uuid> ?<permissions>?
       **
       ** Identifies a file in a manifest.  Multiple F lines are
       ** allowed in a manifest.  F lines are not allowed in any
       ** other control file.  The filename is fossil-encoded.
       */
       case 'F': {
-        char *zName, *zUuid;
+        char *zName, *zUuid, *zPerm;
         md5sum_step_text(blob_buffer(&line), blob_size(&line));
         if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
         if( blob_token(&line, &a2)==0 ) goto manifest_syntax_error;
-        if( blob_token(&line, &a3)!=0 ) goto manifest_syntax_error;
         zName = blob_terminate(&a1);
         zUuid = blob_terminate(&a2);
+        blob_token(&line, &a3);
+        zPerm = blob_terminate(&a3);
         if( blob_size(&a2)!=UUID_SIZE ) goto manifest_syntax_error;
         if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error;
         defossilize(zName);
         if( !file_is_simple_pathname(zName) ){
           goto manifest_syntax_error;
@@ -303,10 +306,11 @@
           if( p->aFile==0 ) fossil_panic("out of memory");
         }
         i = p->nFile++;
         p->aFile[i].zName = zName;
         p->aFile[i].zUuid = zUuid;
+        p->aFile[i].zPerm = zPerm;
         if( i>0 && strcmp(p->aFile[i-1].zName, zName)>=0 ){
           goto manifest_syntax_error;
         }
         break;
       }

Modified src/schema.c from [07530b805a] to [f141028e53].

@@ -299,11 +299,11 @@
 @ -- is already in the repository.
 @ --
 @ --
 @ CREATE TABLE vfile(
 @   id INTEGER PRIMARY KEY,           -- ID of the checked out file
-@   vid INTEGER REFERENCES blob,      -- The version this file is part of.
+@   vid INTEGER REFERENCES blob,      -- The baseline this file is part of.
 @   chnged INT DEFAULT 0,             -- 0:unchnged 1:edited 2:m-chng 3:m-add
 @   deleted BOOLEAN DEFAULT 0,        -- True if deleted
 @   rid INTEGER,                      -- Originally from this repository record
 @   mrid INTEGER,                     -- Based on this record due to a merge
 @   pathname TEXT,                    -- Full pathname
@@ -320,21 +320,6 @@
 @   id INTEGER REFERENCES vfile,      -- VFILE entry that has been merged
 @   merge INTEGER,                    -- Merged with this record
 @   UNIQUE(id, merge)
 @ );
 @
-;
-
-const char zServerTempSchema[] =
-@ -- A copy of the vfile table schema used by the WWW server
-@ --
-@ CREATE TEMP TABLE vfile(
-@   id INTEGER PRIMARY KEY,           -- ID of the checked out file
-@   vid INTEGER REFERENCES record,    -- The version this file is part of.
-@   chnged INT DEFAULT 0,             -- 0:unchnged 1:edited 2:m-chng 3:m-add
-@   deleted BOOLEAN DEFAULT 0,        -- True if deleted
-@   rid INTEGER,                      -- Originally from this repository record
-@   mrid INTEGER,                     -- Based on this record due to a merge
-@   pathname TEXT,                    -- Full pathname
-@   UNIQUE(pathname,vid)
-@ );
 ;

Modified src/update.c from [69c9aea1a1] to [70dcd36640].

@@ -67,17 +67,10 @@
     fossil_fatal("cannot find current version");
   }
   if( db_exists("SELECT 1 FROM vmerge") ){
     fossil_fatal("cannot update an uncommitted merge");
   }
-#if 0
-  /* Always do the update.  If it does not work out, the user can back out
-  ** the changes using "undo" */
-  if( !forceFlag && unsaved_changes() ){
-    fossil_fatal("uncommitted changes; use -f or --force to override");
-  }
-#endif
 
   if( g.argc==3 ){
     tid = name_to_rid(g.argv[2]);
     if( tid==0 ){
       fossil_fatal("not a version: %s", g.argv[2]);