Fossil SCM

Add two new columns to the MLINK table. ("fossil rebuild" is not required but is highly recommended.) Use these new tables to improve the display of the history of changes to a single file.

drh 2015-01-26 16:45 trunk merge
Commit 65aa10f97c25606cdc100a73dfa50a81520a31d1
+16 -1
--- src/db.c
+++ src/db.c
@@ -1175,10 +1175,26 @@
11751175
g.zRepositoryName = mprintf("%s", zDbName);
11761176
db_open_or_attach(g.zRepositoryName, "repository", 0);
11771177
g.repositoryOpen = 1;
11781178
/* Cache "allow-symlinks" option, because we'll need it on every stat call */
11791179
g.allowSymlinks = db_get_boolean("allow-symlinks", 0);
1180
+ g.zAuxSchema = db_get("aux-schema","");
1181
+
1182
+ /* Verify that the MLINK table has the newer columns added by the
1183
+ ** 2015-01-24 schema change. Create them if necessary. This code
1184
+ ** can be removed in the future, once all users have upgraded to the
1185
+ ** 2015-01-24 schema.
1186
+ */
1187
+ if( !db_table_has_column("repository","mlink","isaux") ){
1188
+ db_begin_transaction();
1189
+ db_multi_exec(
1190
+ "ALTER TABLE %s.mlink ADD COLUMN pmid INTEGER DEFAULT 0;"
1191
+ "ALTER TABLE %s.mlink ADD COLUMN isaux INTEGER DEFAULT 0;",
1192
+ db_name("repository"), db_name("repository")
1193
+ );
1194
+ db_end_transaction(0);
1195
+ }
11801196
}
11811197
11821198
/*
11831199
** Flags for the db_find_and_open_repository() function.
11841200
*/
@@ -1242,11 +1258,10 @@
12421258
12431259
/*
12441260
** Return TRUE if the schema is out-of-date
12451261
*/
12461262
int db_schema_is_outofdate(void){
1247
- if( g.zAuxSchema==0 ) g.zAuxSchema = db_get("aux-schema","");
12481263
return strcmp(g.zAuxSchema,AUX_SCHEMA_MIN)<0
12491264
|| strcmp(g.zAuxSchema,AUX_SCHEMA_MAX)>0;
12501265
}
12511266
12521267
/*
12531268
--- src/db.c
+++ src/db.c
@@ -1175,10 +1175,26 @@
1175 g.zRepositoryName = mprintf("%s", zDbName);
1176 db_open_or_attach(g.zRepositoryName, "repository", 0);
1177 g.repositoryOpen = 1;
1178 /* Cache "allow-symlinks" option, because we'll need it on every stat call */
1179 g.allowSymlinks = db_get_boolean("allow-symlinks", 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1180 }
1181
1182 /*
1183 ** Flags for the db_find_and_open_repository() function.
1184 */
@@ -1242,11 +1258,10 @@
1242
1243 /*
1244 ** Return TRUE if the schema is out-of-date
1245 */
1246 int db_schema_is_outofdate(void){
1247 if( g.zAuxSchema==0 ) g.zAuxSchema = db_get("aux-schema","");
1248 return strcmp(g.zAuxSchema,AUX_SCHEMA_MIN)<0
1249 || strcmp(g.zAuxSchema,AUX_SCHEMA_MAX)>0;
1250 }
1251
1252 /*
1253
--- src/db.c
+++ src/db.c
@@ -1175,10 +1175,26 @@
1175 g.zRepositoryName = mprintf("%s", zDbName);
1176 db_open_or_attach(g.zRepositoryName, "repository", 0);
1177 g.repositoryOpen = 1;
1178 /* Cache "allow-symlinks" option, because we'll need it on every stat call */
1179 g.allowSymlinks = db_get_boolean("allow-symlinks", 0);
1180 g.zAuxSchema = db_get("aux-schema","");
1181
1182 /* Verify that the MLINK table has the newer columns added by the
1183 ** 2015-01-24 schema change. Create them if necessary. This code
1184 ** can be removed in the future, once all users have upgraded to the
1185 ** 2015-01-24 schema.
1186 */
1187 if( !db_table_has_column("repository","mlink","isaux") ){
1188 db_begin_transaction();
1189 db_multi_exec(
1190 "ALTER TABLE %s.mlink ADD COLUMN pmid INTEGER DEFAULT 0;"
1191 "ALTER TABLE %s.mlink ADD COLUMN isaux INTEGER DEFAULT 0;",
1192 db_name("repository"), db_name("repository")
1193 );
1194 db_end_transaction(0);
1195 }
1196 }
1197
1198 /*
1199 ** Flags for the db_find_and_open_repository() function.
1200 */
@@ -1242,11 +1258,10 @@
1258
1259 /*
1260 ** Return TRUE if the schema is out-of-date
1261 */
1262 int db_schema_is_outofdate(void){
 
1263 return strcmp(g.zAuxSchema,AUX_SCHEMA_MIN)<0
1264 || strcmp(g.zAuxSchema,AUX_SCHEMA_MAX)>0;
1265 }
1266
1267 /*
1268
+26 -37
--- src/finfo.c
+++ src/finfo.c
@@ -284,11 +284,10 @@
284284
** b=DATE Only show changes before DATE
285285
** n=NUM Show the first NUM changes only
286286
** brbg Background color by branch name
287287
** ubg Background color by user name
288288
** ci=UUID Ancestors of a particular check-in
289
-** fco=BOOL Show only first occurrence of each version if true (default)
290289
*/
291290
void finfo_page(void){
292291
Stmt q;
293292
const char *zFilename;
294293
char zPrevDate[20];
@@ -302,11 +301,10 @@
302301
Blob sql;
303302
HQuery url;
304303
GraphContext *pGraph;
305304
int brBg = P("brbg")!=0;
306305
int uBg = P("ubg")!=0;
307
- int firstChngOnly = atoi(PD("fco","1"))!=0;
308306
int fDebug = atoi(PD("debug","0"));
309307
int fShowId = P("showid")!=0;
310308
311309
login_check_credentials();
312310
if( !g.perm.Read ){ login_needed(); return; }
@@ -314,13 +312,10 @@
314312
login_anonymous_available();
315313
url_initialize(&url, "finfo");
316314
if( brBg ) url_add_parameter(&url, "brbg", 0);
317315
if( uBg ) url_add_parameter(&url, "ubg", 0);
318316
baseCheckin = name_to_rid_www("ci");
319
- if( baseCheckin ) firstChngOnly = 1;
320
- if( !firstChngOnly ) url_add_parameter(&url, "fco", "0");
321
-
322317
zPrevDate[0] = 0;
323318
zFilename = PD("name","");
324319
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
325320
if( fnid==0 ){
326321
@ No such file: %h(zFilename)
@@ -329,38 +324,27 @@
329324
}
330325
url_add_parameter(&url, "name", zFilename);
331326
blob_zero(&sql);
332327
blob_append_sql(&sql,
333328
"SELECT"
334
- " datetime(event.mtime%s)," /* Date of change */
329
+ " datetime(min(event.mtime)%s)," /* Date of change */
335330
" coalesce(event.ecomment, event.comment)," /* Check-in comment */
336331
" coalesce(event.euser, event.user)," /* User who made chng */
337332
" mlink.pid," /* Parent file rid */
338333
" mlink.fid," /* File rid */
339334
" (SELECT uuid FROM blob WHERE rid=mlink.pid)," /* Parent file uuid */
340335
" (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */
341336
" (SELECT uuid FROM blob WHERE rid=mlink.mid)," /* Check-in uuid */
342337
" event.bgcolor," /* Background color */
343338
" (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0"
344
- " AND tagxref.rid=mlink.mid)," /* Tags */
339
+ " AND tagxref.rid=mlink.mid)," /* Branchname */
345340
" mlink.mid," /* check-in ID */
346
- " mlink.pfnid", /* Previous filename */
347
- timeline_utc(), TAG_BRANCH
348
- );
349
- if( firstChngOnly ){
350
- blob_append_sql(&sql,
351
- ", min(CASE (SELECT value FROM tagxref"
352
- " WHERE tagtype>0 AND tagid=%d"
353
- " AND tagxref.rid=mlink.mid)"
354
- " WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)",
355
- TAG_BRANCH);
356
- }
357
- blob_append_sql(&sql,
341
+ " mlink.pfnid" /* Previous filename */
358342
" FROM mlink, event"
359343
" WHERE mlink.fnid=%d"
360344
" AND event.objid=mlink.mid",
361
- fnid
345
+ timeline_utc(), TAG_BRANCH, fnid
362346
);
363347
if( baseCheckin ){
364348
compute_direct_ancestors(baseCheckin, 10000000);
365349
blob_append_sql(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)");
366350
}
@@ -370,28 +354,18 @@
370354
}
371355
if( (zB = P("b"))!=0 ){
372356
blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zB);
373357
url_add_parameter(&url, "b", zB);
374358
}
375
- if( firstChngOnly ){
376
- blob_append_sql(&sql, " GROUP BY mlink.fid");
377
- }
378
- blob_append_sql(&sql," ORDER BY event.mtime DESC /*sort*/");
359
+ blob_append_sql(&sql,
360
+ " GROUP BY mlink.fid"
361
+ " ORDER BY event.mtime DESC /*sort*/"
362
+ );
379363
if( (n = atoi(PD("n","0")))>0 ){
380364
blob_append_sql(&sql, " LIMIT %d", n);
381365
url_add_parameter(&url, "n", P("n"));
382366
}
383
- if( baseCheckin==0 ){
384
- if( firstChngOnly ){
385
- style_submenu_element("Full", "Show all changes","%s",
386
- url_render(&url, "fco", "0", 0, 0));
387
- }else{
388
- style_submenu_element("Simplified",
389
- "Show only first use of a change","%s",
390
- url_render(&url, "fco", 0, 0, 0));
391
- }
392
- }
393367
db_prepare(&q, "%s", blob_sql_text(&sql));
394368
if( P("showsql")!=0 ){
395369
@ <p>SQL: %h(blob_str(&sql))</p>
396370
}
397371
blob_reset(&sql);
@@ -427,17 +401,32 @@
427401
const char *zBr = db_column_text(&q, 9);
428402
int fmid = db_column_int(&q, 10);
429403
int pfnid = db_column_int(&q, 11);
430404
int gidx;
431405
char zTime[10];
406
+ int nParent = 0;
407
+ int aParent[GR_MAX_RAIL];
408
+ static Stmt qparent;
409
+ db_static_prepare(&qparent,
410
+ "SELECT DISTINCT pid FROM mlink"
411
+ " WHERE fid=:fid AND mid=:mid AND pid>0 AND fnid=:fnid"
412
+ " ORDER BY isaux /*sort*/"
413
+ );
414
+ db_bind_int(&qparent, ":fid", frid);
415
+ db_bind_int(&qparent, ":mid", fmid);
416
+ db_bind_int(&qparent, ":fnid", fnid);
417
+ while( db_step(&qparent)==SQLITE_ROW && nParent<ArraySize(aParent) ){
418
+ aParent[nParent++] = db_column_int(&qparent, 0);
419
+ }
420
+ db_reset(&qparent);
432421
if( zBr==0 ) zBr = "trunk";
433422
if( uBg ){
434423
zBgClr = hash_color(zUser);
435424
}else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
436425
zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
437426
}
438
- gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr,
427
+ gidx = graph_add_row(pGraph, frid, nParent, aParent, zBr, zBgClr,
439428
zUuid, 0);
440429
if( strncmp(zDate, zPrevDate, 10) ){
441430
sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
442431
@ <tr><td>
443432
@ <div class="divider">%s(zPrevDate)</div>
@@ -452,11 +441,11 @@
452441
@ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
453442
}else{
454443
@ <td class="timelineTableCell">
455444
}
456445
if( zUuid ){
457
- if( fpid==0 ){
446
+ if( nParent==0 ){
458447
@ <b>Added</b>
459448
}else if( pfnid ){
460449
char *zPrevName = db_text(0, "SELECT name FROM filename WHERE fnid=%d",
461450
pfnid);
462451
@ <b>Renamed</b> from
@@ -487,11 +476,11 @@
487476
if( fShowId ){
488477
@ (%d(fmid))
489478
}
490479
@ %W(zCom) (user:
491480
hyperlink_to_user(zUser, zDate, "");
492
- @ branch: %h(zBr))
481
+ @ branch: %z(href("%R/timeline?t=%T&n=200",zBr))%h(zBr)</a>
493482
if( g.perm.Hyperlink && zUuid ){
494483
const char *z = zFilename;
495484
@ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin))
496485
@ [annotate]</a>
497486
@ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin))
498487
--- src/finfo.c
+++ src/finfo.c
@@ -284,11 +284,10 @@
284 ** b=DATE Only show changes before DATE
285 ** n=NUM Show the first NUM changes only
286 ** brbg Background color by branch name
287 ** ubg Background color by user name
288 ** ci=UUID Ancestors of a particular check-in
289 ** fco=BOOL Show only first occurrence of each version if true (default)
290 */
291 void finfo_page(void){
292 Stmt q;
293 const char *zFilename;
294 char zPrevDate[20];
@@ -302,11 +301,10 @@
302 Blob sql;
303 HQuery url;
304 GraphContext *pGraph;
305 int brBg = P("brbg")!=0;
306 int uBg = P("ubg")!=0;
307 int firstChngOnly = atoi(PD("fco","1"))!=0;
308 int fDebug = atoi(PD("debug","0"));
309 int fShowId = P("showid")!=0;
310
311 login_check_credentials();
312 if( !g.perm.Read ){ login_needed(); return; }
@@ -314,13 +312,10 @@
314 login_anonymous_available();
315 url_initialize(&url, "finfo");
316 if( brBg ) url_add_parameter(&url, "brbg", 0);
317 if( uBg ) url_add_parameter(&url, "ubg", 0);
318 baseCheckin = name_to_rid_www("ci");
319 if( baseCheckin ) firstChngOnly = 1;
320 if( !firstChngOnly ) url_add_parameter(&url, "fco", "0");
321
322 zPrevDate[0] = 0;
323 zFilename = PD("name","");
324 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
325 if( fnid==0 ){
326 @ No such file: %h(zFilename)
@@ -329,38 +324,27 @@
329 }
330 url_add_parameter(&url, "name", zFilename);
331 blob_zero(&sql);
332 blob_append_sql(&sql,
333 "SELECT"
334 " datetime(event.mtime%s)," /* Date of change */
335 " coalesce(event.ecomment, event.comment)," /* Check-in comment */
336 " coalesce(event.euser, event.user)," /* User who made chng */
337 " mlink.pid," /* Parent file rid */
338 " mlink.fid," /* File rid */
339 " (SELECT uuid FROM blob WHERE rid=mlink.pid)," /* Parent file uuid */
340 " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */
341 " (SELECT uuid FROM blob WHERE rid=mlink.mid)," /* Check-in uuid */
342 " event.bgcolor," /* Background color */
343 " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0"
344 " AND tagxref.rid=mlink.mid)," /* Tags */
345 " mlink.mid," /* check-in ID */
346 " mlink.pfnid", /* Previous filename */
347 timeline_utc(), TAG_BRANCH
348 );
349 if( firstChngOnly ){
350 blob_append_sql(&sql,
351 ", min(CASE (SELECT value FROM tagxref"
352 " WHERE tagtype>0 AND tagid=%d"
353 " AND tagxref.rid=mlink.mid)"
354 " WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)",
355 TAG_BRANCH);
356 }
357 blob_append_sql(&sql,
358 " FROM mlink, event"
359 " WHERE mlink.fnid=%d"
360 " AND event.objid=mlink.mid",
361 fnid
362 );
363 if( baseCheckin ){
364 compute_direct_ancestors(baseCheckin, 10000000);
365 blob_append_sql(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)");
366 }
@@ -370,28 +354,18 @@
370 }
371 if( (zB = P("b"))!=0 ){
372 blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zB);
373 url_add_parameter(&url, "b", zB);
374 }
375 if( firstChngOnly ){
376 blob_append_sql(&sql, " GROUP BY mlink.fid");
377 }
378 blob_append_sql(&sql," ORDER BY event.mtime DESC /*sort*/");
379 if( (n = atoi(PD("n","0")))>0 ){
380 blob_append_sql(&sql, " LIMIT %d", n);
381 url_add_parameter(&url, "n", P("n"));
382 }
383 if( baseCheckin==0 ){
384 if( firstChngOnly ){
385 style_submenu_element("Full", "Show all changes","%s",
386 url_render(&url, "fco", "0", 0, 0));
387 }else{
388 style_submenu_element("Simplified",
389 "Show only first use of a change","%s",
390 url_render(&url, "fco", 0, 0, 0));
391 }
392 }
393 db_prepare(&q, "%s", blob_sql_text(&sql));
394 if( P("showsql")!=0 ){
395 @ <p>SQL: %h(blob_str(&sql))</p>
396 }
397 blob_reset(&sql);
@@ -427,17 +401,32 @@
427 const char *zBr = db_column_text(&q, 9);
428 int fmid = db_column_int(&q, 10);
429 int pfnid = db_column_int(&q, 11);
430 int gidx;
431 char zTime[10];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
432 if( zBr==0 ) zBr = "trunk";
433 if( uBg ){
434 zBgClr = hash_color(zUser);
435 }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
436 zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
437 }
438 gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr,
439 zUuid, 0);
440 if( strncmp(zDate, zPrevDate, 10) ){
441 sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
442 @ <tr><td>
443 @ <div class="divider">%s(zPrevDate)</div>
@@ -452,11 +441,11 @@
452 @ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
453 }else{
454 @ <td class="timelineTableCell">
455 }
456 if( zUuid ){
457 if( fpid==0 ){
458 @ <b>Added</b>
459 }else if( pfnid ){
460 char *zPrevName = db_text(0, "SELECT name FROM filename WHERE fnid=%d",
461 pfnid);
462 @ <b>Renamed</b> from
@@ -487,11 +476,11 @@
487 if( fShowId ){
488 @ (%d(fmid))
489 }
490 @ %W(zCom) (user:
491 hyperlink_to_user(zUser, zDate, "");
492 @ branch: %h(zBr))
493 if( g.perm.Hyperlink && zUuid ){
494 const char *z = zFilename;
495 @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin))
496 @ [annotate]</a>
497 @ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin))
498
--- src/finfo.c
+++ src/finfo.c
@@ -284,11 +284,10 @@
284 ** b=DATE Only show changes before DATE
285 ** n=NUM Show the first NUM changes only
286 ** brbg Background color by branch name
287 ** ubg Background color by user name
288 ** ci=UUID Ancestors of a particular check-in
 
