Fossil SCM
Windows clients now preserve the execute permission bits when doing a commit.
Commit
356fc21d40ef3ea70d661a73a6af6b287fbff32e
Parent
46d98dd5552cffc…
5 files changed
+9
-2
+9
+14
+1
-1
+1
+9
-2
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -687,11 +687,11 @@ | ||
| 687 | 687 | zDate = db_text(0, "SELECT datetime('%q')", zDateOvrd ? zDateOvrd : "now"); |
| 688 | 688 | zDate[10] = 'T'; |
| 689 | 689 | blob_appendf(&manifest, "D %s\n", zDate); |
| 690 | 690 | zDate[10] = ' '; |
| 691 | 691 | db_prepare(&q, |
| 692 | - "SELECT pathname, uuid, origname, blob.rid" | |
| 692 | + "SELECT pathname, uuid, origname, blob.rid, isexe" | |
| 693 | 693 | " FROM vfile JOIN blob ON vfile.mrid=blob.rid" |
| 694 | 694 | " WHERE NOT deleted AND vfile.vid=%d" |
| 695 | 695 | " ORDER BY 1", vid); |
| 696 | 696 | blob_zero(&filename); |
| 697 | 697 | blob_appendf(&filename, "%s", g.zLocalRoot); |
| @@ -699,13 +699,20 @@ | ||
| 699 | 699 | while( db_step(&q)==SQLITE_ROW ){ |
| 700 | 700 | const char *zName = db_column_text(&q, 0); |
| 701 | 701 | const char *zUuid = db_column_text(&q, 1); |
| 702 | 702 | const char *zOrig = db_column_text(&q, 2); |
| 703 | 703 | int frid = db_column_int(&q, 3); |
| 704 | + int isexe = db_column_int(&q, 4); | |
| 704 | 705 | const char *zPerm; |
| 705 | 706 | blob_append(&filename, zName, -1); |
| 706 | - if( file_isexe(blob_str(&filename)) ){ | |
| 707 | +#ifndef __MINGW32__ | |
| 708 | + /* For unix, extract the "executable" permission bit directly from | |
| 709 | + ** the filesystem. On windows, the "executable" bit is retained | |
| 710 | + ** unchanged from the original. */ | |
| 711 | + isexe = file_isexe(blob_str(&filename)); | |
| 712 | +#endif | |
| 713 | + if( isexe ){ | |
| 707 | 714 | zPerm = " x"; |
| 708 | 715 | }else{ |
| 709 | 716 | zPerm = ""; |
| 710 | 717 | } |
| 711 | 718 | blob_resize(&filename, nBasename); |
| 712 | 719 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -687,11 +687,11 @@ | |
| 687 | zDate = db_text(0, "SELECT datetime('%q')", zDateOvrd ? zDateOvrd : "now"); |
| 688 | zDate[10] = 'T'; |
| 689 | blob_appendf(&manifest, "D %s\n", zDate); |
| 690 | zDate[10] = ' '; |
| 691 | db_prepare(&q, |
| 692 | "SELECT pathname, uuid, origname, blob.rid" |
| 693 | " FROM vfile JOIN blob ON vfile.mrid=blob.rid" |
| 694 | " WHERE NOT deleted AND vfile.vid=%d" |
| 695 | " ORDER BY 1", vid); |
| 696 | blob_zero(&filename); |
| 697 | blob_appendf(&filename, "%s", g.zLocalRoot); |
| @@ -699,13 +699,20 @@ | |
| 699 | while( db_step(&q)==SQLITE_ROW ){ |
| 700 | const char *zName = db_column_text(&q, 0); |
| 701 | const char *zUuid = db_column_text(&q, 1); |
| 702 | const char *zOrig = db_column_text(&q, 2); |
| 703 | int frid = db_column_int(&q, 3); |
| 704 | const char *zPerm; |
| 705 | blob_append(&filename, zName, -1); |
| 706 | if( file_isexe(blob_str(&filename)) ){ |
| 707 | zPerm = " x"; |
| 708 | }else{ |
| 709 | zPerm = ""; |
| 710 | } |
| 711 | blob_resize(&filename, nBasename); |
| 712 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -687,11 +687,11 @@ | |
| 687 | zDate = db_text(0, "SELECT datetime('%q')", zDateOvrd ? zDateOvrd : "now"); |
| 688 | zDate[10] = 'T'; |
| 689 | blob_appendf(&manifest, "D %s\n", zDate); |
| 690 | zDate[10] = ' '; |
| 691 | db_prepare(&q, |
| 692 | "SELECT pathname, uuid, origname, blob.rid, isexe" |
| 693 | " FROM vfile JOIN blob ON vfile.mrid=blob.rid" |
| 694 | " WHERE NOT deleted AND vfile.vid=%d" |
| 695 | " ORDER BY 1", vid); |
| 696 | blob_zero(&filename); |
| 697 | blob_appendf(&filename, "%s", g.zLocalRoot); |
| @@ -699,13 +699,20 @@ | |
| 699 | while( db_step(&q)==SQLITE_ROW ){ |
| 700 | const char *zName = db_column_text(&q, 0); |
| 701 | const char *zUuid = db_column_text(&q, 1); |
| 702 | const char *zOrig = db_column_text(&q, 2); |
| 703 | int frid = db_column_int(&q, 3); |
| 704 | int isexe = db_column_int(&q, 4); |
| 705 | const char *zPerm; |
| 706 | blob_append(&filename, zName, -1); |
| 707 | #ifndef __MINGW32__ |
| 708 | /* For unix, extract the "executable" permission bit directly from |
| 709 | ** the filesystem. On windows, the "executable" bit is retained |
| 710 | ** unchanged from the original. */ |
| 711 | isexe = file_isexe(blob_str(&filename)); |
| 712 | #endif |
| 713 | if( isexe ){ |
| 714 | zPerm = " x"; |
| 715 | }else{ |
| 716 | zPerm = ""; |
| 717 | } |
| 718 | blob_resize(&filename, nBasename); |
| 719 |
+9
| --- src/checkout.c | ||
| +++ src/checkout.c | ||
| @@ -93,10 +93,18 @@ | ||
| 93 | 93 | } |
| 94 | 94 | content_get(vid, &manifest); |
| 95 | 95 | vfile_build(vid, &manifest); |
| 96 | 96 | blob_reset(&manifest); |
| 97 | 97 | } |
| 98 | + | |
| 99 | +/* | |
| 100 | +** Set or clear the vfile.isexe flag for a file. | |
| 101 | +*/ | |
| 102 | +static void set_or_clear_isexe(const char *zFilename, int vid, int onoff){ | |
| 103 | + db_multi_exec("UPDATE vfile SET isexe=%d WHERE vid=%d and pathname=%Q", | |
| 104 | + onoff, vid, zFilename); | |
| 105 | +} | |
| 98 | 106 | |
| 99 | 107 | /* |
| 100 | 108 | ** Read the manifest file given by vid out of the repository |
| 101 | 109 | ** and store it in the root of the local check-out. |
| 102 | 110 | */ |
| @@ -128,10 +136,11 @@ | ||
| 128 | 136 | for(i=0; i<m.nFile; i++){ |
| 129 | 137 | int isExe; |
| 130 | 138 | blob_append(&filename, m.aFile[i].zName, -1); |
| 131 | 139 | isExe = m.aFile[i].zPerm && strstr(m.aFile[i].zPerm, "x"); |
| 132 | 140 | file_setexe(blob_str(&filename), isExe); |
| 141 | + set_or_clear_isexe(m.aFile[i].zName, vid, isExe); | |
| 133 | 142 | blob_resize(&filename, baseLen); |
| 134 | 143 | } |
| 135 | 144 | blob_reset(&filename); |
| 136 | 145 | manifest_clear(&m); |
| 137 | 146 | } |
| 138 | 147 |
| --- src/checkout.c | |
| +++ src/checkout.c | |
| @@ -93,10 +93,18 @@ | |
| 93 | } |
| 94 | content_get(vid, &manifest); |
| 95 | vfile_build(vid, &manifest); |
| 96 | blob_reset(&manifest); |
| 97 | } |
| 98 | |
| 99 | /* |
| 100 | ** Read the manifest file given by vid out of the repository |
| 101 | ** and store it in the root of the local check-out. |
| 102 | */ |
| @@ -128,10 +136,11 @@ | |
| 128 | for(i=0; i<m.nFile; i++){ |
| 129 | int isExe; |
| 130 | blob_append(&filename, m.aFile[i].zName, -1); |
| 131 | isExe = m.aFile[i].zPerm && strstr(m.aFile[i].zPerm, "x"); |
| 132 | file_setexe(blob_str(&filename), isExe); |
| 133 | blob_resize(&filename, baseLen); |
| 134 | } |
| 135 | blob_reset(&filename); |
| 136 | manifest_clear(&m); |
| 137 | } |
| 138 |
| --- src/checkout.c | |
| +++ src/checkout.c | |
| @@ -93,10 +93,18 @@ | |
| 93 | } |
| 94 | content_get(vid, &manifest); |
| 95 | vfile_build(vid, &manifest); |
| 96 | blob_reset(&manifest); |
| 97 | } |
| 98 | |
| 99 | /* |
| 100 | ** Set or clear the vfile.isexe flag for a file. |
| 101 | */ |
| 102 | static void set_or_clear_isexe(const char *zFilename, int vid, int onoff){ |
| 103 | db_multi_exec("UPDATE vfile SET isexe=%d WHERE vid=%d and pathname=%Q", |
| 104 | onoff, vid, zFilename); |
| 105 | } |
| 106 | |
| 107 | /* |
| 108 | ** Read the manifest file given by vid out of the repository |
| 109 | ** and store it in the root of the local check-out. |
| 110 | */ |
| @@ -128,10 +136,11 @@ | |
| 136 | for(i=0; i<m.nFile; i++){ |
| 137 | int isExe; |
| 138 | blob_append(&filename, m.aFile[i].zName, -1); |
| 139 | isExe = m.aFile[i].zPerm && strstr(m.aFile[i].zPerm, "x"); |
| 140 | file_setexe(blob_str(&filename), isExe); |
| 141 | set_or_clear_isexe(m.aFile[i].zName, vid, isExe); |
| 142 | blob_resize(&filename, baseLen); |
| 143 | } |
| 144 | blob_reset(&filename); |
| 145 | manifest_clear(&m); |
| 146 | } |
| 147 |
M
src/db.c
+14
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -667,29 +667,43 @@ | ||
| 667 | 667 | db_open_or_attach(zDbName, "localdb"); |
| 668 | 668 | g.localOpen = 1; |
| 669 | 669 | db_open_config(0); |
| 670 | 670 | db_open_repository(0); |
| 671 | 671 | |
| 672 | + /* If the "isexe" column is missing from the vfile table, then | |
| 673 | + ** add it now. This code added on 2010-03-06. After all users have | |
| 674 | + ** upgraded, this code can be safely deleted. | |
| 675 | + */ | |
| 676 | + rc = sqlite3_prepare(g.db, "SELECT isexe FROM vfile", -1, &pStmt, 0); | |
| 677 | + sqlite3_finalize(pStmt); | |
| 678 | + if( rc==SQLITE_ERROR ){ | |
| 679 | + sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN isexe BOOLEAN", 0, 0, 0); | |
| 680 | + } | |
| 681 | + | |
| 682 | +#if 0 | |
| 672 | 683 | /* If the "mtime" column is missing from the vfile table, then |
| 673 | 684 | ** add it now. This code added on 2008-12-06. After all users have |
| 674 | 685 | ** upgraded, this code can be safely deleted. |
| 675 | 686 | */ |
| 676 | 687 | rc = sqlite3_prepare(g.db, "SELECT mtime FROM vfile", -1, &pStmt, 0); |
| 677 | 688 | sqlite3_finalize(pStmt); |
| 678 | 689 | if( rc==SQLITE_ERROR ){ |
| 679 | 690 | sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN mtime INTEGER", 0, 0, 0); |
| 680 | 691 | } |
| 692 | +#endif | |
| 681 | 693 | |
| 694 | +#if 0 | |
| 682 | 695 | /* If the "origname" column is missing from the vfile table, then |
| 683 | 696 | ** add it now. This code added on 2008-11-09. After all users have |
| 684 | 697 | ** upgraded, this code can be safely deleted. |
| 685 | 698 | */ |
| 686 | 699 | rc = sqlite3_prepare(g.db, "SELECT origname FROM vfile", -1, &pStmt, 0); |
| 687 | 700 | sqlite3_finalize(pStmt); |
| 688 | 701 | if( rc==SQLITE_ERROR ){ |
| 689 | 702 | sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN origname TEXT", 0, 0, 0); |
| 690 | 703 | } |
| 704 | +#endif | |
| 691 | 705 | |
| 692 | 706 | return 1; |
| 693 | 707 | } |
| 694 | 708 | |
| 695 | 709 | /* |
| 696 | 710 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -667,29 +667,43 @@ | |
| 667 | db_open_or_attach(zDbName, "localdb"); |
| 668 | g.localOpen = 1; |
| 669 | db_open_config(0); |
| 670 | db_open_repository(0); |
| 671 | |
| 672 | /* If the "mtime" column is missing from the vfile table, then |
| 673 | ** add it now. This code added on 2008-12-06. After all users have |
| 674 | ** upgraded, this code can be safely deleted. |
| 675 | */ |
| 676 | rc = sqlite3_prepare(g.db, "SELECT mtime FROM vfile", -1, &pStmt, 0); |
| 677 | sqlite3_finalize(pStmt); |
| 678 | if( rc==SQLITE_ERROR ){ |
| 679 | sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN mtime INTEGER", 0, 0, 0); |
| 680 | } |
| 681 | |
| 682 | /* If the "origname" column is missing from the vfile table, then |
| 683 | ** add it now. This code added on 2008-11-09. After all users have |
| 684 | ** upgraded, this code can be safely deleted. |
| 685 | */ |
| 686 | rc = sqlite3_prepare(g.db, "SELECT origname FROM vfile", -1, &pStmt, 0); |
| 687 | sqlite3_finalize(pStmt); |
| 688 | if( rc==SQLITE_ERROR ){ |
| 689 | sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN origname TEXT", 0, 0, 0); |
| 690 | } |
| 691 | |
| 692 | return 1; |
| 693 | } |
| 694 | |
| 695 | /* |
| 696 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -667,29 +667,43 @@ | |
| 667 | db_open_or_attach(zDbName, "localdb"); |
| 668 | g.localOpen = 1; |
| 669 | db_open_config(0); |
| 670 | db_open_repository(0); |
| 671 | |
| 672 | /* If the "isexe" column is missing from the vfile table, then |
| 673 | ** add it now. This code added on 2010-03-06. After all users have |
| 674 | ** upgraded, this code can be safely deleted. |
| 675 | */ |
| 676 | rc = sqlite3_prepare(g.db, "SELECT isexe FROM vfile", -1, &pStmt, 0); |
| 677 | sqlite3_finalize(pStmt); |
| 678 | if( rc==SQLITE_ERROR ){ |
| 679 | sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN isexe BOOLEAN", 0, 0, 0); |
| 680 | } |
| 681 | |
| 682 | #if 0 |
| 683 | /* If the "mtime" column is missing from the vfile table, then |
| 684 | ** add it now. This code added on 2008-12-06. After all users have |
| 685 | ** upgraded, this code can be safely deleted. |
| 686 | */ |
| 687 | rc = sqlite3_prepare(g.db, "SELECT mtime FROM vfile", -1, &pStmt, 0); |
| 688 | sqlite3_finalize(pStmt); |
| 689 | if( rc==SQLITE_ERROR ){ |
| 690 | sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN mtime INTEGER", 0, 0, 0); |
| 691 | } |
| 692 | #endif |
| 693 | |
| 694 | #if 0 |
| 695 | /* If the "origname" column is missing from the vfile table, then |
| 696 | ** add it now. This code added on 2008-11-09. After all users have |
| 697 | ** upgraded, this code can be safely deleted. |
| 698 | */ |
| 699 | rc = sqlite3_prepare(g.db, "SELECT origname FROM vfile", -1, &pStmt, 0); |
| 700 | sqlite3_finalize(pStmt); |
| 701 | if( rc==SQLITE_ERROR ){ |
| 702 | sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN origname TEXT", 0, 0, 0); |
| 703 | } |
| 704 | #endif |
| 705 | |
| 706 | return 1; |
| 707 | } |
| 708 | |
| 709 | /* |
| 710 |
+1
-1
| --- src/file.c | ||
| +++ src/file.c | ||
| @@ -163,11 +163,11 @@ | ||
| 163 | 163 | }else{ |
| 164 | 164 | if( (buf.st_mode & 0111)!=0 ){ |
| 165 | 165 | chmod(zFilename, buf.st_mode & ~0111); |
| 166 | 166 | } |
| 167 | 167 | } |
| 168 | -#endif | |
| 168 | +#endif /* __MINGW32__ */ | |
| 169 | 169 | } |
| 170 | 170 | |
| 171 | 171 | /* |
| 172 | 172 | ** Create the directory named in the argument, if it does not already |
| 173 | 173 | ** exist. If forceFlag is 1, delete any prior non-directory object |
| 174 | 174 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -163,11 +163,11 @@ | |
| 163 | }else{ |
| 164 | if( (buf.st_mode & 0111)!=0 ){ |
| 165 | chmod(zFilename, buf.st_mode & ~0111); |
| 166 | } |
| 167 | } |
| 168 | #endif |
| 169 | } |
| 170 | |
| 171 | /* |
| 172 | ** Create the directory named in the argument, if it does not already |
| 173 | ** exist. If forceFlag is 1, delete any prior non-directory object |
| 174 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -163,11 +163,11 @@ | |
| 163 | }else{ |
| 164 | if( (buf.st_mode & 0111)!=0 ){ |
| 165 | chmod(zFilename, buf.st_mode & ~0111); |
| 166 | } |
| 167 | } |
| 168 | #endif /* __MINGW32__ */ |
| 169 | } |
| 170 | |
| 171 | /* |
| 172 | ** Create the directory named in the argument, if it does not already |
| 173 | ** exist. If forceFlag is 1, delete any prior non-directory object |
| 174 |
+1
| --- src/schema.c | ||
| +++ src/schema.c | ||
| @@ -393,10 +393,11 @@ | ||
| 393 | 393 | @ CREATE TABLE vfile( |
| 394 | 394 | @ id INTEGER PRIMARY KEY, -- ID of the checked out file |
| 395 | 395 | @ vid INTEGER REFERENCES blob, -- The baseline this file is part of. |
| 396 | 396 | @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add |
| 397 | 397 | @ deleted BOOLEAN DEFAULT 0, -- True if deleted |
| 398 | +@ isexe BOOLEAN, -- True if file should be executable | |
| 398 | 399 | @ rid INTEGER, -- Originally from this repository record |
| 399 | 400 | @ mrid INTEGER, -- Based on this record due to a merge |
| 400 | 401 | @ mtime INTEGER, -- Modification time of file on disk |
| 401 | 402 | @ pathname TEXT, -- Full pathname relative to root |
| 402 | 403 | @ origname TEXT, -- Original pathname. NULL if unchanged |
| 403 | 404 |
| --- src/schema.c | |
| +++ src/schema.c | |
| @@ -393,10 +393,11 @@ | |
| 393 | @ CREATE TABLE vfile( |
| 394 | @ id INTEGER PRIMARY KEY, -- ID of the checked out file |
| 395 | @ vid INTEGER REFERENCES blob, -- The baseline this file is part of. |
| 396 | @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add |
| 397 | @ deleted BOOLEAN DEFAULT 0, -- True if deleted |
| 398 | @ rid INTEGER, -- Originally from this repository record |
| 399 | @ mrid INTEGER, -- Based on this record due to a merge |
| 400 | @ mtime INTEGER, -- Modification time of file on disk |
| 401 | @ pathname TEXT, -- Full pathname relative to root |
| 402 | @ origname TEXT, -- Original pathname. NULL if unchanged |
| 403 |
| --- src/schema.c | |
| +++ src/schema.c | |
| @@ -393,10 +393,11 @@ | |
| 393 | @ CREATE TABLE vfile( |
| 394 | @ id INTEGER PRIMARY KEY, -- ID of the checked out file |
| 395 | @ vid INTEGER REFERENCES blob, -- The baseline this file is part of. |
| 396 | @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add |
| 397 | @ deleted BOOLEAN DEFAULT 0, -- True if deleted |
| 398 | @ isexe BOOLEAN, -- True if file should be executable |
| 399 | @ rid INTEGER, -- Originally from this repository record |
| 400 | @ mrid INTEGER, -- Based on this record due to a merge |
| 401 | @ mtime INTEGER, -- Modification time of file on disk |
| 402 | @ pathname TEXT, -- Full pathname relative to root |
| 403 | @ origname TEXT, -- Original pathname. NULL if unchanged |
| 404 |