Fossil SCM

Track file permission changes in the mlink table. Updating through this check-in requires a rebuild.

drh 2011-02-25 16:20 trunk
Commit 7f11789bf1522a21183dff8f4802bb2b3dc287a1
3 files changed +22 -11 +62 -15 +3 -2
+22 -11
--- src/info.c
+++ src/info.c
@@ -280,17 +280,20 @@
280280
*/
281281
static void append_file_change_line(
282282
const char *zName, /* Name of the file that has changed */
283283
const char *zOld, /* blob.uuid before change. NULL for added files */
284284
const char *zNew, /* blob.uuid after change. NULL for deletes */
285
- int showDiff /* Show edit diffs if true */
285
+ int showDiff, /* Show edit diffs if true */
286
+ int mperm /* EXE permission for zNew */
286287
){
287288
if( !g.okHistory ){
288289
if( zNew==0 ){
289290
@ <p>Deleted %h(zName)</p>
290291
}else if( zOld==0 ){
291292
@ <p>Added %h(zName)</p>
293
+ }else if( fossil_strcmp(zNew, zOld)==0 ){
294
+ @ <p>Execute permission %s(mperm?"set":"cleared") for %h(zName)
292295
}else{
293296
@ <p>Changes to %h(zName)</p>
294297
}
295298
if( showDiff ){
296299
@ <blockquote><pre>
@@ -297,13 +300,18 @@
297300
append_diff(zOld, zNew);
298301
@ </pre></blockquote>
299302
}
300303
}else{
301304
if( zOld && zNew ){
302
- @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
303
- @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a>
304
- @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a>
305
+ if( fossil_strcmp(zOld, zNew)!=0 ){
306
+ @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
307
+ @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a>
308
+ @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a>
309
+ }else{
310
+ @ <p>Execute permission %s(mperm?"set":"cleared") for
311
+ @ <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
312
+ }
305313
}else if( zOld ){
306314
@ <p>Deleted <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
307315
@ version <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a>
308316
}else{
309317
@ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
@@ -499,23 +507,24 @@
499507
}
500508
}
501509
@ &nbsp;&nbsp;
502510
@ <a href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">[patch]</a><br/>
503511
db_prepare(&q,
504
- "SELECT name,"
512
+ "SELECT name, mperm,"
505513
" (SELECT uuid FROM blob WHERE rid=mlink.pid),"
506514
" (SELECT uuid FROM blob WHERE rid=mlink.fid)"
507515
" FROM mlink JOIN filename ON filename.fnid=mlink.fnid"
508516
" WHERE mlink.mid=%d"
509517
" ORDER BY name",
510518
rid
511519
);
512520
while( db_step(&q)==SQLITE_ROW ){
513521
const char *zName = db_column_text(&q,0);
514
- const char *zOld = db_column_text(&q,1);
515
- const char *zNew = db_column_text(&q,2);
516
- append_file_change_line(zName, zOld, zNew, showDiff);
522
+ int mperm = db_column_int(&q, 1);
523
+ const char *zOld = db_column_text(&q,2);
524
+ const char *zNew = db_column_text(&q,3);
525
+ append_file_change_line(zName, zOld, zNew, showDiff, mperm);
517526
}
518527
db_finalize(&q);
519528
}
520529
style_footer();
521530
}
@@ -702,24 +711,26 @@
702711
}else{
703712
cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName);
704713
}
705714
if( cmp<0 ){
706715
append_file_change_line(pFileFrom->zName,
707
- pFileFrom->zUuid, 0, 0);
716
+ pFileFrom->zUuid, 0, 0, 0);
708717
pFileFrom = manifest_file_next(pFrom, 0);
709718
}else if( cmp>0 ){
710719
append_file_change_line(pFileTo->zName,
711
- 0, pFileTo->zUuid, 0);
720
+ 0, pFileTo->zUuid, 0,
721
+ manifest_file_mperm(pFileTo));
712722
pFileTo = manifest_file_next(pTo, 0);
713723
}else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){
714724
/* No changes */
715725
pFileFrom = manifest_file_next(pFrom, 0);
716726
pFileTo = manifest_file_next(pTo, 0);
717727
}else{
718728
append_file_change_line(pFileFrom->zName,
719729
pFileFrom->zUuid,
720
- pFileTo->zUuid, showDetail);
730
+ pFileTo->zUuid, showDetail,
731
+ manifest_file_mperm(pFileTo));
721732
pFileFrom = manifest_file_next(pFrom, 0);
722733
pFileTo = manifest_file_next(pTo, 0);
723734
}
724735
}
725736
manifest_destroy(pFrom);
726737
--- src/info.c
+++ src/info.c
@@ -280,17 +280,20 @@
280 */
281 static void append_file_change_line(
282 const char *zName, /* Name of the file that has changed */
283 const char *zOld, /* blob.uuid before change. NULL for added files */
284 const char *zNew, /* blob.uuid after change. NULL for deletes */
285 int showDiff /* Show edit diffs if true */
 
286 ){
287 if( !g.okHistory ){
288 if( zNew==0 ){
289 @ <p>Deleted %h(zName)</p>
290 }else if( zOld==0 ){
291 @ <p>Added %h(zName)</p>
 
 
292 }else{
293 @ <p>Changes to %h(zName)</p>
294 }
295 if( showDiff ){
296 @ <blockquote><pre>
@@ -297,13 +300,18 @@
297 append_diff(zOld, zNew);
298 @ </pre></blockquote>
299 }
300 }else{
301 if( zOld && zNew ){
302 @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
303 @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a>
304 @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a>
 
 
 
 
 
305 }else if( zOld ){
306 @ <p>Deleted <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
307 @ version <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a>
308 }else{
309 @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
@@ -499,23 +507,24 @@
499 }
500 }
501 @ &nbsp;&nbsp;
502 @ <a href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">[patch]</a><br/>
503 db_prepare(&q,
504 "SELECT name,"
505 " (SELECT uuid FROM blob WHERE rid=mlink.pid),"
506 " (SELECT uuid FROM blob WHERE rid=mlink.fid)"
507 " FROM mlink JOIN filename ON filename.fnid=mlink.fnid"
508 " WHERE mlink.mid=%d"
509 " ORDER BY name",
510 rid
511 );
512 while( db_step(&q)==SQLITE_ROW ){
513 const char *zName = db_column_text(&q,0);
514 const char *zOld = db_column_text(&q,1);
515 const char *zNew = db_column_text(&q,2);
516 append_file_change_line(zName, zOld, zNew, showDiff);
 
517 }
518 db_finalize(&q);
519 }
520 style_footer();
521 }
@@ -702,24 +711,26 @@
702 }else{
703 cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName);
704 }
705 if( cmp<0 ){
706 append_file_change_line(pFileFrom->zName,
707 pFileFrom->zUuid, 0, 0);
708 pFileFrom = manifest_file_next(pFrom, 0);
709 }else if( cmp>0 ){
710 append_file_change_line(pFileTo->zName,
711 0, pFileTo->zUuid, 0);
 
712 pFileTo = manifest_file_next(pTo, 0);
713 }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){
714 /* No changes */
715 pFileFrom = manifest_file_next(pFrom, 0);
716 pFileTo = manifest_file_next(pTo, 0);
717 }else{
718 append_file_change_line(pFileFrom->zName,
719 pFileFrom->zUuid,
720 pFileTo->zUuid, showDetail);
 
721 pFileFrom = manifest_file_next(pFrom, 0);
722 pFileTo = manifest_file_next(pTo, 0);
723 }
724 }
725 manifest_destroy(pFrom);
726
--- src/info.c
+++ src/info.c
@@ -280,17 +280,20 @@
280 */
281 static void append_file_change_line(
282 const char *zName, /* Name of the file that has changed */
283 const char *zOld, /* blob.uuid before change. NULL for added files */
284 const char *zNew, /* blob.uuid after change. NULL for deletes */
285 int showDiff, /* Show edit diffs if true */
286 int mperm /* EXE permission for zNew */
287 ){
288 if( !g.okHistory ){
289 if( zNew==0 ){
290 @ <p>Deleted %h(zName)</p>
291 }else if( zOld==0 ){
292 @ <p>Added %h(zName)</p>
293 }else if( fossil_strcmp(zNew, zOld)==0 ){
294 @ <p>Execute permission %s(mperm?"set":"cleared") for %h(zName)
295 }else{
296 @ <p>Changes to %h(zName)</p>
297 }
298 if( showDiff ){
299 @ <blockquote><pre>
@@ -297,13 +300,18 @@
300 append_diff(zOld, zNew);
301 @ </pre></blockquote>
302 }
303 }else{
304 if( zOld && zNew ){
305 if( fossil_strcmp(zOld, zNew)!=0 ){
306 @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
307 @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a>
308 @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a>
309 }else{
310 @ <p>Execute permission %s(mperm?"set":"cleared") for
311 @ <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
312 }
313 }else if( zOld ){
314 @ <p>Deleted <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
315 @ version <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a>
316 }else{
317 @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
@@ -499,23 +507,24 @@
507 }
508 }
509 @ &nbsp;&nbsp;
510 @ <a href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">[patch]</a><br/>
511 db_prepare(&q,
512 "SELECT name, mperm,"
513 " (SELECT uuid FROM blob WHERE rid=mlink.pid),"
514 " (SELECT uuid FROM blob WHERE rid=mlink.fid)"
515 " FROM mlink JOIN filename ON filename.fnid=mlink.fnid"
516 " WHERE mlink.mid=%d"
517 " ORDER BY name",
518 rid
519 );
520 while( db_step(&q)==SQLITE_ROW ){
521 const char *zName = db_column_text(&q,0);
522 int mperm = db_column_int(&q, 1);
523 const char *zOld = db_column_text(&q,2);
524 const char *zNew = db_column_text(&q,3);
525 append_file_change_line(zName, zOld, zNew, showDiff, mperm);
526 }
527 db_finalize(&q);
528 }
529 style_footer();
530 }
@@ -702,24 +711,26 @@
711 }else{
712 cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName);
713 }
714 if( cmp<0 ){
715 append_file_change_line(pFileFrom->zName,
716 pFileFrom->zUuid, 0, 0, 0);
717 pFileFrom = manifest_file_next(pFrom, 0);
718 }else if( cmp>0 ){
719 append_file_change_line(pFileTo->zName,
720 0, pFileTo->zUuid, 0,
721 manifest_file_mperm(pFileTo));
722 pFileTo = manifest_file_next(pTo, 0);
723 }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){
724 /* No changes */
725 pFileFrom = manifest_file_next(pFrom, 0);
726 pFileTo = manifest_file_next(pTo, 0);
727 }else{
728 append_file_change_line(pFileFrom->zName,
729 pFileFrom->zUuid,
730 pFileTo->zUuid, showDetail,
731 manifest_file_mperm(pFileTo));
732 pFileFrom = manifest_file_next(pFrom, 0);
733 pFileTo = manifest_file_next(pTo, 0);
734 }
735 }
736 manifest_destroy(pFrom);
737
+62 -15
--- src/manifest.c
+++ src/manifest.c
@@ -1049,10 +1049,22 @@
10491049
db_exec(&s1);
10501050
fnid = db_last_insert_rowid();
10511051
}
10521052
return fnid;
10531053
}
1054
+
1055
+/*
1056
+** Compute an appropriate mlink.mperm integer for the permission string
1057
+** of a file.
1058
+*/
1059
+int manifest_file_mperm(ManifestFile *pFile){
1060
+ int mperm = 0;
1061
+ if( pFile && pFile->zPerm && strstr(pFile->zPerm,"x")!=0 ){
1062
+ mperm = 1;
1063
+ }
1064
+ return mperm;
1065
+}
10541066
10551067
/*
10561068
** Add a single entry to the mlink table. Also add the filename to
10571069
** the filename table if it is not there already.
10581070
*/
@@ -1059,11 +1071,12 @@
10591071
static void add_one_mlink(
10601072
int mid, /* The record ID of the manifest */
10611073
const char *zFromUuid, /* UUID for the mlink.pid. "" to add file */
10621074
const char *zToUuid, /* UUID for the mlink.fid. "" to delele */
10631075
const char *zFilename, /* Filename */
1064
- const char *zPrior /* Previous filename. NULL if unchanged */
1076
+ const char *zPrior, /* Previous filename. NULL if unchanged */
1077
+ int mperm /* 1: exec */
10651078
){
10661079
int fnid, pfnid, pid, fid;
10671080
static Stmt s1;
10681081
10691082
fnid = filename_to_fnid(zFilename);
@@ -1081,18 +1094,19 @@
10811094
fid = 0;
10821095
}else{
10831096
fid = uuid_to_rid(zToUuid, 1);
10841097
}
10851098
db_static_prepare(&s1,
1086
- "INSERT INTO mlink(mid,pid,fid,fnid,pfnid)"
1087
- "VALUES(:m,:p,:f,:n,:pfn)"
1099
+ "INSERT INTO mlink(mid,pid,fid,fnid,pfnid,mperm)"
1100
+ "VALUES(:m,:p,:f,:n,:pfn,:mp)"
10881101
);
10891102
db_bind_int(&s1, ":m", mid);
10901103
db_bind_int(&s1, ":p", pid);
10911104
db_bind_int(&s1, ":f", fid);
10921105
db_bind_int(&s1, ":n", fnid);
10931106
db_bind_int(&s1, ":pfn", pfnid);
1107
+ db_bind_int(&s1, ":mp", mperm);
10941108
db_exec(&s1);
10951109
if( pid && fid ){
10961110
content_deltify(pid, fid, 0);
10971111
}
10981112
}
@@ -1158,15 +1172,16 @@
11581172
}
11591173
return pFile;
11601174
}
11611175
11621176
/*
1163
-** Add mlink table entries associated with manifest cid. The
1164
-** parent manifest is pid.
1177
+** Add mlink table entries associated with manifest cid, pChild. The
1178
+** parent manifest is pid, pParent. One of either pChild or pParent
1179
+** will be NULL and it will be computed based on cid/pid.
11651180
**
1166
-** A single mlink entry is added for every file that changed content
1167
-** and/or name going from pid to cid.
1181
+** A single mlink entry is added for every file that changed content,
1182
+** name, and/or permissions going from pid to cid.
11681183
**
11691184
** Deleted files have mlink.fid=0.
11701185
** Added files have mlink.pid=0.
11711186
** Edited files have both mlink.pid!=0 and mlink.fid!=0
11721187
*/
@@ -1176,16 +1191,22 @@
11761191
int i, rc;
11771192
ManifestFile *pChildFile, *pParentFile;
11781193
Manifest **ppOther;
11791194
static Stmt eq;
11801195
1196
+ /* If mlink table entires are already set for cid, then abort early
1197
+ ** doing no work.
1198
+ */
11811199
db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid");
11821200
db_bind_int(&eq, ":mid", cid);
11831201
rc = db_step(&eq);
11841202
db_reset(&eq);
11851203
if( rc==SQLITE_ROW ) return;
11861204
1205
+ /* Compute the value of the missing pParent or pChild parameter.
1206
+ ** Fetch the baseline checkins for both.
1207
+ */
11871208
assert( pParent==0 || pChild==0 );
11881209
if( pParent==0 ){
11891210
ppOther = &pParent;
11901211
otherRid = pid;
11911212
}else{
@@ -1200,10 +1221,14 @@
12001221
}
12011222
if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){
12021223
manifest_destroy(*ppOther);
12031224
return;
12041225
}
1226
+
1227
+ /* Try to make the parent manifest a delta from the child, if that
1228
+ ** is an appropriate thing to do.
1229
+ */
12051230
if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){
12061231
content_deltify(pid, cid, 0);
12071232
}else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){
12081233
content_deltify(pParent->pBaseline->rid, cid, 0);
12091234
}
@@ -1217,44 +1242,63 @@
12171242
db_multi_exec(
12181243
"INSERT OR REPLACE INTO time_fudge VALUES(%d, %.17g, %d, %.17g);",
12191244
pParent->rid, pParent->rDate, pChild->rid, pChild->rDate
12201245
);
12211246
}
1222
-
1247
+
1248
+ /* First look at all files in pChild, ignoring its baseline. This
1249
+ ** is where most of the changes will be found.
1250
+ */
12231251
for(i=0, pChildFile=pChild->aFile; i<pChild->nFile; i++, pChildFile++){
1252
+ int mperm = manifest_file_mperm(pChildFile);
12241253
if( pChildFile->zPrior ){
12251254
pParentFile = manifest_file_seek(pParent, pChildFile->zPrior);
12261255
if( pParentFile ){
1256
+ /* File with name change */
12271257
add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid,
1228
- pChildFile->zName, pChildFile->zPrior);
1258
+ pChildFile->zName, pChildFile->zPrior, mperm);
1259
+ }else{
1260
+ /* File name changed, but the old name is not found in the parent!
1261
+ ** Treat this like a new file. */
1262
+ add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, mperm);
12291263
}
12301264
}else{
12311265
pParentFile = manifest_file_seek(pParent, pChildFile->zName);
12321266
if( pParentFile==0 ){
12331267
if( pChildFile->zUuid ){
1234
- add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0);
1268
+ /* A new file */
1269
+ add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName,0,mperm);
12351270
}
1236
- }else if( fossil_strcmp(pChildFile->zUuid, pParentFile->zUuid)!=0 ){
1271
+ }else if( fossil_strcmp(pChildFile->zUuid, pParentFile->zUuid)!=0
1272
+ || manifest_file_mperm(pParentFile)!=mperm ){
1273
+ /* Changes in file content or permissions */
12371274
add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid,
1238
- pChildFile->zName, 0);
1275
+ pChildFile->zName, 0, mperm);
12391276
}
12401277
}
12411278
}
12421279
if( pParent->zBaseline && pChild->zBaseline ){
1280
+ /* Both parent and child are delta manifests. Look for files that
1281
+ ** are marked as deleted in the parent but which reappear in the child
1282
+ ** and show such files as being added in the child. */
12431283
for(i=0, pParentFile=pParent->aFile; i<pParent->nFile; i++, pParentFile++){
12441284
if( pParentFile->zUuid ) continue;
12451285
pChildFile = manifest_file_seek(pChild, pParentFile->zName);
12461286
if( pChildFile ){
1247
- add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0);
1287
+ add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0,
1288
+ manifest_file_mperm(pChildFile));
12481289
}
12491290
}
12501291
}else if( pChild->zBaseline==0 ){
1292
+ /* Parent is a delta but pChild is a baseline. Look for files that are
1293
+ ** present in pParent but which are missing from pChild and mark them
1294
+ ** has having been deleted. */
12511295
manifest_file_rewind(pParent);
12521296
while( (pParentFile = manifest_file_next(pParent,0))!=0 ){
12531297
pChildFile = manifest_file_seek(pChild, pParentFile->zName);
12541298
if( pChildFile==0 ){
1255
- add_one_mlink(cid, pParentFile->zUuid, 0, pParentFile->zName, 0);
1299
+ add_one_mlink(cid, pParentFile->zUuid, 0, pParentFile->zName, 0, 0);
12561300
}
12571301
}
12581302
}
12591303
manifest_cache_insert(*ppOther);
12601304
}
@@ -1483,12 +1527,15 @@
14831527
int cid = db_column_int(&q, 0);
14841528
add_mlink(rid, p, cid, 0);
14851529
}
14861530
db_finalize(&q);
14871531
if( p->nParent==0 ){
1532
+ /* For root files (files without parents) add mlink entries
1533
+ ** showing all content as new. */
14881534
for(i=0; i<p->nFile; i++){
1489
- add_one_mlink(rid, 0, p->aFile[i].zUuid, p->aFile[i].zName, 0);
1535
+ add_one_mlink(rid, 0, p->aFile[i].zUuid, p->aFile[i].zName, 0,
1536
+ manifest_file_mperm(&p->aFile[i]));
14901537
}
14911538
}
14921539
db_multi_exec(
14931540
"REPLACE INTO event(type,mtime,objid,user,comment,"
14941541
"bgcolor,euser,ecomment,omtime)"
14951542
--- src/manifest.c
+++ src/manifest.c
@@ -1049,10 +1049,22 @@
1049 db_exec(&s1);
1050 fnid = db_last_insert_rowid();
1051 }
1052 return fnid;
1053 }
 
 
 
 
 
 
 
 
 
 
 
 
1054
1055 /*
1056 ** Add a single entry to the mlink table. Also add the filename to
1057 ** the filename table if it is not there already.
1058 */
@@ -1059,11 +1071,12 @@
1059 static void add_one_mlink(
1060 int mid, /* The record ID of the manifest */
1061 const char *zFromUuid, /* UUID for the mlink.pid. "" to add file */
1062 const char *zToUuid, /* UUID for the mlink.fid. "" to delele */
1063 const char *zFilename, /* Filename */
1064 const char *zPrior /* Previous filename. NULL if unchanged */
 
1065 ){
1066 int fnid, pfnid, pid, fid;
1067 static Stmt s1;
1068
1069 fnid = filename_to_fnid(zFilename);
@@ -1081,18 +1094,19 @@
1081 fid = 0;
1082 }else{
1083 fid = uuid_to_rid(zToUuid, 1);
1084 }
1085 db_static_prepare(&s1,
1086 "INSERT INTO mlink(mid,pid,fid,fnid,pfnid)"
1087 "VALUES(:m,:p,:f,:n,:pfn)"
1088 );
1089 db_bind_int(&s1, ":m", mid);
1090 db_bind_int(&s1, ":p", pid);
1091 db_bind_int(&s1, ":f", fid);
1092 db_bind_int(&s1, ":n", fnid);
1093 db_bind_int(&s1, ":pfn", pfnid);
 