289 */
290 void finfo_page(void){
291 Stmt q;
292 const char *zFilename;
293 char zPrevDate[20];
@@ -302,11 +301,10 @@
301 Blob sql;
302 HQuery url;
303 GraphContext *pGraph;
304 int brBg = P("brbg")!=0;
305 int uBg = P("ubg")!=0;
 
306 int fDebug = atoi(PD("debug","0"));
307 int fShowId = P("showid")!=0;
308
309 login_check_credentials();
310 if( !g.perm.Read ){ login_needed(); return; }
@@ -314,13 +312,10 @@
312 login_anonymous_available();
313 url_initialize(&url, "finfo");
314 if( brBg ) url_add_parameter(&url, "brbg", 0);
315 if( uBg ) url_add_parameter(&url, "ubg", 0);
316 baseCheckin = name_to_rid_www("ci");
 
 
 
317 zPrevDate[0] = 0;
318 zFilename = PD("name","");
319 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
320 if( fnid==0 ){
321 @ No such file: %h(zFilename)
@@ -329,38 +324,27 @@
324 }
325 url_add_parameter(&url, "name", zFilename);
326 blob_zero(&sql);
327 blob_append_sql(&sql,
328 "SELECT"
329 " datetime(min(event.mtime)%s)," /* Date of change */
330 " coalesce(event.ecomment, event.comment)," /* Check-in comment */
331 " coalesce(event.euser, event.user)," /* User who made chng */
332 " mlink.pid," /* Parent file rid */
333 " mlink.fid," /* File rid */
334 " (SELECT uuid FROM blob WHERE rid=mlink.pid)," /* Parent file uuid */
335 " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */
336 " (SELECT uuid FROM blob WHERE rid=mlink.mid)," /* Check-in uuid */
337 " event.bgcolor," /* Background color */
338 " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0"
339 " AND tagxref.rid=mlink.mid)," /* Branchname */
340 " mlink.mid," /* check-in ID */
341 " mlink.pfnid" /* Previous filename */
 
 
 
 
 
 
 
 
 
 
 
342 " FROM mlink, event"
343 " WHERE mlink.fnid=%d"
344 " AND event.objid=mlink.mid",
345 timeline_utc(), TAG_BRANCH, fnid
346 );
347 if( baseCheckin ){
348 compute_direct_ancestors(baseCheckin, 10000000);
349 blob_append_sql(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)");
350 }
@@ -370,28 +354,18 @@
354 }
355 if( (zB = P("b"))!=0 ){
356 blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zB);
357 url_add_parameter(&url, "b", zB);
358 }
359 blob_append_sql(&sql,
360 " GROUP BY mlink.fid"
361 " ORDER BY event.mtime DESC /*sort*/"
362 );
363 if( (n = atoi(PD("n","0")))>0 ){
364 blob_append_sql(&sql, " LIMIT %d", n);
365 url_add_parameter(&url, "n", P("n"));
366 }
 
 
 
 
 
 
 
 
 
 
367 db_prepare(&q, "%s", blob_sql_text(&sql));
368 if( P("showsql")!=0 ){
369 @ <p>SQL: %h(blob_str(&sql))</p>
370 }
371 blob_reset(&sql);
@@ -427,17 +401,32 @@
401 const char *zBr = db_column_text(&q, 9);
402 int fmid = db_column_int(&q, 10);
403 int pfnid = db_column_int(&q, 11);
404 int gidx;
405 char zTime[10];
406 int nParent = 0;
407 int aParent[GR_MAX_RAIL];
408 static Stmt qparent;
409 db_static_prepare(&qparent,
410 "SELECT DISTINCT pid FROM mlink"
411 " WHERE fid=:fid AND mid=:mid AND pid>0 AND fnid=:fnid"
412 " ORDER BY isaux /*sort*/"
413 );
414 db_bind_int(&qparent, ":fid", frid);
415 db_bind_int(&qparent, ":mid", fmid);
416 db_bind_int(&qparent, ":fnid", fnid);
417 while( db_step(&qparent)==SQLITE_ROW && nParent<ArraySize(aParent) ){
418 aParent[nParent++] = db_column_int(&qparent, 0);
419 }
420 db_reset(&qparent);
421 if( zBr==0 ) zBr = "trunk";
422 if( uBg ){
423 zBgClr = hash_color(zUser);
424 }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
425 zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
426 }
427 gidx = graph_add_row(pGraph, frid, nParent, aParent, zBr, zBgClr,
428 zUuid, 0);
429 if( strncmp(zDate, zPrevDate, 10) ){
430 sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
431 @ <tr><td>
432 @ <div class="divider">%s(zPrevDate)</div>
@@ -452,11 +441,11 @@
441 @ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
442 }else{
443 @ <td class="timelineTableCell">
444 }
445 if( zUuid ){
446 if( nParent==0 ){
447 @ <b>Added</b>
448 }else if( pfnid ){
449 char *zPrevName = db_text(0, "SELECT name FROM filename WHERE fnid=%d",
450 pfnid);
451 @ <b>Renamed</b> from
@@ -487,11 +476,11 @@
476 if( fShowId ){
477 @ (%d(fmid))
478 }
479 @ %W(zCom) (user:
480 hyperlink_to_user(zUser, zDate, "");
481 @ branch: %z(href("%R/timeline?t=%T&n=200",zBr))%h(zBr)</a>
482 if( g.perm.Hyperlink && zUuid ){
483 const char *z = zFilename;
484 @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin))
485 @ [annotate]</a>
486 @ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin))
487
+21
--- src/graph.c
+++ src/graph.c
@@ -378,10 +378,31 @@
378378
i--;
379379
}
380380
}
381381
}
382382
}
383
+
384
+ /* If the primary parent is in a different branch, but there are
385
+ ** other parents in the same branch, reorder the parents to make
386
+ ** the parent from the same branch the primary parent.
387
+ */
388
+ for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
389
+ if( pRow->isDup ) continue;
390
+ if( pRow->nParent<2 ) continue; /* Not a fork */
391
+ pParent = hashFind(p, pRow->aParent[0]);
392
+ if( pParent==0 ) continue; /* Parent off-screen */
393
+ if( pParent->zBranch==pRow->zBranch ) continue; /* Same branch */
394
+ for(i=1; i<pRow->nParent; i++){
395
+ pParent = hashFind(p, pRow->aParent[i]);
396
+ if( pParent->zBranch==pRow->zBranch ){
397
+ int t = pRow->aParent[0];
398
+ pRow->aParent[0] = pRow->aParent[i];
399
+ pRow->aParent[i] = t;
400
+ break;
401
+ }
402
+ }
403
+ }
383404
384405
385406
/* Find the pChild pointer for each node.
386407
**
387408
** The pChild points to the node directly above on the same rail.
388409
--- src/graph.c
+++ src/graph.c
@@ -378,10 +378,31 @@
378 i--;
379 }
380 }
381 }
382 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
384
385 /* Find the pChild pointer for each node.
386 **
387 ** The pChild points to the node directly above on the same rail.
388
--- src/graph.c
+++ src/graph.c
@@ -378,10 +378,31 @@
378 i--;
379 }
380 }
381 }
382 }
383
384 /* If the primary parent is in a different branch, but there are
385 ** other parents in the same branch, reorder the parents to make
386 ** the parent from the same branch the primary parent.
387 */
388 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
389 if( pRow->isDup ) continue;
390 if( pRow->nParent<2 ) continue; /* Not a fork */
391 pParent = hashFind(p, pRow->aParent[0]);
392 if( pParent==0 ) continue; /* Parent off-screen */
393 if( pParent->zBranch==pRow->zBranch ) continue; /* Same branch */
394 for(i=1; i<pRow->nParent; i++){
395 pParent = hashFind(p, pRow->aParent[i]);
396 if( pParent->zBranch==pRow->zBranch ){
397 int t = pRow->aParent[0];
398 pRow->aParent[0] = pRow->aParent[i];
399 pRow->aParent[i] = t;
400 break;
401 }
402 }
403 }
404
405
406 /* Find the pChild pointer for each node.
407 **
408 ** The pChild points to the node directly above on the same rail.
409
+64 -53
--- src/manifest.c
+++ src/manifest.c
@@ -1187,16 +1187,18 @@
11871187
/*
11881188
** Add a single entry to the mlink table. Also add the filename to
11891189
** the filename table if it is not there already.
11901190
*/
11911191
static void add_one_mlink(
1192
+ int pmid, /* The parent manifest */
1193
+ const char *zFromUuid, /* UUID for content in parent */
11921194
int mid, /* The record ID of the manifest */
1193
- const char *zFromUuid, /* UUID for the mlink.pid. "" to add file */
1194
- const char *zToUuid, /* UUID for the mlink.fid. "" to delete */
1195
+ const char *zToUuid, /* UUID for content in child */
11951196
const char *zFilename, /* Filename */
11961197
const char *zPrior, /* Previous filename. NULL if unchanged */
11971198
int isPublic, /* True if mid is not a private manifest */
1199
+ int isPrimary, /* pmid is the primary parent of mid */
11981200
int mperm /* 1: exec, 2: symlink */
11991201
){
12001202
int fnid, pfnid, pid, fid;
12011203
static Stmt s1;
12021204
@@ -1216,19 +1218,21 @@
12161218
}else{
12171219
fid = uuid_to_rid(zToUuid, 1);
12181220
if( isPublic ) content_make_public(fid);
12191221
}
12201222
db_static_prepare(&s1,
1221
- "INSERT INTO mlink(mid,pid,fid,fnid,pfnid,mperm)"
1222
- "VALUES(:m,:p,:f,:n,:pfn,:mp)"
1223
+ "INSERT INTO mlink(mid,fid,pmid,pid,fnid,pfnid,mperm,isaux)"
1224
+ "VALUES(:m,:f,:pm,:p,:n,:pfn,:mp,:isaux)"
12231225
);
12241226
db_bind_int(&s1, ":m", mid);
1225
- db_bind_int(&s1, ":p", pid);
12261227
db_bind_int(&s1, ":f", fid);
1228
+ db_bind_int(&s1, ":pm", pmid);
1229
+ db_bind_int(&s1, ":p", pid);
12271230
db_bind_int(&s1, ":n", fnid);
12281231
db_bind_int(&s1, ":pfn", pfnid);
12291232
db_bind_int(&s1, ":mp", mperm);
1233
+ db_bind_int(&s1, ":isaux", isPrimary==0);
12301234
db_exec(&s1);
12311235
if( pid && fid ){
12321236
content_deltify(pid, fid, 0);
12331237
}
12341238
}
@@ -1342,24 +1346,29 @@
13421346
**
13431347
** Deleted files have mlink.fid=0.
13441348
** Added files have mlink.pid=0.
13451349
** Edited files have both mlink.pid!=0 and mlink.fid!=0
13461350
*/
1347
-static void add_mlink(int pid, Manifest *pParent, int cid, Manifest *pChild){
1351
+static void add_mlink(
1352
+ int pmid, Manifest *pParent, /* Parent check-in */
1353
+ int mid, Manifest *pChild, /* The child check-in */
1354
+ int isPrim /* TRUE if pmid is the primary parent of mid */
1355
+){
13481356
Blob otherContent;
13491357
int otherRid;
13501358
int i, rc;
13511359
ManifestFile *pChildFile, *pParentFile;
13521360
Manifest **ppOther;
13531361
static Stmt eq;
13541362
int isPublic; /* True if pChild is non-private */
13551363
1356
- /* If mlink table entires are already set for cid, then abort early
1357
- ** doing no work.
1364
+ /* If mlink table entires are already exist for the pmid-to-mid transition,
1365
+ ** then abort early doing no work.
13581366
*/
1359
- db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid");
1360
- db_bind_int(&eq, ":mid", cid);
1367
+ db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid AND pmid=:pmid");
1368
+ db_bind_int(&eq, ":mid", mid);
1369
+ db_bind_int(&eq, ":pmid", pmid);
13611370
rc = db_step(&eq);
13621371
db_reset(&eq);
13631372
if( rc==SQLITE_ROW ) return;
13641373
13651374
/* Compute the value of the missing pParent or pChild parameter.
@@ -1366,14 +1375,14 @@
13661375
** Fetch the baseline checkins for both.
13671376
*/
13681377
assert( pParent==0 || pChild==0 );
13691378
if( pParent==0 ){
13701379
ppOther = &pParent;
1371
- otherRid = pid;
1380
+ otherRid = pmid;
13721381
}else{
13731382
ppOther = &pChild;
1374
- otherRid = cid;
1383
+ otherRid = mid;
13751384
}
13761385
if( (*ppOther = manifest_cache_find(otherRid))==0 ){
13771386
content_get(otherRid, &otherContent);
13781387
if( blob_size(&otherContent)==0 ) return;
13791388
*ppOther = manifest_parse(&otherContent, otherRid, 0);
@@ -1381,20 +1390,20 @@
13811390
}
13821391
if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){
13831392
manifest_destroy(*ppOther);
13841393
return;
13851394
}
1386
- isPublic = !content_is_private(cid);
1395
+ isPublic = !content_is_private(mid);
13871396
13881397
/* Try to make the parent manifest a delta from the child, if that
13891398
** is an appropriate thing to do. For a new baseline, make the
13901399
** previous baseline a delta from the current baseline.
13911400
*/
13921401
if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){
1393
- content_deltify(pid, cid, 0);
1402
+ content_deltify(pmid, mid, 0);
13941403
}else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){
1395
- content_deltify(pParent->pBaseline->rid, cid, 0);
1404
+ content_deltify(pParent->pBaseline->rid, mid, 0);
13961405
}
13971406
13981407
/* Remember all children less than a few seconds younger than their parent,
13991408
** as we might want to fudge the times for those children.
14001409
*/
@@ -1414,31 +1423,32 @@
14141423
int mperm = manifest_file_mperm(pChildFile);
14151424
if( pChildFile->zPrior ){
14161425
pParentFile = manifest_file_seek(pParent, pChildFile->zPrior, 0);
14171426
if( pParentFile ){
14181427
/* File with name change */
1419
- add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid,
1420
- pChildFile->zName, pChildFile->zPrior, isPublic, mperm);
1428
+ add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid,
1429
+ pChildFile->zName, pChildFile->zPrior,
1430
+ isPublic, isPrim, mperm);
14211431
}else{
14221432
/* File name changed, but the old name is not found in the parent!
14231433
** Treat this like a new file. */
1424
- add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0,
1425
- isPublic, mperm);
1434
+ add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0,
1435
+ isPublic, isPrim, mperm);
14261436
}
14271437
}else{
14281438
pParentFile = manifest_file_seek(pParent, pChildFile->zName, 0);
14291439
if( pParentFile==0 ){
14301440
if( pChildFile->zUuid ){
14311441
/* A new file */
1432
- add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0,
1433
- isPublic, mperm);
1442
+ add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0,
1443
+ isPublic, isPrim, mperm);
14341444
}
14351445
}else if( fossil_strcmp(pChildFile->zUuid, pParentFile->zUuid)!=0
14361446
|| manifest_file_mperm(pParentFile)!=mperm ){
14371447
/* Changes in file content or permissions */
1438
- add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid,
1439
- pChildFile->zName, 0, isPublic, mperm);
1448
+ add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid,
1449
+ pChildFile->zName, 0, isPublic, isPrim, mperm);
14401450
}
14411451
}
14421452
}
14431453
if( pParent->zBaseline && pChild->zBaseline ){
14441454
/* Both parent and child are delta manifests. Look for files that
@@ -1450,22 +1460,22 @@
14501460
pChildFile = manifest_file_seek_base(pChild, pParentFile->zName, 0);
14511461
if( pChildFile==0 ){
14521462
/* The child file reverts to baseline. Show this as a change */
14531463
pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0);
14541464
if( pChildFile ){
1455
- add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid,
1456
- pChildFile->zName, 0, isPublic,
1465
+ add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid,
1466
+ pChildFile->zName, 0, isPublic, isPrim,
14571467
manifest_file_mperm(pChildFile));
14581468
}
14591469
}
14601470
}else{
14611471
pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0);
14621472
if( pChildFile ){
14631473
/* File resurrected in the child after having been deleted in
14641474
** the parent. Show this as an added file. */
1465
- add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0,
1466
- isPublic, manifest_file_mperm(pChildFile));
1475
+ add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0,
1476
+ isPublic, isPrim, manifest_file_mperm(pChildFile));
14671477
}
14681478
}
14691479
}
14701480
}else if( pChild->zBaseline==0 ){
14711481
/* pChild is a baseline. Look for files that are present in pParent
@@ -1472,12 +1482,12 @@
14721482
** but are missing from pChild and mark them as having been deleted. */
14731483
manifest_file_rewind(pParent);
14741484
while( (pParentFile = manifest_file_next(pParent,0))!=0 ){
14751485
pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0);
14761486
if( pChildFile==0 && pParentFile->zUuid!=0 ){
1477
- add_one_mlink(cid, pParentFile->zUuid, 0, pParentFile->zName, 0,
1478
- isPublic, 0);
1487
+ add_one_mlink(pmid, pParentFile->zUuid, mid, 0, pParentFile->zName, 0,
1488
+ isPublic, isPrim, 0);
14791489
}
14801490
}
14811491
}
14821492
manifest_cache_insert(*ppOther);
14831493
}
@@ -1781,45 +1791,46 @@
17811791
sqlite3_snprintf(sizeof(zBaseId), zBaseId, "%d",
17821792
uuid_to_rid(p->zBaseline,1));
17831793
}else{
17841794
sqlite3_snprintf(sizeof(zBaseId), zBaseId, "NULL");
17851795
}
1786
- (void)db_schema_is_outofdate(); /* Make sure g.zAuxSchema is initialized */
17871796
for(i=0; i<p->nParent; i++){
17881797
int pid = uuid_to_rid(p->azParent[i], 1);
1789
- if( strcmp(g.zAuxSchema,"2014-11-24 20:35")>=0 ){
1790
- /* Support for PLINK.BASEID added on 2014-11-24 */
1791
- db_multi_exec(
1792
- "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)"
1793
- "VALUES(%d, %d, %d, %.17g, %s)",
1794
- pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/);
1795
- }else{
1796
- /* Continue to work with older schema to avoid an unnecessary
1797
- ** rebuild */
1798
- db_multi_exec(
1799
- "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)"
1800
- "VALUES(%d, %d, %d, %.17g)",
1801
- pid, rid, i==0, p->rDate);
1802
- }
1803
- if( i==0 ){
1804
- add_mlink(pid, 0, rid, p);
1805
- parentid = pid;
1806
- }
1807
- }
1808
- db_prepare(&q, "SELECT cid FROM plink WHERE pid=%d AND isprim", rid);
1798
+ db_multi_exec(
1799
+ "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)"
1800
+ "VALUES(%d, %d, %d, %.17g, %s)",
1801
+ pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/);
1802
+ add_mlink(pid, 0, rid, p, i);
1803
+ if( i==0 ) parentid = pid;
1804
+ }
1805
+ if( p->nParent>1 ){
1806
+ /* Remove incorrect MLINK create-file entries that arise when a
1807
+ ** file is added by merge. */
1808
+ db_multi_exec(
1809
+ "DELETE FROM mlink"
1810
+ " WHERE mid=%d"
1811
+ " AND pid=0"
1812
+ " AND fnid IN "
1813
+ " (SELECT fnid FROM mlink WHERE mid=%d GROUP BY fnid"
1814
+ " HAVING count(*)<%d)",
1815
+ rid, rid, p->nParent
1816
+ );
1817
+ }
1818
+ db_prepare(&q, "SELECT cid, isprim FROM plink WHERE pid=%d", rid);
18091819
while( db_step(&q)==SQLITE_ROW ){
18101820
int cid = db_column_int(&q, 0);
1811
- add_mlink(rid, p, cid, 0);
1821
+ int isprim = db_column_int(&q, 1);
1822
+ add_mlink(rid, p, cid, 0, isprim);
18121823
}
18131824
db_finalize(&q);
18141825
if( p->nParent==0 ){
18151826
/* For root files (files without parents) add mlink entries
18161827
** showing all content as new. */
18171828
int isPublic = !content_is_private(rid);
18181829
for(i=0; i<p->nFile; i++){
1819
- add_one_mlink(rid, 0, p->aFile[i].zUuid, p->aFile[i].zName, 0,
1820
- isPublic, manifest_file_mperm(&p->aFile[i]));
1830
+ add_one_mlink(0, 0, rid, p->aFile[i].zUuid, p->aFile[i].zName, 0,
1831
+ isPublic, 1, manifest_file_mperm(&p->aFile[i]));
18211832
}
18221833
}
18231834
db_multi_exec(
18241835
"REPLACE INTO event(type,mtime,objid,user,comment,"
18251836
"bgcolor,euser,ecomment,omtime)"
18261837
--- src/manifest.c
+++ src/manifest.c
@@ -1187,16 +1187,18 @@
1187 /*
1188 ** Add a single entry to the mlink table. Also add the filename to
1189 ** the filename table if it is not there already.
1190 */
1191 static void add_one_mlink(
 
 
1192 int mid, /* The record ID of the manifest */
1193 const char *zFromUuid, /* UUID for the mlink.pid. "" to add file */
1194 const char *zToUuid, /* UUID for the mlink.fid. "" to delete */
1195 const char *zFilename, /* Filename */
1196 const char *zPrior, /* Previous filename. NULL if unchanged */
1197 int isPublic, /* True if mid is not a private manifest */
 
1198 int mperm /* 1: exec, 2: symlink */
1199 ){
1200 int fnid, pfnid, pid, fid;
1201 static Stmt s1;
1202
@@ -1216,19 +1218,21 @@
1216 }else{
1217 fid = uuid_to_rid(zToUuid, 1);
1218 if( isPublic ) content_make_public(fid);
1219 }
1220 db_static_prepare(&s1,
1221 "INSERT INTO mlink(mid,pid,fid,fnid,pfnid,mperm)"
1222 "VALUES(:m,:p,:f,:n,:pfn,:mp)"
1223 );
1224 db_bind_int(&s1, ":m", mid);
1225 db_bind_int(&s1, ":p", pid);
1226 db_bind_int(&s1, ":f", fid);
 
 
1227 db_bind_int(&s1, ":n", fnid);
1228 db_bind_int(&s1, ":pfn", pfnid);
1229 db_bind_int(&s1, ":mp", mperm);
 
1230 db_exec(&s1);
1231 if( pid && fid ){
1232 content_deltify(pid, fid, 0);
1233 }
1234 }
@@ -1342,24 +1346,29 @@
1342 **
1343 ** Deleted files have mlink.fid=0.
1344 ** Added files have mlink.pid=0.
1345 ** Edited files have both mlink.pid!=0 and mlink.fid!=0
1346 */
1347 static void add_mlink(int pid, Manifest *pParent, int cid, Manifest *pChild){
 
 
 
 
1348 Blob otherContent;
1349 int otherRid;
1350 int i, rc;
1351 ManifestFile *pChildFile, *pParentFile;
1352 Manifest **ppOther;
1353 static Stmt eq;
1354 int isPublic; /* True if pChild is non-private */
1355
1356 /* If mlink table entires are already set for cid, then abort early
1357 ** doing no work.
1358 */
1359 db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid");
1360 db_bind_int(&eq, ":mid", cid);
 
1361 rc = db_step(&eq);
1362 db_reset(&eq);
1363 if( rc==SQLITE_ROW ) return;
1364
1365 /* Compute the value of the missing pParent or pChild parameter.
@@ -1366,14 +1375,14 @@
1366 ** Fetch the baseline checkins for both.
1367 */
1368 assert( pParent==0 || pChild==0 );
1369 if( pParent==0 ){
1370 ppOther = &pParent;
1371 otherRid = pid;
1372 }else{
1373 ppOther = &pChild;
1374 otherRid = cid;
1375 }
1376 if( (*ppOther = manifest_cache_find(otherRid))==0 ){
1377 content_get(otherRid, &otherContent);
1378 if( blob_size(&otherContent)==0 ) return;
1379 *ppOther = manifest_parse(&otherContent, otherRid, 0);
@@ -1381,20 +1390,20 @@
1381 }
1382 if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){
1383 manifest_destroy(*ppOther);
1384 return;
1385 }
1386 isPublic = !content_is_private(cid);
1387
1388 /* Try to make the parent manifest a delta from the child, if that
1389 ** is an appropriate thing to do. For a new baseline, make the
1390 ** previous baseline a delta from the current baseline.
1391 */
1392 if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){
1393 content_deltify(pid, cid, 0);
1394 }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){
1395 content_deltify(pParent->pBaseline->rid, cid, 0);
1396 }
1397
1398 /* Remember all children less than a few seconds younger than their parent,
1399 ** as we might want to fudge the times for those children.
1400 */
@@ -1414,31 +1423,32 @@
1414 int mperm = manifest_file_mperm(pChildFile);
1415 if( pChildFile->zPrior ){
1416 pParentFile = manifest_file_seek(pParent, pChildFile->zPrior, 0);
1417 if( pParentFile ){
1418 /* File with name change */
1419 add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid,
1420 pChildFile->zName, pChildFile->zPrior, isPublic, mperm);
 
1421 }else{
1422 /* File name changed, but the old name is not found in the parent!
1423 ** Treat this like a new file. */
1424 add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0,
1425 isPublic, mperm);
1426 }
1427 }else{
1428 pParentFile = manifest_file_seek(pParent, pChildFile->zName, 0);
1429 if( pParentFile==0 ){
1430 if( pChildFile->zUuid ){
1431 /* A new file */
1432 add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0,
1433 isPublic, mperm);
1434 }
1435 }else if( fossil_strcmp(pChildFile->zUuid, pParentFile->zUuid)!=0
1436 || manifest_file_mperm(pParentFile)!=mperm ){
1437 /* Changes in file content or permissions */
1438 add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid,
1439 pChildFile->zName, 0, isPublic, mperm);
1440 }
1441 }
1442 }
1443 if( pParent->zBaseline && pChild->zBaseline ){
1444 /* Both parent and child are delta manifests. Look for files that
@@ -1450,22 +1460,22 @@
1450 pChildFile = manifest_file_seek_base(pChild, pParentFile->zName, 0);
1451 if( pChildFile==0 ){
1452 /* The child file reverts to baseline. Show this as a change */
1453 pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0);
1454 if( pChildFile ){
1455 add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid,
1456 pChildFile->zName, 0, isPublic,
1457 manifest_file_mperm(pChildFile));
1458 }
1459 }
1460 }else{
1461 pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0);
1462 if( pChildFile ){
1463 /* File resurrected in the child after having been deleted in
1464 ** the parent. Show this as an added file. */
1465 add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0,
1466 isPublic, manifest_file_mperm(pChildFile));
1467 }
1468 }
1469 }
1470 }else if( pChild->zBaseline==0 ){
1471 /* pChild is a baseline. Look for files that are present in pParent
@@ -1472,12 +1482,12 @@
1472 ** but are missing from pChild and mark them as having been deleted. */
1473 manifest_file_rewind(pParent);
1474 while( (pParentFile = manifest_file_next(pParent,0))!=0 ){
1475 pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0);
1476 if( pChildFile==0 && pParentFile->zUuid!=0 ){
1477 add_one_mlink(cid, pParentFile->zUuid, 0, pParentFile->zName, 0,
1478 isPublic, 0);
1479 }
1480 }
1481 }
1482 manifest_cache_insert(*ppOther);
1483 }
@@ -1781,45 +1791,46 @@
1781 sqlite3_snprintf(sizeof(zBaseId), zBaseId, "%d",
1782 uuid_to_rid(p->zBaseline,1));
1783 }else{
1784 sqlite3_snprintf(sizeof(zBaseId), zBaseId, "NULL");
1785 }
1786 (void)db_schema_is_outofdate(); /* Make sure g.zAuxSchema is initialized */
1787 for(i=0; i<p->nParent; i++){
1788 int pid = uuid_to_rid(p->azParent[i], 1);
1789 if( strcmp(g.zAuxSchema,"2014-11-24 20:35")>=0 ){
1790 /* Support for PLINK.BASEID added on 2014-11-24 */
1791 db_multi_exec(
1792 "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)"
1793 "VALUES(%d, %d, %d, %.17g, %s)",
1794 pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/);
1795 }else{
1796 /* Continue to work with older schema to avoid an unnecessary
1797 ** rebuild */
1798 db_multi_exec(
1799 "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)"
1800 "VALUES(%d, %d, %d, %.17g)",
1801 pid, rid, i==0, p->rDate);
1802 }
1803 if( i==0 ){
1804 add_mlink(pid, 0, rid, p);
1805 parentid = pid;
1806 }
1807 }
1808 db_prepare(&q, "SELECT cid FROM plink WHERE pid=%d AND isprim", rid);
 
