Fossil SCM

Add the ability to detect file changes using only the mtime. This is turned on using the "fossil setting mtime-changes ON" command. It is off by default, but it does make many operations go much faster, especially on large repositories, so we might want to start turning it on by default.

drh 2008-12-06 18:02 trunk
Commit 2dffce041d44564bb95515e0f9d344c4a4ba80f7
3 files changed +18 -1 +1 +14 -1
+18 -1
--- src/db.c
+++ src/db.c
@@ -686,14 +686,27 @@
686686
if( lsize%1024!=0 || lsize<4096 ) return 0;
687687
db_open_or_attach(zDbName, "localdb");
688688
g.localOpen = 1;
689689
db_open_config();
690690
db_open_repository(0);
691
+
692
+ /* If the "mtime" column is missing from the vfile table, then
693
+ ** add it now. This code added on 2008-12-06. After all users have
694
+ ** upgraded, this code can be safely deleted.
695
+ */
696
+ rc = sqlite3_prepare(g.db, "SELECT mtime FROM vfile", -1, &pStmt, 0);
697
+ sqlite3_finalize(pStmt);
698
+ if( rc==SQLITE_ERROR ){
699
+ sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN mtime INTEGER", 0, 0, 0);
700
+ }
691701
692702
/* If the "origname" column is missing from the vfile table, then
693
- ** add it now. */
703
+ ** add it now. This code added on 2008-11-09. After all users have
704
+ ** upgraded, this code can be safely deleted.
705
+ */
694706
rc = sqlite3_prepare(g.db, "SELECT origname FROM vfile", -1, &pStmt, 0);
707
+ sqlite3_finalize(pStmt);
695708
if( rc==SQLITE_ERROR ){
696709
sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN origname TEXT", 0, 0, 0);
697710
}
698711
699712
return 1;
@@ -1323,10 +1336,13 @@
13231336
** sign all commits with gpg. When disabled, commits will
13241337
** be unsigned.
13251338
**
13261339
** pgp-command Command used to clear-sign manifests at check-in.
13271340
** The default is "gpg --clearsign -o ".
1341
+**
1342
+** mtime-changes Use file modification times (mtimes) to detect when
1343
+** files have been modified.
13281344
**
13291345
** proxy URL of the HTTP proxy. If undefined or "off" then
13301346
** the "http_proxy" environment variable is consulted.
13311347
** If the http_proxy environment variable is undefined
13321348
** then a direct HTTP connection is used.
@@ -1344,10 +1360,11 @@
13441360
"gdiff-command",
13451361
"http-port",
13461362
"localauth",
13471363
"clearsign",
13481364
"pgp-command",
1365
+ "mtime-changes",
13491366
"proxy",
13501367
"web-browser",
13511368
};
13521369
int i;
13531370
int globalFlag = find_option("global","g",0)!=0;
13541371
--- src/db.c
+++ src/db.c
@@ -686,14 +686,27 @@
686 if( lsize%1024!=0 || lsize<4096 ) return 0;
687 db_open_or_attach(zDbName, "localdb");
688 g.localOpen = 1;
689 db_open_config();
690 db_open_repository(0);
 
 
 
 
 
 
 
 
 
 
691
692 /* If the "origname" column is missing from the vfile table, then
693 ** add it now. */
 
 
694 rc = sqlite3_prepare(g.db, "SELECT origname FROM vfile", -1, &pStmt, 0);
 
695 if( rc==SQLITE_ERROR ){
696 sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN origname TEXT", 0, 0, 0);
697 }
698
699 return 1;
@@ -1323,10 +1336,13 @@
1323 ** sign all commits with gpg. When disabled, commits will
1324 ** be unsigned.
1325 **
1326 ** pgp-command Command used to clear-sign manifests at check-in.
1327 ** The default is "gpg --clearsign -o ".
 
 
 
1328 **
1329 ** proxy URL of the HTTP proxy. If undefined or "off" then
1330 ** the "http_proxy" environment variable is consulted.
1331 ** If the http_proxy environment variable is undefined
1332 ** then a direct HTTP connection is used.
@@ -1344,10 +1360,11 @@
1344 "gdiff-command",
1345 "http-port",
1346 "localauth",
1347 "clearsign",
1348 "pgp-command",
 
