Fossil SCM
Improvements to the way mlink is computed. Some unnecessary mlink entries are suppressed. Running "fossil rebuild" is recommended.
Commit
e2c53534b59487b1fceb850f8cfe5f791fe8dfe8
Parent
9a8d082701b4a21…
2 files changed
+22
-19
+67
-15
+22
-19
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -592,12 +592,13 @@ | ||
| 592 | 592 | /* 1 */ " (SELECT uuid FROM blob WHERE rid=mlink.mid)," |
| 593 | 593 | /* 2 */ " (SELECT uuid FROM blob WHERE rid=mlink.pmid)," |
| 594 | 594 | /* 3 */ " isaux," |
| 595 | 595 | /* 4 */ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 596 | 596 | /* 5 */ " (SELECT uuid FROM blob WHERE rid=mlink.pid)," |
| 597 | - /* 6 */ " mperm," | |
| 598 | - /* 7 */ " (SELECT name FROM filename WHERE fnid=mlink.pfnid)" | |
| 597 | + /* 6 */ " mlink.pid," | |
| 598 | + /* 7 */ " mperm," | |
| 599 | + /* 8 */ " (SELECT name FROM filename WHERE fnid=mlink.pfnid)" | |
| 599 | 600 | " FROM mlink, event" |
| 600 | 601 | " WHERE mlink.fnid=%d" |
| 601 | 602 | " AND event.objid=mlink.mid" |
| 602 | 603 | " ORDER BY 1 DESC", |
| 603 | 604 | fnid |
| @@ -622,12 +623,12 @@ | ||
| 622 | 623 | const char *zCkin = db_column_text(&q,1); |
| 623 | 624 | const char *zParent = db_column_text(&q,2); |
| 624 | 625 | int isMerge = db_column_int(&q,3); |
| 625 | 626 | const char *zFid = db_column_text(&q,4); |
| 626 | 627 | const char *zPid = db_column_text(&q,5); |
| 627 | - int isExe = db_column_int(&q,6); | |
| 628 | - const char *zPrior = db_column_text(&q,7); | |
| 628 | + int isExe = db_column_int(&q,7); | |
| 629 | + const char *zPrior = db_column_text(&q,8); | |
| 629 | 630 | @ <tr> |
| 630 | 631 | @ <td><a href='%R/timeline?c=%!S(zCkin)'>%s(zDate)</a></td> |
| 631 | 632 | @ <td><a href='%R/info/%!S(zCkin)'>%S(zCkin)</a></td> |
| 632 | 633 | if( zParent ){ |
| 633 | 634 | @ <td><a href='%R/info/%!S(zPid)'>%S(zParent)</a></td> |
| @@ -640,10 +641,12 @@ | ||
| 640 | 641 | }else{ |
| 641 | 642 | @ <td><i>(Deleted)</i></td> |
| 642 | 643 | } |
| 643 | 644 | if( zPid ){ |
| 644 | 645 | @ <td><a href='%R/info/%!S(zPid)'>%S(zPid)</a> |
| 646 | + }else if( db_column_int(&q,6)<0 ){ | |
| 647 | + @ <td><i>(Added by merge)</i></td> | |
| 645 | 648 | }else{ |
| 646 | 649 | @ <td><i>(New)</i></td> |
| 647 | 650 | } |
| 648 | 651 | @ <td align='center'>%s(isExe?"✓":"")</td> |
| 649 | 652 | if( zPrior ){ |
| @@ -661,19 +664,17 @@ | ||
| 661 | 664 | }else{ |
| 662 | 665 | int mid = name_to_rid_www("ci"); |
| 663 | 666 | db_prepare(&q, |
| 664 | 667 | "SELECT" |
| 665 | 668 | /* 0 */ " (SELECT name FROM filename WHERE fnid=mlink.fnid)," |
| 666 | - /* 1 */ " fid," | |
| 667 | - /* 2 */ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," | |
| 668 | - /* 3 */ " pid," | |
| 669 | - /* 4 */ " (SELECT uuid FROM blob WHERE rid=mlink.pid)," | |
| 670 | - /* 5 */ " (SELECT name FROM filename WHERE fnid=mlink.pfnid)," | |
| 671 | - /* 6 */ " pmid," | |
| 672 | - /* 7 */ " (SELECT uuid FROM blob WHERE rid=mlink.pmid)," | |
| 673 | - /* 8 */ " mperm," | |
| 674 | - /* 9 */ " isaux" | |
| 669 | + /* 1 */ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," | |
| 670 | + /* 2 */ " pid," | |
| 671 | + /* 3 */ " (SELECT uuid FROM blob WHERE rid=mlink.pid)," | |
| 672 | + /* 4 */ " (SELECT name FROM filename WHERE fnid=mlink.pfnid)," | |
| 673 | + /* 5 */ " (SELECT uuid FROM blob WHERE rid=mlink.pmid)," | |
| 674 | + /* 6 */ " mperm," | |
| 675 | + /* 7 */ " isaux" | |
| 675 | 676 | " FROM mlink WHERE mid=%d ORDER BY 1", |
| 676 | 677 | mid |
| 677 | 678 | ); |
| 678 | 679 | @ <h1>MLINK table for check-in %h(zCI)</h1> |
| 679 | 680 | render_checkin_context(mid, 1); |
| @@ -690,16 +691,16 @@ | ||
| 690 | 691 | @ <th>Prior Name</th> |
| 691 | 692 | @ </tr></thead> |
| 692 | 693 | @ <tbody> |
| 693 | 694 | while( db_step(&q)==SQLITE_ROW ){ |
| 694 | 695 | const char *zName = db_column_text(&q,0); |
| 695 | - const char *zFid = db_column_text(&q,2); | |
| 696 | - const char *zPid = db_column_text(&q,4); | |
| 697 | - const char *zParent = db_column_text(&q,7); | |
| 698 | - const char *zPrior = db_column_text(&q,5); | |
| 699 | - int isExec = db_column_int(&q,8); | |
| 700 | - int isAux = db_column_int(&q,9); | |
| 696 | + const char *zFid = db_column_text(&q,1); | |
| 697 | + const char *zPid = db_column_text(&q,3); | |
| 698 | + const char *zPrior = db_column_text(&q,4); | |
| 699 | + const char *zParent = db_column_text(&q,5); | |
| 700 | + int isExec = db_column_int(&q,6); | |
| 701 | + int isAux = db_column_int(&q,7); | |
| 701 | 702 | @ <tr> |
| 702 | 703 | @ <td><a href='%R/finfo?name=%t(zName)'>%h(zName)</a></td> |
| 703 | 704 | if( zParent ){ |
| 704 | 705 | @ <td><a href='%R/info/%!S(zPid)'>%S(zParent)</a></td> |
| 705 | 706 | }else{ |
| @@ -711,10 +712,12 @@ | ||
| 711 | 712 | }else{ |
| 712 | 713 | @ <td><i>(Deleted)</i></td> |
| 713 | 714 | } |
| 714 | 715 | if( zPid ){ |
| 715 | 716 | @ <td><a href='%R/info/%!S(zPid)'>%S(zPid)</a> |
| 717 | + }else if( db_column_int(&q,2)<0 ){ | |
| 718 | + @ <td><i>(Added by merge)</i></td> | |
| 716 | 719 | }else{ |
| 717 | 720 | @ <td><i>(New)</i></td> |
| 718 | 721 | } |
| 719 | 722 | @ <td align='center'>%s(isExec?"✓":"")</td> |
| 720 | 723 | if( zPrior ){ |
| 721 | 724 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -592,12 +592,13 @@ | |
| 592 | /* 1 */ " (SELECT uuid FROM blob WHERE rid=mlink.mid)," |
| 593 | /* 2 */ " (SELECT uuid FROM blob WHERE rid=mlink.pmid)," |
| 594 | /* 3 */ " isaux," |
| 595 | /* 4 */ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 596 | /* 5 */ " (SELECT uuid FROM blob WHERE rid=mlink.pid)," |
| 597 | /* 6 */ " mperm," |
| 598 | /* 7 */ " (SELECT name FROM filename WHERE fnid=mlink.pfnid)" |
| 599 | " FROM mlink, event" |
| 600 | " WHERE mlink.fnid=%d" |
| 601 | " AND event.objid=mlink.mid" |
| 602 | " ORDER BY 1 DESC", |
| 603 | fnid |
| @@ -622,12 +623,12 @@ | |
| 622 | const char *zCkin = db_column_text(&q,1); |
| 623 | const char *zParent = db_column_text(&q,2); |
| 624 | int isMerge = db_column_int(&q,3); |
| 625 | const char *zFid = db_column_text(&q,4); |
| 626 | const char *zPid = db_column_text(&q,5); |
| 627 | int isExe = db_column_int(&q,6); |
| 628 | const char *zPrior = db_column_text(&q,7); |
| 629 | @ <tr> |
| 630 | @ <td><a href='%R/timeline?c=%!S(zCkin)'>%s(zDate)</a></td> |
| 631 | @ <td><a href='%R/info/%!S(zCkin)'>%S(zCkin)</a></td> |
| 632 | if( zParent ){ |
| 633 | @ <td><a href='%R/info/%!S(zPid)'>%S(zParent)</a></td> |
| @@ -640,10 +641,12 @@ | |
| 640 | }else{ |
| 641 | @ <td><i>(Deleted)</i></td> |
| 642 | } |
| 643 | if( zPid ){ |
| 644 | @ <td><a href='%R/info/%!S(zPid)'>%S(zPid)</a> |
| 645 | }else{ |
| 646 | @ <td><i>(New)</i></td> |
| 647 | } |
| 648 | @ <td align='center'>%s(isExe?"✓":"")</td> |
| 649 | if( zPrior ){ |
| @@ -661,19 +664,17 @@ | |
| 661 | }else{ |
| 662 | int mid = name_to_rid_www("ci"); |
| 663 | db_prepare(&q, |
| 664 | "SELECT" |
| 665 | /* 0 */ " (SELECT name FROM filename WHERE fnid=mlink.fnid)," |
| 666 | /* 1 */ " fid," |
| 667 | /* 2 */ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 668 | /* 3 */ " pid," |
| 669 | /* 4 */ " (SELECT uuid FROM blob WHERE rid=mlink.pid)," |
| 670 | /* 5 */ " (SELECT name FROM filename WHERE fnid=mlink.pfnid)," |
| 671 | /* 6 */ " pmid," |
| 672 | /* 7 */ " (SELECT uuid FROM blob WHERE rid=mlink.pmid)," |
| 673 | /* 8 */ " mperm," |
| 674 | /* 9 */ " isaux" |
| 675 | " FROM mlink WHERE mid=%d ORDER BY 1", |
| 676 | mid |
| 677 | ); |
| 678 | @ <h1>MLINK table for check-in %h(zCI)</h1> |
| 679 | render_checkin_context(mid, 1); |
| @@ -690,16 +691,16 @@ | |
| 690 | @ <th>Prior Name</th> |
| 691 | @ </tr></thead> |
| 692 | @ <tbody> |
| 693 | while( db_step(&q)==SQLITE_ROW ){ |
| 694 | const char *zName = db_column_text(&q,0); |
| 695 | const char *zFid = db_column_text(&q,2); |
| 696 | const char *zPid = db_column_text(&q,4); |
| 697 | const char *zParent = db_column_text(&q,7); |
| 698 | const char *zPrior = db_column_text(&q,5); |
| 699 | int isExec = db_column_int(&q,8); |
| 700 | int isAux = db_column_int(&q,9); |
| 701 | @ <tr> |
| 702 | @ <td><a href='%R/finfo?name=%t(zName)'>%h(zName)</a></td> |
| 703 | if( zParent ){ |
| 704 | @ <td><a href='%R/info/%!S(zPid)'>%S(zParent)</a></td> |
| 705 | }else{ |
| @@ -711,10 +712,12 @@ | |
| 711 | }else{ |
| 712 | @ <td><i>(Deleted)</i></td> |
| 713 | } |
| 714 | if( zPid ){ |
| 715 | @ <td><a href='%R/info/%!S(zPid)'>%S(zPid)</a> |
| 716 | }else{ |
| 717 | @ <td><i>(New)</i></td> |
| 718 | } |
| 719 | @ <td align='center'>%s(isExec?"✓":"")</td> |
| 720 | if( zPrior ){ |
| 721 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -592,12 +592,13 @@ | |
| 592 | /* 1 */ " (SELECT uuid FROM blob WHERE rid=mlink.mid)," |
| 593 | /* 2 */ " (SELECT uuid FROM blob WHERE rid=mlink.pmid)," |
| 594 | /* 3 */ " isaux," |
| 595 | /* 4 */ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 596 | /* 5 */ " (SELECT uuid FROM blob WHERE rid=mlink.pid)," |
| 597 | /* 6 */ " mlink.pid," |
| 598 | /* 7 */ " mperm," |
| 599 | /* 8 */ " (SELECT name FROM filename WHERE fnid=mlink.pfnid)" |
| 600 | " FROM mlink, event" |
| 601 | " WHERE mlink.fnid=%d" |
| 602 | " AND event.objid=mlink.mid" |
| 603 | " ORDER BY 1 DESC", |
| 604 | fnid |
| @@ -622,12 +623,12 @@ | |
| 623 | const char *zCkin = db_column_text(&q,1); |
| 624 | const char *zParent = db_column_text(&q,2); |
| 625 | int isMerge = db_column_int(&q,3); |
| 626 | const char *zFid = db_column_text(&q,4); |
| 627 | const char *zPid = db_column_text(&q,5); |
| 628 | int isExe = db_column_int(&q,7); |
| 629 | const char *zPrior = db_column_text(&q,8); |
| 630 | @ <tr> |
| 631 | @ <td><a href='%R/timeline?c=%!S(zCkin)'>%s(zDate)</a></td> |
| 632 | @ <td><a href='%R/info/%!S(zCkin)'>%S(zCkin)</a></td> |
| 633 | if( zParent ){ |
| 634 | @ <td><a href='%R/info/%!S(zPid)'>%S(zParent)</a></td> |
| @@ -640,10 +641,12 @@ | |
| 641 | }else{ |
| 642 | @ <td><i>(Deleted)</i></td> |
| 643 | } |
| 644 | if( zPid ){ |
| 645 | @ <td><a href='%R/info/%!S(zPid)'>%S(zPid)</a> |
| 646 | }else if( db_column_int(&q,6)<0 ){ |
| 647 | @ <td><i>(Added by merge)</i></td> |
| 648 | }else{ |
| 649 | @ <td><i>(New)</i></td> |
| 650 | } |
| 651 | @ <td align='center'>%s(isExe?"✓":"")</td> |
| 652 | if( zPrior ){ |
| @@ -661,19 +664,17 @@ | |
| 664 | }else{ |
| 665 | int mid = name_to_rid_www("ci"); |
| 666 | db_prepare(&q, |
| 667 | "SELECT" |
| 668 | /* 0 */ " (SELECT name FROM filename WHERE fnid=mlink.fnid)," |
| 669 | /* 1 */ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 670 | /* 2 */ " pid," |
| 671 | /* 3 */ " (SELECT uuid FROM blob WHERE rid=mlink.pid)," |
| 672 | /* 4 */ " (SELECT name FROM filename WHERE fnid=mlink.pfnid)," |
| 673 | /* 5 */ " (SELECT uuid FROM blob WHERE rid=mlink.pmid)," |
| 674 | /* 6 */ " mperm," |
| 675 | /* 7 */ " isaux" |
| 676 | " FROM mlink WHERE mid=%d ORDER BY 1", |
| 677 | mid |
| 678 | ); |
| 679 | @ <h1>MLINK table for check-in %h(zCI)</h1> |
| 680 | render_checkin_context(mid, 1); |
| @@ -690,16 +691,16 @@ | |
| 691 | @ <th>Prior Name</th> |
| 692 | @ </tr></thead> |
| 693 | @ <tbody> |
| 694 | while( db_step(&q)==SQLITE_ROW ){ |
| 695 | const char *zName = db_column_text(&q,0); |
| 696 | const char *zFid = db_column_text(&q,1); |
| 697 | const char *zPid = db_column_text(&q,3); |
| 698 | const char *zPrior = db_column_text(&q,4); |
| 699 | const char *zParent = db_column_text(&q,5); |
| 700 | int isExec = db_column_int(&q,6); |
| 701 | int isAux = db_column_int(&q,7); |
| 702 | @ <tr> |
| 703 | @ <td><a href='%R/finfo?name=%t(zName)'>%h(zName)</a></td> |
| 704 | if( zParent ){ |
| 705 | @ <td><a href='%R/info/%!S(zPid)'>%S(zParent)</a></td> |
| 706 | }else{ |
| @@ -711,10 +712,12 @@ | |
| 712 | }else{ |
| 713 | @ <td><i>(Deleted)</i></td> |
| 714 | } |
| 715 | if( zPid ){ |
| 716 | @ <td><a href='%R/info/%!S(zPid)'>%S(zPid)</a> |
| 717 | }else if( db_column_int(&q,2)<0 ){ |
| 718 | @ <td><i>(Added by merge)</i></td> |
| 719 | }else{ |
| 720 | @ <td><i>(New)</i></td> |
| 721 | } |
| 722 | @ <td align='center'>%s(isExec?"✓":"")</td> |
| 723 | if( zPrior ){ |
| 724 |
+67
-15
| --- src/manifest.c | ||
| +++ src/manifest.c | ||
| @@ -1185,10 +1185,15 @@ | ||
| 1185 | 1185 | } |
| 1186 | 1186 | |
| 1187 | 1187 | /* |
| 1188 | 1188 | ** Add a single entry to the mlink table. Also add the filename to |
| 1189 | 1189 | ** the filename table if it is not there already. |
| 1190 | +** | |
| 1191 | +** An mlink entry is always created if isPrimary is true. But if | |
| 1192 | +** isPrimary is false (meaning that pmid is a merge parent of mid) | |
| 1193 | +** then the mlink entry is only created if there is already an mlink | |
| 1194 | +** from primary parent for the same file. | |
| 1190 | 1195 | */ |
| 1191 | 1196 | static void add_one_mlink( |
| 1192 | 1197 | int pmid, /* The parent manifest */ |
| 1193 | 1198 | const char *zFromUuid, /* UUID for content in parent */ |
| 1194 | 1199 | int mid, /* The record ID of the manifest */ |
| @@ -1198,11 +1203,12 @@ | ||
| 1198 | 1203 | int isPublic, /* True if mid is not a private manifest */ |
| 1199 | 1204 | int isPrimary, /* pmid is the primary parent of mid */ |
| 1200 | 1205 | int mperm /* 1: exec, 2: symlink */ |
| 1201 | 1206 | ){ |
| 1202 | 1207 | int fnid, pfnid, pid, fid; |
| 1203 | - static Stmt s1; | |
| 1208 | + int doInsert; | |
| 1209 | + static Stmt s1, s2; | |
| 1204 | 1210 | |
| 1205 | 1211 | fnid = filename_to_fnid(zFilename); |
| 1206 | 1212 | if( zPrior==0 ){ |
| 1207 | 1213 | pfnid = 0; |
| 1208 | 1214 | }else{ |
| @@ -1217,23 +1223,36 @@ | ||
| 1217 | 1223 | fid = 0; |
| 1218 | 1224 | }else{ |
| 1219 | 1225 | fid = uuid_to_rid(zToUuid, 1); |
| 1220 | 1226 | if( isPublic ) content_make_public(fid); |
| 1221 | 1227 | } |
| 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); | |
| 1228 | + if( isPrimary ){ | |
| 1229 | + doInsert = 1; | |
| 1230 | + }else{ | |
| 1231 | + db_static_prepare(&s2, | |
| 1232 | + "SELECT 1 FROM mlink WHERE mid=:m AND fnid=:n AND NOT isaux" | |
| 1233 | + ); | |
| 1234 | + db_bind_int(&s2, ":m", mid); | |
| 1235 | + db_bind_int(&s2, ":n", fnid); | |
| 1236 | + doInsert = db_step(&s2)==SQLITE_ROW; | |
| 1237 | + db_reset(&s2); | |
| 1238 | + } | |
| 1239 | + if( doInsert ){ | |
| 1240 | + db_static_prepare(&s1, | |
| 1241 | + "INSERT INTO mlink(mid,fid,pmid,pid,fnid,pfnid,mperm,isaux)" | |
| 1242 | + "VALUES(:m,:f,:pm,:p,:n,:pfn,:mp,:isaux)" | |
| 1243 | + ); | |
| 1244 | + db_bind_int(&s1, ":m", mid); | |
| 1245 | + db_bind_int(&s1, ":f", fid); | |
| 1246 | + db_bind_int(&s1, ":pm", pmid); | |
| 1247 | + db_bind_int(&s1, ":p", pid); | |
| 1248 | + db_bind_int(&s1, ":n", fnid); | |
| 1249 | + db_bind_int(&s1, ":pfn", pfnid); | |
| 1250 | + db_bind_int(&s1, ":mp", mperm); | |
| 1251 | + db_bind_int(&s1, ":isaux", isPrimary==0); | |
| 1252 | + db_exec(&s1); | |
| 1253 | + } | |
| 1235 | 1254 | if( pid && fid ){ |
| 1236 | 1255 | content_deltify(pid, fid, 0); |
| 1237 | 1256 | } |
| 1238 | 1257 | } |
| 1239 | 1258 | |
| @@ -1346,10 +1365,19 @@ | ||
| 1346 | 1365 | ** |
| 1347 | 1366 | ** Deleted files have mlink.fid=0. |
| 1348 | 1367 | ** Added files have mlink.pid=0. |
| 1349 | 1368 | ** File added by merge have mlink.pid=-1 |
| 1350 | 1369 | ** Edited files have both mlink.pid!=0 and mlink.fid!=0 |
| 1370 | +** | |
| 1371 | +** Many mlink entries for merge parents will only be added if another mlink | |
| 1372 | +** entry already exists for the same file from the primary parent. Therefore, | |
| 1373 | +** to ensure that all merge-parent mlink entries are properly created: | |
| 1374 | +** | |
| 1375 | +** (1) Make this routine a no-op if pParent is a merge parent and the | |
| 1376 | +** primary parent is a phantom. | |
| 1377 | +** (2) Invoke this routine recursively for merge-parents if pParent is the | |
| 1378 | +** primary parent. | |
| 1351 | 1379 | */ |
| 1352 | 1380 | static void add_mlink( |
| 1353 | 1381 | int pmid, Manifest *pParent, /* Parent check-in */ |
| 1354 | 1382 | int mid, Manifest *pChild, /* The child check-in */ |
| 1355 | 1383 | int isPrim /* TRUE if pmid is the primary parent of mid */ |
| @@ -1392,10 +1420,23 @@ | ||
| 1392 | 1420 | if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){ |
| 1393 | 1421 | manifest_destroy(*ppOther); |
| 1394 | 1422 | return; |
| 1395 | 1423 | } |
| 1396 | 1424 | isPublic = !content_is_private(mid); |
| 1425 | + | |
| 1426 | + /* If pParent is not the primary parent of pChild, and the primary | |
| 1427 | + ** parent of pChild is a phantom, then abort this routine without | |
| 1428 | + ** doing any work. The mlink entries will be computed when the | |
| 1429 | + ** primary parent dephantomizes. | |
| 1430 | + */ | |
| 1431 | + if( !isPrim && otherRid==mid | |
| 1432 | + && !db_exists("SELECT 1 FROM blob WHERE uuid=%Q AND size>0", | |
| 1433 | + pChild->azParent[0]) | |
| 1434 | + ){ | |
| 1435 | + manifest_cache_insert(*ppOther); | |
| 1436 | + return; | |
| 1437 | + } | |
| 1397 | 1438 | |
| 1398 | 1439 | /* Try to make the parent manifest a delta from the child, if that |
| 1399 | 1440 | ** is an appropriate thing to do. For a new baseline, make the |
| 1400 | 1441 | ** previous baseline a delta from the current baseline. |
| 1401 | 1442 | */ |
| @@ -1489,10 +1530,21 @@ | ||
| 1489 | 1530 | isPublic, isPrim, 0); |
| 1490 | 1531 | } |
| 1491 | 1532 | } |
| 1492 | 1533 | } |
| 1493 | 1534 | manifest_cache_insert(*ppOther); |
| 1535 | + | |
| 1536 | + /* If pParent is the primary parent of pChild, also run this analysis | |
| 1537 | + ** for all merge parents of pChild | |
| 1538 | + */ | |
| 1539 | + if( isPrim ){ | |
| 1540 | + for(i=1; i<pChild->nParent; i++){ | |
| 1541 | + pmid = uuid_to_rid(pChild->azParent[i], 0); | |
| 1542 | + if( pmid<=0 ) continue; | |
| 1543 | + add_mlink(pmid, 0, mid, pChild, 0); | |
| 1544 | + } | |
| 1545 | + } | |
| 1494 | 1546 | } |
| 1495 | 1547 | |
| 1496 | 1548 | /* |
| 1497 | 1549 | ** Setup to do multiple manifest_crosslink() calls. |
| 1498 | 1550 | ** This is only required if processing ticket changes. |
| @@ -1798,13 +1850,13 @@ | ||
| 1798 | 1850 | int pid = uuid_to_rid(p->azParent[i], 1); |
| 1799 | 1851 | db_multi_exec( |
| 1800 | 1852 | "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)" |
| 1801 | 1853 | "VALUES(%d, %d, %d, %.17g, %s)", |
| 1802 | 1854 | pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/); |
| 1803 | - add_mlink(pid, 0, rid, p, i==0); | |
| 1804 | 1855 | if( i==0 ) parentid = pid; |
| 1805 | 1856 | } |
| 1857 | + add_mlink(parentid, 0, rid, p, 1); | |
| 1806 | 1858 | if( p->nParent>1 ){ |
| 1807 | 1859 | /* Change MLINK.PID from 0 to -1 for files that are added by merge. */ |
| 1808 | 1860 | db_multi_exec( |
| 1809 | 1861 | "UPDATE mlink SET pid=-1" |
| 1810 | 1862 | " WHERE mid=%d" |
| 1811 | 1863 |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -1185,10 +1185,15 @@ | |
| 1185 | } |
| 1186 | |
| 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 */ |
| @@ -1198,11 +1203,12 @@ | |
| 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 | |
| 1205 | fnid = filename_to_fnid(zFilename); |
| 1206 | if( zPrior==0 ){ |
| 1207 | pfnid = 0; |
| 1208 | }else{ |
| @@ -1217,23 +1223,36 @@ | |
| 1217 | fid = 0; |
| 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 | } |
| 1239 | |
| @@ -1346,10 +1365,19 @@ | |
| 1346 | ** |
| 1347 | ** Deleted files have mlink.fid=0. |
| 1348 | ** Added files have mlink.pid=0. |
| 1349 | ** File added by merge have mlink.pid=-1 |
| 1350 | ** Edited files have both mlink.pid!=0 and mlink.fid!=0 |
| 1351 | */ |
| 1352 | static void add_mlink( |
| 1353 | int pmid, Manifest *pParent, /* Parent check-in */ |
| 1354 | int mid, Manifest *pChild, /* The child check-in */ |
| 1355 | int isPrim /* TRUE if pmid is the primary parent of mid */ |
| @@ -1392,10 +1420,23 @@ | |
| 1392 | if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){ |
| 1393 | manifest_destroy(*ppOther); |
| 1394 | return; |
| 1395 | } |
| 1396 | isPublic = !content_is_private(mid); |
| 1397 | |
| 1398 | /* Try to make the parent manifest a delta from the child, if that |
| 1399 | ** is an appropriate thing to do. For a new baseline, make the |
| 1400 | ** previous baseline a delta from the current baseline. |
| 1401 | */ |
| @@ -1489,10 +1530,21 @@ | |
| 1489 | isPublic, isPrim, 0); |
| 1490 | } |
| 1491 | } |
| 1492 | } |
| 1493 | manifest_cache_insert(*ppOther); |
| 1494 | } |
| 1495 | |
| 1496 | /* |
| 1497 | ** Setup to do multiple manifest_crosslink() calls. |
| 1498 | ** This is only required if processing ticket changes. |
| @@ -1798,13 +1850,13 @@ | |
| 1798 | int pid = uuid_to_rid(p->azParent[i], 1); |
| 1799 | db_multi_exec( |
| 1800 | "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)" |
| 1801 | "VALUES(%d, %d, %d, %.17g, %s)", |
| 1802 | pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/); |
| 1803 | add_mlink(pid, 0, rid, p, i==0); |
| 1804 | if( i==0 ) parentid = pid; |
| 1805 | } |
| 1806 | if( p->nParent>1 ){ |
| 1807 | /* Change MLINK.PID from 0 to -1 for files that are added by merge. */ |
| 1808 | db_multi_exec( |
| 1809 | "UPDATE mlink SET pid=-1" |
| 1810 | " WHERE mid=%d" |
| 1811 |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -1185,10 +1185,15 @@ | |
| 1185 | } |
| 1186 | |
| 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 | ** An mlink entry is always created if isPrimary is true. But if |
| 1192 | ** isPrimary is false (meaning that pmid is a merge parent of mid) |
| 1193 | ** then the mlink entry is only created if there is already an mlink |
| 1194 | ** from primary parent for the same file. |
| 1195 | */ |
| 1196 | static void add_one_mlink( |
| 1197 | int pmid, /* The parent manifest */ |
| 1198 | const char *zFromUuid, /* UUID for content in parent */ |
| 1199 | int mid, /* The record ID of the manifest */ |
| @@ -1198,11 +1203,12 @@ | |
| 1203 | int isPublic, /* True if mid is not a private manifest */ |
| 1204 | int isPrimary, /* pmid is the primary parent of mid */ |
| 1205 | int mperm /* 1: exec, 2: symlink */ |
| 1206 | ){ |
| 1207 | int fnid, pfnid, pid, fid; |
| 1208 | int doInsert; |
| 1209 | static Stmt s1, s2; |
| 1210 | |
| 1211 | fnid = filename_to_fnid(zFilename); |
| 1212 | if( zPrior==0 ){ |
| 1213 | pfnid = 0; |
| 1214 | }else{ |
| @@ -1217,23 +1223,36 @@ | |
| 1223 | fid = 0; |
| 1224 | }else{ |
| 1225 | fid = uuid_to_rid(zToUuid, 1); |
| 1226 | if( isPublic ) content_make_public(fid); |
| 1227 | } |
| 1228 | if( isPrimary ){ |
| 1229 | doInsert = 1; |
| 1230 | }else{ |
| 1231 | db_static_prepare(&s2, |
| 1232 | "SELECT 1 FROM mlink WHERE mid=:m AND fnid=:n AND NOT isaux" |
| 1233 | ); |
| 1234 | db_bind_int(&s2, ":m", mid); |
| 1235 | db_bind_int(&s2, ":n", fnid); |
| 1236 | doInsert = db_step(&s2)==SQLITE_ROW; |
| 1237 | db_reset(&s2); |
| 1238 | } |
| 1239 | if( doInsert ){ |
| 1240 | db_static_prepare(&s1, |
| 1241 | "INSERT INTO mlink(mid,fid,pmid,pid,fnid,pfnid,mperm,isaux)" |
| 1242 | "VALUES(:m,:f,:pm,:p,:n,:pfn,:mp,:isaux)" |
| 1243 | ); |
| 1244 | db_bind_int(&s1, ":m", mid); |
| 1245 | db_bind_int(&s1, ":f", fid); |
| 1246 | db_bind_int(&s1, ":pm", pmid); |
| 1247 | db_bind_int(&s1, ":p", pid); |
| 1248 | db_bind_int(&s1, ":n", fnid); |
| 1249 | db_bind_int(&s1, ":pfn", pfnid); |
| 1250 | db_bind_int(&s1, ":mp", mperm); |
| 1251 | db_bind_int(&s1, ":isaux", isPrimary==0); |
| 1252 | db_exec(&s1); |
| 1253 | } |
| 1254 | if( pid && fid ){ |
| 1255 | content_deltify(pid, fid, 0); |
| 1256 | } |
| 1257 | } |
| 1258 | |
| @@ -1346,10 +1365,19 @@ | |
| 1365 | ** |
| 1366 | ** Deleted files have mlink.fid=0. |
| 1367 | ** Added files have mlink.pid=0. |
| 1368 | ** File added by merge have mlink.pid=-1 |
| 1369 | ** Edited files have both mlink.pid!=0 and mlink.fid!=0 |
| 1370 | ** |
| 1371 | ** Many mlink entries for merge parents will only be added if another mlink |
| 1372 | ** entry already exists for the same file from the primary parent. Therefore, |
| 1373 | ** to ensure that all merge-parent mlink entries are properly created: |
| 1374 | ** |
| 1375 | ** (1) Make this routine a no-op if pParent is a merge parent and the |
| 1376 | ** primary parent is a phantom. |
| 1377 | ** (2) Invoke this routine recursively for merge-parents if pParent is the |
| 1378 | ** primary parent. |
| 1379 | */ |
| 1380 | static void add_mlink( |
| 1381 | int pmid, Manifest *pParent, /* Parent check-in */ |
| 1382 | int mid, Manifest *pChild, /* The child check-in */ |
| 1383 | int isPrim /* TRUE if pmid is the primary parent of mid */ |
| @@ -1392,10 +1420,23 @@ | |
| 1420 | if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){ |
| 1421 | manifest_destroy(*ppOther); |
| 1422 | return; |
| 1423 | } |
| 1424 | isPublic = !content_is_private(mid); |
| 1425 | |
| 1426 | /* If pParent is not the primary parent of pChild, and the primary |
| 1427 | ** parent of pChild is a phantom, then abort this routine without |
| 1428 | ** doing any work. The mlink entries will be computed when the |
| 1429 | ** primary parent dephantomizes. |
| 1430 | */ |
| 1431 | if( !isPrim && otherRid==mid |
| 1432 | && !db_exists("SELECT 1 FROM blob WHERE uuid=%Q AND size>0", |
| 1433 | pChild->azParent[0]) |
| 1434 | ){ |
| 1435 | manifest_cache_insert(*ppOther); |
| 1436 | return; |
| 1437 | } |
| 1438 | |
| 1439 | /* Try to make the parent manifest a delta from the child, if that |
| 1440 | ** is an appropriate thing to do. For a new baseline, make the |
| 1441 | ** previous baseline a delta from the current baseline. |
| 1442 | */ |
| @@ -1489,10 +1530,21 @@ | |
| 1530 | isPublic, isPrim, 0); |
| 1531 | } |
| 1532 | } |
| 1533 | } |
| 1534 | manifest_cache_insert(*ppOther); |
| 1535 | |
| 1536 | /* If pParent is the primary parent of pChild, also run this analysis |
| 1537 | ** for all merge parents of pChild |
| 1538 | */ |
| 1539 | if( isPrim ){ |
| 1540 | for(i=1; i<pChild->nParent; i++){ |
| 1541 | pmid = uuid_to_rid(pChild->azParent[i], 0); |
| 1542 | if( pmid<=0 ) continue; |
| 1543 | add_mlink(pmid, 0, mid, pChild, 0); |
| 1544 | } |
| 1545 | } |
| 1546 | } |
| 1547 | |
| 1548 | /* |
| 1549 | ** Setup to do multiple manifest_crosslink() calls. |
| 1550 | ** This is only required if processing ticket changes. |
| @@ -1798,13 +1850,13 @@ | |
| 1850 | int pid = uuid_to_rid(p->azParent[i], 1); |
| 1851 | db_multi_exec( |
| 1852 | "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)" |
| 1853 | "VALUES(%d, %d, %d, %.17g, %s)", |
| 1854 | pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/); |
| 1855 | if( i==0 ) parentid = pid; |
| 1856 | } |
| 1857 | add_mlink(parentid, 0, rid, p, 1); |
| 1858 | if( p->nParent>1 ){ |
| 1859 | /* Change MLINK.PID from 0 to -1 for files that are added by merge. */ |
| 1860 | db_multi_exec( |
| 1861 | "UPDATE mlink SET pid=-1" |
| 1862 | " WHERE mid=%d" |
| 1863 |