1809 while( db_step(&q)==SQLITE_ROW ){
1810 int cid = db_column_int(&q, 0);
1811 add_mlink(rid, p, cid, 0);
 
1812 }
1813 db_finalize(&q);
1814 if( p->nParent==0 ){
1815 /* For root files (files without parents) add mlink entries
1816 ** showing all content as new. */
1817 int isPublic = !content_is_private(rid);
1818 for(i=0; i<p->nFile; i++){
1819 add_one_mlink(rid, 0, p->aFile[i].zUuid, p->aFile[i].zName, 0,
1820 isPublic, manifest_file_mperm(&p->aFile[i]));
1821 }
1822 }
1823 db_multi_exec(
1824 "REPLACE INTO event(type,mtime,objid,user,comment,"
1825 "bgcolor,euser,ecomment,omtime)"
1826
--- src/manifest.c
+++ src/manifest.c
@@ -1187,16 +1187,18 @@
1187 /*
1188 ** Add a single entry to the mlink table. Also add the filename to
1189 ** the filename table if it is not there already.
1190 */
1191 static void add_one_mlink(
1192 int pmid, /* The parent manifest */
1193 const char *zFromUuid, /* UUID for content in parent */
1194 int mid, /* The record ID of the manifest */
1195 const char *zToUuid, /* UUID for content in child */
 
1196 const char *zFilename, /* Filename */
1197 const char *zPrior, /* Previous filename. NULL if unchanged */
1198 int isPublic, /* True if mid is not a private manifest */
1199 int isPrimary, /* pmid is the primary parent of mid */
1200 int mperm /* 1: exec, 2: symlink */
1201 ){
1202 int fnid, pfnid, pid, fid;
1203 static Stmt s1;
1204
@@ -1216,19 +1218,21 @@
1218 }else{
1219 fid = uuid_to_rid(zToUuid, 1);
1220 if( isPublic ) content_make_public(fid);
1221 }
1222 db_static_prepare(&s1,
1223 "INSERT INTO mlink(mid,fid,pmid,pid,fnid,pfnid,mperm,isaux)"
1224 "VALUES(:m,:f,:pm,:p,:n,:pfn,:mp,:isaux)"
1225 );
1226 db_bind_int(&s1, ":m", mid);
 
1227 db_bind_int(&s1, ":f", fid);
1228 db_bind_int(&s1, ":pm", pmid);
1229 db_bind_int(&s1, ":p", pid);
1230 db_bind_int(&s1, ":n", fnid);
1231 db_bind_int(&s1, ":pfn", pfnid);
1232 db_bind_int(&s1, ":mp", mperm);
1233 db_bind_int(&s1, ":isaux", isPrimary==0);
1234 db_exec(&s1);
1235 if( pid && fid ){
1236 content_deltify(pid, fid, 0);
1237 }
1238 }
@@ -1342,24 +1346,29 @@
1346 **
1347 ** Deleted files have mlink.fid=0.
1348 ** Added files have mlink.pid=0.
1349 ** Edited files have both mlink.pid!=0 and mlink.fid!=0
1350 */
1351 static void add_mlink(
1352 int pmid, Manifest *pParent, /* Parent check-in */
1353 int mid, Manifest *pChild, /* The child check-in */
1354 int isPrim /* TRUE if pmid is the primary parent of mid */
1355 ){
1356 Blob otherContent;
1357 int otherRid;
1358 int i, rc;
1359 ManifestFile *pChildFile, *pParentFile;
1360 Manifest **ppOther;
1361 static Stmt eq;
1362 int isPublic; /* True if pChild is non-private */
1363
1364 /* If mlink table entires are already exist for the pmid-to-mid transition,
1365 ** then abort early doing no work.
1366 */
1367 db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid AND pmid=:pmid");
1368 db_bind_int(&eq, ":mid", mid);
1369 db_bind_int(&eq, ":pmid", pmid);
1370 rc = db_step(&eq);
1371 db_reset(&eq);
1372 if( rc==SQLITE_ROW ) return;
1373
1374 /* Compute the value of the missing pParent or pChild parameter.
@@ -1366,14 +1375,14 @@
1375 ** Fetch the baseline checkins for both.
1376 */
1377 assert( pParent==0 || pChild==0 );
1378 if( pParent==0 ){
1379 ppOther = &pParent;
1380 otherRid = pmid;
1381 }else{
1382 ppOther = &pChild;
1383 otherRid = mid;
1384 }
1385 if( (*ppOther = manifest_cache_find(otherRid))==0 ){
1386 content_get(otherRid, &otherContent);
1387 if( blob_size(&otherContent)==0 ) return;
1388 *ppOther = manifest_parse(&otherContent, otherRid, 0);
@@ -1381,20 +1390,20 @@
1390 }
1391 if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){
1392 manifest_destroy(*ppOther);
1393 return;
1394 }
1395 isPublic = !content_is_private(mid);
1396
1397 /* Try to make the parent manifest a delta from the child, if that
1398 ** is an appropriate thing to do. For a new baseline, make the
1399 ** previous baseline a delta from the current baseline.
1400 */
1401 if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){
1402 content_deltify(pmid, mid, 0);
1403 }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){
1404 content_deltify(pParent->pBaseline->rid, mid, 0);
1405 }
1406
1407 /* Remember all children less than a few seconds younger than their parent,
1408 ** as we might want to fudge the times for those children.
1409 */
@@ -1414,31 +1423,32 @@
1423 int mperm = manifest_file_mperm(pChildFile);
1424 if( pChildFile->zPrior ){
1425 pParentFile = manifest_file_seek(pParent, pChildFile->zPrior, 0);
1426 if( pParentFile ){
1427 /* File with name change */
1428 add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid,
1429 pChildFile->zName, pChildFile->zPrior,
1430 isPublic, isPrim, mperm);
1431 }else{
1432 /* File name changed, but the old name is not found in the parent!
1433 ** Treat this like a new file. */
1434 add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0,
1435 isPublic, isPrim, mperm);
1436 }
1437 }else{
1438 pParentFile = manifest_file_seek(pParent, pChildFile->zName, 0);
1439 if( pParentFile==0 ){
1440 if( pChildFile->zUuid ){
1441 /* A new file */
1442 add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0,
1443 isPublic, isPrim, mperm);
1444 }
1445 }else if( fossil_strcmp(pChildFile->zUuid, pParentFile->zUuid)!=0
1446 || manifest_file_mperm(pParentFile)!=mperm ){
1447 /* Changes in file content or permissions */
1448 add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid,
1449 pChildFile->zName, 0, isPublic, isPrim, mperm);
1450 }
1451 }
1452 }
1453 if( pParent->zBaseline && pChild->zBaseline ){
1454 /* Both parent and child are delta manifests. Look for files that
@@ -1450,22 +1460,22 @@
1460 pChildFile = manifest_file_seek_base(pChild, pParentFile->zName, 0);
1461 if( pChildFile==0 ){
1462 /* The child file reverts to baseline. Show this as a change */
1463 pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0);
1464 if( pChildFile ){
1465 add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid,
1466 pChildFile->zName, 0, isPublic, isPrim,
1467 manifest_file_mperm(pChildFile));
1468 }
1469 }
1470 }else{
1471 pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0);
1472 if( pChildFile ){
1473 /* File resurrected in the child after having been deleted in
1474 ** the parent. Show this as an added file. */
1475 add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0,
1476 isPublic, isPrim, manifest_file_mperm(pChildFile));
1477 }
1478 }
1479 }
1480 }else if( pChild->zBaseline==0 ){
1481 /* pChild is a baseline. Look for files that are present in pParent
@@ -1472,12 +1482,12 @@
1482 ** but are missing from pChild and mark them as having been deleted. */
1483 manifest_file_rewind(pParent);
1484 while( (pParentFile = manifest_file_next(pParent,0))!=0 ){
1485 pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0);
1486 if( pChildFile==0 && pParentFile->zUuid!=0 ){
1487 add_one_mlink(pmid, pParentFile->zUuid, mid, 0, pParentFile->zName, 0,
1488 isPublic, isPrim, 0);
1489 }
1490 }
1491 }
1492 manifest_cache_insert(*ppOther);
1493 }
@@ -1781,45 +1791,46 @@
1791 sqlite3_snprintf(sizeof(zBaseId), zBaseId, "%d",
1792 uuid_to_rid(p->zBaseline,1));
1793 }else{
1794 sqlite3_snprintf(sizeof(zBaseId), zBaseId, "NULL");
1795 }
 