1349 "proxy",
1350 "web-browser",
1351 };
1352 int i;
1353 int globalFlag = find_option("global","g",0)!=0;
1354
--- src/db.c
+++ src/db.c
@@ -686,14 +686,27 @@
686 if( lsize%1024!=0 || lsize<4096 ) return 0;
687 db_open_or_attach(zDbName, "localdb");
688 g.localOpen = 1;
689 db_open_config();
690 db_open_repository(0);
691
692 /* If the "mtime" column is missing from the vfile table, then
693 ** add it now. This code added on 2008-12-06. After all users have
694 ** upgraded, this code can be safely deleted.
695 */
696 rc = sqlite3_prepare(g.db, "SELECT mtime FROM vfile", -1, &pStmt, 0);
697 sqlite3_finalize(pStmt);
698 if( rc==SQLITE_ERROR ){
699 sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN mtime INTEGER", 0, 0, 0);
700 }
701
702 /* If the "origname" column is missing from the vfile table, then
703 ** add it now. This code added on 2008-11-09. After all users have
704 ** upgraded, this code can be safely deleted.
705 */
706 rc = sqlite3_prepare(g.db, "SELECT origname FROM vfile", -1, &pStmt, 0);
707 sqlite3_finalize(pStmt);
708 if( rc==SQLITE_ERROR ){
709 sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN origname TEXT", 0, 0, 0);
710 }
711
712 return 1;
@@ -1323,10 +1336,13 @@
1336 ** sign all commits with gpg. When disabled, commits will
1337 ** be unsigned.
1338 **
1339 ** pgp-command Command used to clear-sign manifests at check-in.
1340 ** The default is "gpg --clearsign -o ".
1341 **
1342 ** mtime-changes Use file modification times (mtimes) to detect when
1343 ** files have been modified.
1344 **
1345 ** proxy URL of the HTTP proxy. If undefined or "off" then
1346 ** the "http_proxy" environment variable is consulted.
1347 ** If the http_proxy environment variable is undefined
1348 ** then a direct HTTP connection is used.
@@ -1344,10 +1360,11 @@
1360 "gdiff-command",
1361 "http-port",
1362 "localauth",
1363 "clearsign",
1364 "pgp-command",
1365 "mtime-changes",
1366 "proxy",
1367 "web-browser",
1368 };
1369 int i;
1370 int globalFlag = find_option("global","g",0)!=0;
1371
--- src/schema.c
+++ src/schema.c
@@ -380,10 +380,11 @@
380380
@ vid INTEGER REFERENCES blob, -- The baseline this file is part of.
381381
@ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add
382382
@ deleted BOOLEAN DEFAULT 0, -- True if deleted
383383
@ rid INTEGER, -- Originally from this repository record
384384
@ mrid INTEGER, -- Based on this record due to a merge
385
+@ mtime INTEGER, -- Modification time of file on disk
385386
@ pathname TEXT, -- Full pathname relative to root
386387
@ origname TEXT, -- Original pathname. NULL if unchanged
387388
@ UNIQUE(pathname,vid)
388389
@ );
389390
@
390391
--- src/schema.c
+++ src/schema.c
@@ -380,10 +380,11 @@
380 @ vid INTEGER REFERENCES blob, -- The baseline this file is part of.
381 @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add
382 @ deleted BOOLEAN DEFAULT 0, -- True if deleted
383 @ rid INTEGER, -- Originally from this repository record
384 @ mrid INTEGER, -- Based on this record due to a merge
 