1094 db_exec(&s1);
1095 if( pid && fid ){
1096 content_deltify(pid, fid, 0);
1097 }
1098 }
@@ -1158,15 +1172,16 @@
1158 }
1159 return pFile;
1160 }
1161
1162 /*
1163 ** Add mlink table entries associated with manifest cid. The
1164 ** parent manifest is pid.
 
1165 **
1166 ** A single mlink entry is added for every file that changed content
1167 ** and/or name going from pid to cid.
1168 **
1169 ** Deleted files have mlink.fid=0.
1170 ** Added files have mlink.pid=0.
1171 ** Edited files have both mlink.pid!=0 and mlink.fid!=0
1172 */
@@ -1176,16 +1191,22 @@
1176 int i, rc;
1177 ManifestFile *pChildFile, *pParentFile;
1178 Manifest **ppOther;
1179 static Stmt eq;
1180
 
 
 
1181 db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid");
1182 db_bind_int(&eq, ":mid", cid);
1183 rc = db_step(&eq);
1184 db_reset(&eq);
1185 if( rc==SQLITE_ROW ) return;
1186
 
 
 
1187 assert( pParent==0 || pChild==0 );
1188 if( pParent==0 ){
1189 ppOther = &pParent;
1190 otherRid = pid;
1191 }else{
@@ -1200,10 +1221,14 @@
1200 }
1201 if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){
1202 manifest_destroy(*ppOther);
1203 return;
1204 }
 
 
 
 
1205 if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){
1206 content_deltify(pid, cid, 0);
1207 }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){
1208 content_deltify(pParent->pBaseline->rid, cid, 0);
1209 }
@@ -1217,44 +1242,63 @@
1217 db_multi_exec(
1218 "INSERT OR REPLACE INTO time_fudge VALUES(%d, %.17g, %d, %.17g);",
1219 pParent->rid, pParent->rDate, pChild->rid, pChild->rDate
1220 );
1221 }
1222
 
 
 