1796 for(i=0; i<p->nParent; i++){
1797 int pid = uuid_to_rid(p->azParent[i], 1);
1798 db_multi_exec(
1799 "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)"
1800 "VALUES(%d, %d, %d, %.17g, %s)",
1801 pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/);
1802 add_mlink(pid, 0, rid, p, i);
1803 if( i==0 ) parentid = pid;
1804 }
1805 if( p->nParent>1 ){
1806 /* Remove incorrect MLINK create-file entries that arise when a
1807 ** file is added by merge. */
1808 db_multi_exec(
1809 "DELETE FROM mlink"
1810 " WHERE mid=%d"
1811 " AND pid=0"
1812 " AND fnid IN "
1813 " (SELECT fnid FROM mlink WHERE mid=%d GROUP BY fnid"
1814 " HAVING count(*)<%d)",
1815 rid, rid, p->nParent
1816 );
1817 }
1818 db_prepare(&q, "SELECT cid, isprim FROM plink WHERE pid=%d", rid);
1819 while( db_step(&q)==SQLITE_ROW ){
1820 int cid = db_column_int(&q, 0);
1821 int isprim = db_column_int(&q, 1);
1822 add_mlink(rid, p, cid, 0, isprim);
1823 }
1824 db_finalize(&q);
1825 if( p->nParent==0 ){
1826 /* For root files (files without parents) add mlink entries
1827 ** showing all content as new. */
1828 int isPublic = !content_is_private(rid);
1829 for(i=0; i<p->nFile; i++){
1830 add_one_mlink(0, 0, rid, p->aFile[i].zUuid, p->aFile[i].zName, 0,
1831 isPublic, 1, manifest_file_mperm(&p->aFile[i]));
1832 }
1833 }
1834 db_multi_exec(
1835 "REPLACE INTO event(type,mtime,objid,user,comment,"
1836 "bgcolor,euser,ecomment,omtime)"
1837
+30 -7
--- src/schema.c
+++ src/schema.c
@@ -45,11 +45,14 @@
4545
** we have to execute special procedures to update the schema. When
4646
** the aux schema changes, all we need to do is rebuild the database.
4747
*/
4848
#define CONTENT_SCHEMA "2"
4949
#define AUX_SCHEMA_MIN "2011-04-25 19:50"
50
-#define AUX_SCHEMA_MAX "2014-11-24 20:35"
50
+#define AUX_SCHEMA_MAX "2015-01-24"
51
+/* NB: Some features require the latest schema. Warning or error messages
52
+** will appear if an older schema is used. However, the older schemas are
53
+** adequate for many common functions. */
5154
5255
#endif /* INTERFACE */
5356
5457
5558
/*
@@ -227,21 +230,41 @@
227230
@ name TEXT UNIQUE -- Name of file page
228231
@ );
229232
@
230233
@ -- Linkages between checkins, files created by each checkin, and
231234
@ -- the names of those files.
235
+@ --
236
+@ -- Each entry represents a file that changed content from pid to fid
237
+@ -- due to the check-in that goes from pmid to mid. fnid is the name
238
+@ -- of the file in the mid check-in. If the file was renamed as part
239
+@ -- of the mid check-in, then pfnid is the previous filename.
240
+@
241
+@ -- There can be multiple entries for (mid,fid) if the mid checkin was
242
+@ -- a merge. Entries with isaux==0 are from the primary parent. Merge
243
+@ -- parents have isaux set to true.
244
+@ --
245
+@ -- Field name mnemonics:
246
+@ -- mid = Manifest ID. (Each check-in is stored as a "Manifest")
247
+@ -- fid = File ID.
248
+@ -- pmid = Parent Manifest ID.
249
+@ -- pid = Parent file ID.
250
+@ -- fnid = File Name ID.
251
+@ -- pfnid = Parent File Name ID.
252
+@ -- isaux = pmid IS AUXiliary parent, not primary parent
232253
@ --
233254
@ -- pid==0 if the file is added by checkin mid.
234255
@ -- fid==0 if the file is removed by checkin mid.
235256
@ --
236257
@ CREATE TABLE mlink(
237
-@ mid INTEGER REFERENCES blob, -- Manifest ID where change occurs
238
-@ pid INTEGER REFERENCES blob, -- File ID in parent manifest
239
-@ fid INTEGER REFERENCES blob, -- Changed file ID in this manifest
258
+@ mid INTEGER REFERENCES plink(cid), -- Checkin that contains fid
259
+@ fid INTEGER REFERENCES blob, -- New file content. 0 if deleted
260
+@ pmid INTEGER REFERENCES plink(cid), -- Checkin that contains pid
261
+@ pid INTEGER REFERENCES blob, -- Prev file content. 0 if new
240262
@ fnid INTEGER REFERENCES filename, -- Name of the file
241263
@ pfnid INTEGER REFERENCES filename, -- Previous name. 0 if unchanged
242
-@ mperm INTEGER -- File permissions. 1==exec
264
+@ mperm INTEGER, -- File permissions. 1==exec
265
+@ isaux BOOLEAN DEFAULT 0 -- TRUE if pmid is the primary
243266
@ );
244267
@ CREATE INDEX mlink_i1 ON mlink(mid);
245268
@ CREATE INDEX mlink_i2 ON mlink(fnid);
246269
@ CREATE INDEX mlink_i3 ON mlink(fid);
247270
@ CREATE INDEX mlink_i4 ON mlink(pid);
@@ -251,11 +274,11 @@
251274
@ CREATE TABLE plink(
252275
@ pid INTEGER REFERENCES blob, -- Parent manifest
253276
@ cid INTEGER REFERENCES blob, -- Child manifest
254277
@ isprim BOOLEAN, -- pid is the primary parent of cid
255278
@ mtime DATETIME, -- the date/time stamp on cid. Julian day.
256
-@ baseid INTEGER REFERENCES blob, -- Baseline if child is a delta manifest
279
+@ baseid INTEGER REFERENCES blob, -- Baseline if cid is a delta manifest.
257280
@ UNIQUE(pid, cid)
258281
@ );
259282
@ CREATE INDEX plink_i2 ON plink(cid,pid);
260283
@
261284
@ -- A "leaf" checkin is a checkin that has no children in the same
@@ -488,11 +511,11 @@
488511
@ -- current version of the file is already in the repository.
489512
@ --
490513
@ CREATE TABLE vfile(
491514
@ id INTEGER PRIMARY KEY, -- ID of the checked out file
492515
@ vid INTEGER REFERENCES blob, -- The baseline this file is part of.
493
-@ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add 4:i-chng 5:i-add
516
+@ chnged INT DEFAULT 0, -- 0:unchng 1:edit 2:m-chng 3:m-add 4:i-chng 5:i-add
494517
@ deleted BOOLEAN DEFAULT 0, -- True if deleted
495518
@ isexe BOOLEAN, -- True if file should be executable
496519
@ islink BOOLEAN, -- True if file should be symlink
497520
@ rid INTEGER, -- Originally from this repository record
498521
@ mrid INTEGER, -- Based on this record due to a merge
499522
--- src/schema.c
+++ src/schema.c
@@ -45,11 +45,14 @@
45 ** we have to execute special procedures to update the schema. When
46 ** the aux schema changes, all we need to do is rebuild the database.
47 */
48 #define CONTENT_SCHEMA "2"
49 #define AUX_SCHEMA_MIN "2011-04-25 19:50"
50 #define AUX_SCHEMA_MAX "2014-11-24 20:35"
 
 
 
51
52 #endif /* INTERFACE */
53
54
55 /*
@@ -227,21 +230,41 @@
227 @ name TEXT UNIQUE -- Name of file page
228 @ );
229 @
230 @ -- Linkages between checkins, files created by each checkin, and
231 @ -- the names of those files.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232 @ --
233 @ -- pid==0 if the file is added by checkin mid.
234 @ -- fid==0 if the file is removed by checkin mid.
235 @ --
236 @ CREATE TABLE mlink(
237 @ mid INTEGER REFERENCES blob, -- Manifest ID where change occurs
238 @ pid INTEGER REFERENCES blob, -- File ID in parent manifest
239 @ fid INTEGER REFERENCES blob, -- Changed file ID in this manifest
 
240 @ fnid INTEGER REFERENCES filename, -- Name of the file
241 @ pfnid INTEGER REFERENCES filename, -- Previous name. 0 if unchanged
242 @ mperm INTEGER -- File permissions. 1==exec
 
243 @ );
244 @ CREATE INDEX mlink_i1 ON mlink(mid);
245 @ CREATE INDEX mlink_i2 ON mlink(fnid);
246 @ CREATE INDEX mlink_i3 ON mlink(fid);
247 @ CREATE INDEX mlink_i4 ON mlink(pid);
@@ -251,11 +274,11 @@
251 @ CREATE TABLE plink(
252 @ pid INTEGER REFERENCES blob, -- Parent manifest
253 @ cid INTEGER REFERENCES blob, -- Child manifest
254 @ isprim BOOLEAN, -- pid is the primary parent of cid
255 @ mtime DATETIME, -- the date/time stamp on cid. Julian day.
256 @ baseid INTEGER REFERENCES blob, -- Baseline if child is a delta manifest
257 @ UNIQUE(pid, cid)
258 @ );
259 @ CREATE INDEX plink_i2 ON plink(cid,pid);
260 @
261 @ -- A "leaf" checkin is a checkin that has no children in the same
@@ -488,11 +511,11 @@
488 @ -- current version of the file is already in the repository.
489 @ --
490 @ CREATE TABLE vfile(
491 @ id INTEGER PRIMARY KEY, -- ID of the checked out file
492 @ vid INTEGER REFERENCES blob, -- The baseline this file is part of.
493 @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add 4:i-chng 5:i-add
494 @ deleted BOOLEAN DEFAULT 0, -- True if deleted
495 @ isexe BOOLEAN, -- True if file should be executable
496 @ islink BOOLEAN, -- True if file should be symlink
497 @ rid INTEGER, -- Originally from this repository record
498 @ mrid INTEGER, -- Based on this record due to a merge
499
--- src/schema.c
+++ src/schema.c
@@ -45,11 +45,14 @@
45 ** we have to execute special procedures to update the schema. When
46 ** the aux schema changes, all we need to do is rebuild the database.
47 */
48 #define CONTENT_SCHEMA "2"
49 #define AUX_SCHEMA_MIN "2011-04-25 19:50"
50 #define AUX_SCHEMA_MAX "2015-01-24"
51 /* NB: Some features require the latest schema. Warning or error messages
52 ** will appear if an older schema is used. However, the older schemas are
53 ** adequate for many common functions. */
54
55 #endif /* INTERFACE */
56
57
58 /*
@@ -227,21 +230,41 @@
230 @ name TEXT UNIQUE -- Name of file page
231 @ );
232 @
233 @ -- Linkages between checkins, files created by each checkin, and
234 @ -- the names of those files.
235 @ --
236 @ -- Each entry represents a file that changed content from pid to fid
237 @ -- due to the check-in that goes from pmid to mid. fnid is the name
238 @ -- of the file in the mid check-in. If the file was renamed as part
239 @ -- of the mid check-in, then pfnid is the previous filename.
240 @
241 @ -- There can be multiple entries for (mid,fid) if the mid checkin was
242 @ -- a merge. Entries with isaux==0 are from the primary parent. Merge
243 @ -- parents have isaux set to true.
244 @ --
245 @ -- Field name mnemonics:
246 @ -- mid = Manifest ID. (Each check-in is stored as a "Manifest")
247 @ -- fid = File ID.
248 @ -- pmid = Parent Manifest ID.
249 @ -- pid = Parent file ID.
250 @ -- fnid = File Name ID.
251 @ -- pfnid = Parent File Name ID.
252 @ -- isaux = pmid IS AUXiliary parent, not primary parent
253 @ --
254 @ -- pid==0 if the file is added by checkin mid.
255 @ -- fid==0 if the file is removed by checkin mid.
256 @ --
257 @ CREATE TABLE mlink(
258 @ mid INTEGER REFERENCES plink(cid), -- Checkin that contains fid
259 @ fid INTEGER REFERENCES blob, -- New file content. 0 if deleted
260 @ pmid INTEGER REFERENCES plink(cid), -- Checkin that contains pid
261 @ pid INTEGER REFERENCES blob, -- Prev file content. 0 if new
262 @ fnid INTEGER REFERENCES filename, -- Name of the file
263 @ pfnid INTEGER REFERENCES filename, -- Previous name. 0 if unchanged
264 @ mperm INTEGER, -- File permissions. 1==exec
265 @ isaux BOOLEAN DEFAULT 0 -- TRUE if pmid is the primary
266 @ );
267 @ CREATE INDEX mlink_i1 ON mlink(mid);
268 @ CREATE INDEX mlink_i2 ON mlink(fnid);
269 @ CREATE INDEX mlink_i3 ON mlink(fid);
270 @ CREATE INDEX mlink_i4 ON mlink(pid);
@@ -251,11 +274,11 @@
274 @ CREATE TABLE plink(
275 @ pid INTEGER REFERENCES blob, -- Parent manifest
276 @ cid INTEGER REFERENCES blob, -- Child manifest
277 @ isprim BOOLEAN, -- pid is the primary parent of cid
278 @ mtime DATETIME, -- the date/time stamp on cid. Julian day.
279 @ baseid INTEGER REFERENCES blob, -- Baseline if cid is a delta manifest.
280 @ UNIQUE(pid, cid)
281 @ );
282 @ CREATE INDEX plink_i2 ON plink(cid,pid);
283 @
284 @ -- A "leaf" checkin is a checkin that has no children in the same
@@ -488,11 +511,11 @@
511 @ -- current version of the file is already in the repository.
512 @ --
513 @ CREATE TABLE vfile(
514 @ id INTEGER PRIMARY KEY, -- ID of the checked out file
515 @ vid INTEGER REFERENCES blob, -- The baseline this file is part of.
516 @ chnged INT DEFAULT 0, -- 0:unchng 1:edit 2:m-chng 3:m-add 4:i-chng 5:i-add
517 @ deleted BOOLEAN DEFAULT 0, -- True if deleted
518 @ isexe BOOLEAN, -- True if file should be executable
519 @ islink BOOLEAN, -- True if file should be symlink
520 @ rid INTEGER, -- Originally from this repository record
521 @ mrid INTEGER, -- Based on this record due to a merge
522
+2 -2
--- src/timeline.c
+++ src/timeline.c
@@ -360,20 +360,20 @@
360360
}
361361
}
362362
}
363363
if( zType[0]=='c' && (pGraph || (tmFlags & TIMELINE_BRCOLOR)!=0) ){
364364
int nParent = 0;
365
- int aParent[32];
365
+ int aParent[GR_MAX_RAIL];
366366
int gidx;
367367
static Stmt qparent;
368368
db_static_prepare(&qparent,
369369
"SELECT pid FROM plink"
370370
" WHERE cid=:rid AND pid NOT IN phantom"
371371
" ORDER BY isprim DESC /*sort*/"
372372
);
373373
db_bind_int(&qparent, ":rid", rid);
374
- while( db_step(&qparent)==SQLITE_ROW && nParent<32 ){
374
+ while( db_step(&qparent)==SQLITE_ROW && nParent<ArraySize(aParent) ){
375375
aParent[nParent++] = db_column_int(&qparent, 0);
376376
}
377377
db_reset(&qparent);
378378
gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr,
379379
zUuid, isLeaf);
380380
--- src/timeline.c
+++ src/timeline.c
@@ -360,20 +360,20 @@
360 }
361 }
362 }
363 if( zType[0]=='c' && (pGraph || (tmFlags & TIMELINE_BRCOLOR)!=0) ){
364 int nParent = 0;
365 int aParent[32];
366 int gidx;
367 static Stmt qparent;
368 db_static_prepare(&qparent,
369 "SELECT pid FROM plink"
370 " WHERE cid=:rid AND pid NOT IN phantom"
371 " ORDER BY isprim DESC /*sort*/"
372 );
373 db_bind_int(&qparent, ":rid", rid);
374 while( db_step(&qparent)==SQLITE_ROW && nParent<32 ){
375 aParent[nParent++] = db_column_int(&qparent, 0);
376 }
377 db_reset(&qparent);
378 gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr,
379 zUuid, isLeaf);
380
--- src/timeline.c
+++ src/timeline.c
@@ -360,20 +360,20 @@
360 }
361 }
362 }
363 if( zType[0]=='c' && (pGraph || (tmFlags & TIMELINE_BRCOLOR)!=0) ){
364 int nParent = 0;
365 int aParent[GR_MAX_RAIL];
366 int gidx;
367 static Stmt qparent;
368 db_static_prepare(&qparent,
369 "SELECT pid FROM plink"
370 " WHERE cid=:rid AND pid NOT IN phantom"
371 " ORDER BY isprim DESC /*sort*/"
372 );
373 db_bind_int(&qparent, ":rid", rid);
374 while( db_step(&qparent)==SQLITE_ROW && nParent<ArraySize(aParent) ){
375 aParent[nParent++] = db_column_int(&qparent, 0);
376 }
377 db_reset(&qparent);
378 gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr,
379 zUuid, isLeaf);
380

Keyboard Shortcuts

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