385 @ pathname TEXT, -- Full pathname relative to root
386 @ origname TEXT, -- Original pathname. NULL if unchanged
387 @ UNIQUE(pathname,vid)
388 @ );
389 @
390
--- src/schema.c
+++ src/schema.c
@@ -380,10 +380,11 @@
380 @ vid INTEGER REFERENCES blob, -- The baseline this file is part of.
381 @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add
382 @ deleted BOOLEAN DEFAULT 0, -- True if deleted
383 @ rid INTEGER, -- Originally from this repository record
384 @ mrid INTEGER, -- Based on this record due to a merge
385 @ mtime INTEGER, -- Modification time of file on disk
386 @ pathname TEXT, -- Full pathname relative to root
387 @ origname TEXT, -- Original pathname. NULL if unchanged
388 @ UNIQUE(pathname,vid)
389 @ );
390 @
391
+14 -1
--- src/vfile.c
+++ src/vfile.c
@@ -145,39 +145,49 @@
145145
** the file has changed without having the check the on-disk image.
146146
*/
147147
void vfile_check_signature(int vid){
148148
Stmt q;
149149
Blob fileCksum, origCksum;
150
+ int checkMtime = db_get_boolean("mtime-changes", 0);
150151
151152
db_begin_transaction();
152153
db_prepare(&q, "SELECT id, %Q || pathname,"
153
- " vfile.mrid, deleted, chnged, uuid"
154
+ " vfile.mrid, deleted, chnged, uuid, mtime"
154155
" FROM vfile LEFT JOIN blob ON vfile.mrid=blob.rid"
155156
" WHERE vid=%d ", g.zLocalRoot, vid);
156157
while( db_step(&q)==SQLITE_ROW ){
157158
int id, rid, isDeleted;
158159
const char *zName;
159160
int chnged = 0;
160161
int oldChnged;
162
+ i64 oldMtime;
163
+ i64 currentMtime;
161164
162165
id = db_column_int(&q, 0);
163166
zName = db_column_text(&q, 1);
164167
rid = db_column_int(&q, 2);
165168
isDeleted = db_column_int(&q, 3);
166169
oldChnged = db_column_int(&q, 4);
170
+ oldMtime = db_column_int64(&q, 6);
167171
if( oldChnged>=2 ){
168172
chnged = oldChnged;
169173
}else if( isDeleted || rid==0 ){
170174
chnged = 1;
171175
}
172176
if( chnged!=1 ){
177
+ currentMtime = file_mtime(zName);
178
+ }
179
+ if( chnged!=1 && (checkMtime==0 || currentMtime!=oldMtime) ){
173180
db_ephemeral_blob(&q, 5, &origCksum);
174181
if( sha1sum_file(zName, &fileCksum) ){
175182
blob_zero(&fileCksum);
176183
}
177184
if( blob_compare(&fileCksum, &origCksum) ){
178185
chnged = 1;
186
+ }else if( currentMtime!=oldMtime ){
187
+ db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d",
188
+ currentMtime, id);
179189
}
180190
blob_reset(&origCksum);
181191
blob_reset(&fileCksum);
182192
}
183193
if( chnged!=oldChnged ){
@@ -217,10 +227,12 @@
217227
zName = db_column_text(&q, 1);
218228
rid = db_column_int(&q, 2);
219229
content_get(rid, &content);
220230
if( verbose ) printf("%s\n", &zName[nRepos]);
221231
blob_write_to_file(&content, zName);
232
+ db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d",
233
+ file_mtime(zName), id);
222234
}
223235
db_finalize(&q);
224236
}
225237
226238
@@ -236,10 +248,11 @@
236248
237249
zName = db_column_text(&q, 0);
238250
unlink(zName);
239251
}
240252
db_finalize(&q);
253
+ db_multi_exec("UPDATE vfile SET mtime=NULL HERE vid=%d AND mrid>0", vid);
241254
}
242255
243256
/*
244257
** Load into table SFILE the name of every ordinary file in
245258
** the directory pPath. Omit the first nPrefix characters of
246259
--- src/vfile.c
+++ src/vfile.c
@@ -145,39 +145,49 @@
145 ** the file has changed without having the check the on-disk image.
146 */
147 void vfile_check_signature(int vid){
148 Stmt q;
149 Blob fileCksum, origCksum;
 
150
151 db_begin_transaction();
152 db_prepare(&q, "SELECT id, %Q || pathname,"
153 " vfile.mrid, deleted, chnged, uuid"
154 " FROM vfile LEFT JOIN blob ON vfile.mrid=blob.rid"
155 " WHERE vid=%d ", g.zLocalRoot, vid);
156 while( db_step(&q)==SQLITE_ROW ){
157 int id, rid, isDeleted;
158 const char *zName;
159 int chnged = 0;
160 int oldChnged;
 
 
161
162 id = db_column_int(&q, 0);
163 zName = db_column_text(&q, 1);
164 rid = db_column_int(&q, 2);
165 isDeleted = db_column_int(&q, 3);
166 oldChnged = db_column_int(&q, 4);
 
167 if( oldChnged>=2 ){
168 chnged = oldChnged;
169 }else if( isDeleted || rid==0 ){
170 chnged = 1;
171 }
172 if( chnged!=1 ){
 
 
 
173 db_ephemeral_blob(&q, 5, &origCksum);
174 if( sha1sum_file(zName, &fileCksum) ){
175 blob_zero(&fileCksum);
176 }
177 if( blob_compare(&fileCksum, &origCksum) ){
178 chnged = 1;
 
 
 
179 }
180 blob_reset(&origCksum);
181 blob_reset(&fileCksum);
182 }
183 if( chnged!=oldChnged ){
@@ -217,10 +227,12 @@
217 zName = db_column_text(&q, 1);
218 rid = db_column_int(&q, 2);
219 content_get(rid, &content);
220 if( verbose ) printf("%s\n", &zName[nRepos]);
221 blob_write_to_file(&content, zName);
 
 
222 }
223 db_finalize(&q);
224 }
225
226
@@ -236,10 +248,11 @@
236
237 zName = db_column_text(&q, 0);
238 unlink(zName);
239 }
240 db_finalize(&q);
 