1223 for(i=0, pChildFile=pChild->aFile; i<pChild->nFile; i++, pChildFile++){
 
1224 if( pChildFile->zPrior ){
1225 pParentFile = manifest_file_seek(pParent, pChildFile->zPrior);
1226 if( pParentFile ){
 
1227 add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid,
1228 pChildFile->zName, pChildFile->zPrior);
 
 
 
 
1229 }
1230 }else{
1231 pParentFile = manifest_file_seek(pParent, pChildFile->zName);
1232 if( pParentFile==0 ){
1233 if( pChildFile->zUuid ){
1234 add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0);
 
1235 }
1236 }else if( fossil_strcmp(pChildFile->zUuid, pParentFile->zUuid)!=0 ){
 
 
1237 add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid,
1238 pChildFile->zName, 0);
1239 }
1240 }
1241 }
1242 if( pParent->zBaseline && pChild->zBaseline ){
 
 
 
1243 for(i=0, pParentFile=pParent->aFile; i<pParent->nFile; i++, pParentFile++){
1244 if( pParentFile->zUuid ) continue;
1245 pChildFile = manifest_file_seek(pChild, pParentFile->zName);
1246 if( pChildFile ){
1247 add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0);
 
1248 }
1249 }
1250 }else if( pChild->zBaseline==0 ){
 
 
 
1251 manifest_file_rewind(pParent);
1252 while( (pParentFile = manifest_file_next(pParent,0))!=0 ){
1253 pChildFile = manifest_file_seek(pChild, pParentFile->zName);
1254 if( pChildFile==0 ){
1255 add_one_mlink(cid, pParentFile->zUuid, 0, pParentFile->zName, 0);
1256 }
1257 }
1258 }
1259 manifest_cache_insert(*ppOther);
1260 }
@@ -1483,12 +1527,15 @@
1483 int cid = db_column_int(&q, 0);
1484 add_mlink(rid, p, cid, 0);
1485 }
1486 db_finalize(&q);
1487 if( p->nParent==0 ){
 
 
1488 for(i=0; i<p->nFile; i++){
1489 add_one_mlink(rid, 0, p->aFile[i].zUuid, p->aFile[i].zName, 0);
 
1490 }
1491 }
1492 db_multi_exec(
1493 "REPLACE INTO event(type,mtime,objid,user,comment,"
1494 "bgcolor,euser,ecomment,omtime)"
1495
--- src/manifest.c
+++ src/manifest.c
@@ -1049,10 +1049,22 @@
1049 db_exec(&s1);
1050 fnid = db_last_insert_rowid();
1051 }
1052 return fnid;
1053 }
1054
1055 /*
1056 ** Compute an appropriate mlink.mperm integer for the permission string
1057 ** of a file.
1058 */
1059 int manifest_file_mperm(ManifestFile *pFile){
1060 int mperm = 0;
1061 if( pFile && pFile->zPerm && strstr(pFile->zPerm,"x")!=0 ){
1062 mperm = 1;
1063 }
1064 return mperm;
1065 }
1066
1067 /*
1068 ** Add a single entry to the mlink table. Also add the filename to
1069 ** the filename table if it is not there already.
1070 */
@@ -1059,11 +1071,12 @@
1071 static void add_one_mlink(
1072 int mid, /* The record ID of the manifest */
1073 const char *zFromUuid, /* UUID for the mlink.pid. "" to add file */
1074 const char *zToUuid, /* UUID for the mlink.fid. "" to delele */
1075 const char *zFilename, /* Filename */
1076 const char *zPrior, /* Previous filename. NULL if unchanged */
1077 int mperm /* 1: exec */
1078 ){
1079 int fnid, pfnid, pid, fid;
1080 static Stmt s1;
1081
1082 fnid = filename_to_fnid(zFilename);
@@ -1081,18 +1094,19 @@
1094 fid = 0;
1095 }else{
1096 fid = uuid_to_rid(zToUuid, 1);
1097 }
1098 db_static_prepare(&s1,
1099 "INSERT INTO mlink(mid,pid,fid,fnid,pfnid,mperm)"
1100 "VALUES(:m,:p,:f,:n,:pfn,:mp)"
1101 );
1102 db_bind_int(&s1, ":m", mid);
1103 db_bind_int(&s1, ":p", pid);
1104 db_bind_int(&s1, ":f", fid);
1105 db_bind_int(&s1, ":n", fnid);
1106 db_bind_int(&s1, ":pfn", pfnid);
1107 db_bind_int(&s1, ":mp", mperm);
1108 db_exec(&s1);
1109 if( pid && fid ){
1110 content_deltify(pid, fid, 0);
1111 }
1112 }
@@ -1158,15 +1172,16 @@
1172 }
1173 return pFile;
1174 }
1175
1176 /*
1177 ** Add mlink table entries associated with manifest cid, pChild. The
1178 ** parent manifest is pid, pParent. One of either pChild or pParent
1179 ** will be NULL and it will be computed based on cid/pid.
1180 **
1181 ** A single mlink entry is added for every file that changed content,
1182 ** name, and/or permissions going from pid to cid.
1183 **
1184 ** Deleted files have mlink.fid=0.
1185 ** Added files have mlink.pid=0.
1186 ** Edited files have both mlink.pid!=0 and mlink.fid!=0
1187 */
@@ -1176,16 +1191,22 @@
1191 int i, rc;
1192 ManifestFile *pChildFile, *pParentFile;
1193 Manifest **ppOther;
1194 static Stmt eq;
1195
1196 /* If mlink table entires are already set for cid, then abort early
1197 ** doing no work.
1198 */
1199 db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid");
1200 db_bind_int(&eq, ":mid", cid);
1201 rc = db_step(&eq);
1202 db_reset(&eq);
1203 if( rc==SQLITE_ROW ) return;
1204
1205 /* Compute the value of the missing pParent or pChild parameter.
1206 ** Fetch the baseline checkins for both.
1207 */
1208 assert( pParent==0 || pChild==0 );
1209 if( pParent==0 ){
1210 ppOther = &pParent;
1211 otherRid = pid;
1212 }else{
@@ -1200,10 +1221,14 @@
1221 }
1222 if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){
1223 manifest_destroy(*ppOther);
1224 return;
1225 }
1226
1227 /* Try to make the parent manifest a delta from the child, if that
1228 ** is an appropriate thing to do.
1229 */
1230 if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){
1231 content_deltify(pid, cid, 0);
1232 }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){
1233 content_deltify(pParent->pBaseline->rid, cid, 0);
1234 }
@@ -1217,44 +1242,63 @@
1242 db_multi_exec(
1243 "INSERT OR REPLACE INTO time_fudge VALUES(%d, %.17g, %d, %.17g);",
1244 pParent->rid, pParent->rDate, pChild->rid, pChild->rDate
1245 );
1246 }
1247
1248 /* First look at all files in pChild, ignoring its baseline. This
1249 ** is where most of the changes will be found.
1250 */
1251 for(i=0, pChildFile=pChild->aFile; i<pChild->nFile; i++, pChildFile++){
1252 int mperm = manifest_file_mperm(pChildFile);
1253 if( pChildFile->zPrior ){
1254 pParentFile = manifest_file_seek(pParent, pChildFile->zPrior);
1255 if( pParentFile ){
1256 /* File with name change */
1257 add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid,
1258 pChildFile->zName, pChildFile->zPrior, mperm);
1259 }else{
1260 /* File name changed, but the old name is not found in the parent!
1261 ** Treat this like a new file. */
1262 add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, mperm);
1263 }
1264 }else{
1265 pParentFile = manifest_file_seek(pParent, pChildFile->zName);
1266 if( pParentFile==0 ){
1267 if( pChildFile->zUuid ){
1268 /* A new file */
1269 add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName,0,mperm);
1270 }
1271 }else if( fossil_strcmp(pChildFile->zUuid, pParentFile->zUuid)!=0
1272 || manifest_file_mperm(pParentFile)!=mperm ){
1273 /* Changes in file content or permissions */
1274 add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid,
1275 pChildFile->zName, 0, mperm);
1276 }
1277 }
1278 }
1279 if( pParent->zBaseline && pChild->zBaseline ){
1280 /* Both parent and child are delta manifests. Look for files that
1281 ** are marked as deleted in the parent but which reappear in the child
1282 ** and show such files as being added in the child. */
1283 for(i=0, pParentFile=pParent->aFile; i<pParent->nFile; i++, pParentFile++){
1284 if( pParentFile->zUuid ) continue;
1285 pChildFile = manifest_file_seek(pChild, pParentFile->zName);
1286 if( pChildFile ){
1287 add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0,
1288 manifest_file_mperm(pChildFile));
1289 }
1290 }
1291 }else if( pChild->zBaseline==0 ){
1292 /* Parent is a delta but pChild is a baseline. Look for files that are
1293 ** present in pParent but which are missing from pChild and mark them
1294 ** has having been deleted. */
1295 manifest_file_rewind(pParent);
1296 while( (pParentFile = manifest_file_next(pParent,0))!=0 ){
1297 pChildFile = manifest_file_seek(pChild, pParentFile->zName);
1298 if( pChildFile==0 ){
1299 add_one_mlink(cid, pParentFile->zUuid, 0, pParentFile->zName, 0, 0);
1300 }
1301 }
1302 }
1303 manifest_cache_insert(*ppOther);
1304 }
@@ -1483,12 +1527,15 @@
1527 int cid = db_column_int(&q, 0);
1528 add_mlink(rid, p, cid, 0);
1529 }
1530 db_finalize(&q);
1531 if( p->nParent==0 ){
1532 /* For root files (files without parents) add mlink entries
1533 ** showing all content as new. */
1534 for(i=0; i<p->nFile; i++){
1535 add_one_mlink(rid, 0, p->aFile[i].zUuid, p->aFile[i].zName, 0,
1536 manifest_file_mperm(&p->aFile[i]));
1537 }
1538 }
1539 db_multi_exec(
1540 "REPLACE INTO event(type,mtime,objid,user,comment,"
1541 "bgcolor,euser,ecomment,omtime)"
1542
+3 -2
--- src/schema.c
+++ src/schema.c
@@ -40,11 +40,11 @@
4040
** a date) which can change frequently. When the content schema changes,
4141
** we have to execute special procedures to update the schema. When
4242
** the aux schema changes, all we need to do is rebuild the database.
4343
*/
4444
#define CONTENT_SCHEMA "1"
45
-#define AUX_SCHEMA "2011-02-25"
45
+#define AUX_SCHEMA "2011-02-25 14:52"
4646
4747
#endif /* INTERFACE */
4848
4949
5050
/*
@@ -200,11 +200,12 @@
200200
@ CREATE TABLE mlink(
201201
@ mid INTEGER REFERENCES blob, -- Manifest ID where change occurs
202202
@ pid INTEGER REFERENCES blob, -- File ID in parent manifest
203203
@ fid INTEGER REFERENCES blob, -- Changed file ID in this manifest
204204
@ fnid INTEGER REFERENCES filename, -- Name of the file
205
-@ pfnid INTEGER REFERENCES filename -- Previous name. 0 if unchanged
205
+@ pfnid INTEGER REFERENCES filename, -- Previous name. 0 if unchanged
206
+@ mperm INTEGER -- File permissions. 1==exec
206207
@ );
207208
@ CREATE INDEX mlink_i1 ON mlink(mid);
208209
@ CREATE INDEX mlink_i2 ON mlink(fnid);
209210
@ CREATE INDEX mlink_i3 ON mlink(fid);
210211
@ CREATE INDEX mlink_i4 ON mlink(pid);
211212
--- src/schema.c
+++ src/schema.c
@@ -40,11 +40,11 @@
40 ** a date) which can change frequently. When the content schema changes,
41 ** we have to execute special procedures to update the schema. When
42 ** the aux schema changes, all we need to do is rebuild the database.
43 */
44 #define CONTENT_SCHEMA "1"
45 #define AUX_SCHEMA "2011-02-25"
46
47 #endif /* INTERFACE */
48
49
50 /*
@@ -200,11 +200,12 @@
200 @ CREATE TABLE mlink(
201 @ mid INTEGER REFERENCES blob, -- Manifest ID where change occurs
202 @ pid INTEGER REFERENCES blob, -- File ID in parent manifest
203 @ fid INTEGER REFERENCES blob, -- Changed file ID in this manifest
204 @ fnid INTEGER REFERENCES filename, -- Name of the file
205 @ pfnid INTEGER REFERENCES filename -- Previous name. 0 if unchanged
 
206 @ );
207 @ CREATE INDEX mlink_i1 ON mlink(mid);
208 @ CREATE INDEX mlink_i2 ON mlink(fnid);
209 @ CREATE INDEX mlink_i3 ON mlink(fid);
210 @ CREATE INDEX mlink_i4 ON mlink(pid);
211
--- src/schema.c
+++ src/schema.c
@@ -40,11 +40,11 @@
40 ** a date) which can change frequently. When the content schema changes,
41 ** we have to execute special procedures to update the schema. When
42 ** the aux schema changes, all we need to do is rebuild the database.
43 */
44 #define CONTENT_SCHEMA "1"
45 #define AUX_SCHEMA "2011-02-25 14:52"
46
47 #endif /* INTERFACE */
48
49
50 /*
@@ -200,11 +200,12 @@
200 @ CREATE TABLE mlink(
201 @ mid INTEGER REFERENCES blob, -- Manifest ID where change occurs
202 @ pid INTEGER REFERENCES blob, -- File ID in parent manifest
203 @ fid INTEGER REFERENCES blob, -- Changed file ID in this manifest
204 @ fnid INTEGER REFERENCES filename, -- Name of the file
205 @ pfnid INTEGER REFERENCES filename, -- Previous name. 0 if unchanged
206 @ mperm INTEGER -- File permissions. 1==exec
207 @ );
208 @ CREATE INDEX mlink_i1 ON mlink(mid);
209 @ CREATE INDEX mlink_i2 ON mlink(fnid);
210 @ CREATE INDEX mlink_i3 ON mlink(fid);
211 @ CREATE INDEX mlink_i4 ON mlink(pid);
212

Keyboard Shortcuts

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