241 }
242
243 /*
244 ** Load into table SFILE the name of every ordinary file in
245 ** the directory pPath. Omit the first nPrefix characters of
246
--- src/vfile.c
+++ src/vfile.c
@@ -145,39 +145,49 @@
145 ** the file has changed without having the check the on-disk image.
146 */
147 void vfile_check_signature(int vid){
148 Stmt q;
149 Blob fileCksum, origCksum;
150 int checkMtime = db_get_boolean("mtime-changes", 0);
151
152 db_begin_transaction();
153 db_prepare(&q, "SELECT id, %Q || pathname,"
154 " vfile.mrid, deleted, chnged, uuid, mtime"
155 " FROM vfile LEFT JOIN blob ON vfile.mrid=blob.rid"
156 " WHERE vid=%d ", g.zLocalRoot, vid);
157 while( db_step(&q)==SQLITE_ROW ){
158 int id, rid, isDeleted;
159 const char *zName;
160 int chnged = 0;
161 int oldChnged;
162 i64 oldMtime;
163 i64 currentMtime;
164
165 id = db_column_int(&q, 0);
166 zName = db_column_text(&q, 1);
167 rid = db_column_int(&q, 2);
168 isDeleted = db_column_int(&q, 3);
169 oldChnged = db_column_int(&q, 4);
170 oldMtime = db_column_int64(&q, 6);
171 if( oldChnged>=2 ){
172 chnged = oldChnged;
173 }else if( isDeleted || rid==0 ){
174 chnged = 1;
175 }
176 if( chnged!=1 ){
177 currentMtime = file_mtime(zName);
178 }
179 if( chnged!=1 && (checkMtime==0 || currentMtime!=oldMtime) ){
180 db_ephemeral_blob(&q, 5, &origCksum);
181 if( sha1sum_file(zName, &fileCksum) ){
182 blob_zero(&fileCksum);
183 }
184 if( blob_compare(&fileCksum, &origCksum) ){
185 chnged = 1;
186 }else if( currentMtime!=oldMtime ){
187 db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d",
188 currentMtime, id);
189 }
190 blob_reset(&origCksum);
191 blob_reset(&fileCksum);
192 }
193 if( chnged!=oldChnged ){
@@ -217,10 +227,12 @@
227 zName = db_column_text(&q, 1);
228 rid = db_column_int(&q, 2);
229 content_get(rid, &content);
230 if( verbose ) printf("%s\n", &zName[nRepos]);
231 blob_write_to_file(&content, zName);
232 db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d",
233 file_mtime(zName), id);
234 }
235 db_finalize(&q);
236 }
237
238
@@ -236,10 +248,11 @@
248
249 zName = db_column_text(&q, 0);
250 unlink(zName);
251 }
252 db_finalize(&q);
253 db_multi_exec("UPDATE vfile SET mtime=NULL HERE vid=%d AND mrid>0", vid);
254 }
255
256 /*
257 ** Load into table SFILE the name of every ordinary file in
258 ** the directory pPath. Omit the first nPrefix characters of
259

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button