Fossil SCM

Add the orig= query parameter to the /finfo webpage. Use this in the hyperlink from the analysis log of the /annotate page.

drh 2017-09-27 02:10 trunk
Commit 95cc4b90da9e73fd81d8ecb342886fcb04fb0def9725fb20ce084547d0e1cb92
3 files changed +6 -22 +29 -10 +32
+6 -22
--- src/diff.c
+++ src/diff.c
@@ -2248,31 +2248,11 @@
22482248
origid = zOrigin ? name_to_typed_rid(zOrigin, "ci") : 0;
22492249
22502250
/* Compute all direct ancestors of the check-in being analyzed into
22512251
** the "ancestor" table. */
22522252
if( origid ){
2253
- PathNode *pPath;
2254
- Blob sql;
2255
- int gen = 0;
2256
- char *zSep = "VALUES";
2257
- pPath = path_shortest(cid, origid, 1, 0);
2258
- db_multi_exec(
2259
- "CREATE TEMP TABLE IF NOT EXISTS ancestor("
2260
- " rid INT UNIQUE,"
2261
- " generation INTEGER PRIMARY KEY"
2262
- ");"
2263
- "DELETE FROM ancestor;"
2264
- );
2265
- blob_init(&sql, "INSERT INTO ancestor(rid, generation)", -1);
2266
- while( pPath ){
2267
- blob_append_sql(&sql, "%s(%d,%d)", zSep/*safe-for-%s*/, pPath->rid,++gen);
2268
- zSep = ",";
2269
- pPath = pPath->u.pTo;
2270
- }
2271
- path_reset();
2272
- db_multi_exec("%s", blob_sql_text(&sql));
2273
- blob_reset(&sql);
2253
+ path_shortest_stored_in_ancestor_table(origid, cid);
22742254
}else{
22752255
compute_direct_ancestors(cid);
22762256
}
22772257
22782258
/* Get filename ID */
@@ -2462,11 +2442,15 @@
24622442
clr = gradient_color(clr1, clr2, ann.nVers-1, i);
24632443
ann.aVers[i].zBgColor = mprintf("#%06x", clr);
24642444
}
24652445
24662446
@ <div id="annotation_log" style='display:%s(showLog?"block":"none");'>
2467
- zLink = href("%R/finfo?name=%t&ci=%!S",zFilename,zCI);
2447
+ if( zOrigin ){
2448
+ zLink = href("%R/finfo?name=%t&ci=%!S&orig=%!S",zFilename,zCI,zOrigin);
2449
+ }else{
2450
+ zLink = href("%R/finfo?name=%t&ci=%!S",zFilename,zCI);
2451
+ }
24682452
@ <h2>Versions of %z(zLink)%h(zFilename)</a> analyzed:</h2>
24692453
@ <ol>
24702454
for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
24712455
@ <li><span style='background-color:%s(p->zBgColor);'>%s(p->zDate)
24722456
@ check-in %z(href("%R/info/%!S",p->zMUuid))%S(p->zMUuid)</a>
24732457
--- src/diff.c
+++ src/diff.c
@@ -2248,31 +2248,11 @@
2248 origid = zOrigin ? name_to_typed_rid(zOrigin, "ci") : 0;
2249
2250 /* Compute all direct ancestors of the check-in being analyzed into
2251 ** the "ancestor" table. */
2252 if( origid ){
2253 PathNode *pPath;
2254 Blob sql;
2255 int gen = 0;
2256 char *zSep = "VALUES";
2257 pPath = path_shortest(cid, origid, 1, 0);
2258 db_multi_exec(
2259 "CREATE TEMP TABLE IF NOT EXISTS ancestor("
2260 " rid INT UNIQUE,"
2261 " generation INTEGER PRIMARY KEY"
2262 ");"
2263 "DELETE FROM ancestor;"
2264 );
2265 blob_init(&sql, "INSERT INTO ancestor(rid, generation)", -1);
2266 while( pPath ){
2267 blob_append_sql(&sql, "%s(%d,%d)", zSep/*safe-for-%s*/, pPath->rid,++gen);
2268 zSep = ",";
2269 pPath = pPath->u.pTo;
2270 }
2271 path_reset();
2272 db_multi_exec("%s", blob_sql_text(&sql));
2273 blob_reset(&sql);
2274 }else{
2275 compute_direct_ancestors(cid);
2276 }
2277
2278 /* Get filename ID */
@@ -2462,11 +2442,15 @@
2462 clr = gradient_color(clr1, clr2, ann.nVers-1, i);
2463 ann.aVers[i].zBgColor = mprintf("#%06x", clr);
2464 }
2465
2466 @ <div id="annotation_log" style='display:%s(showLog?"block":"none");'>
2467 zLink = href("%R/finfo?name=%t&ci=%!S",zFilename,zCI);
 
 
 
 
2468 @ <h2>Versions of %z(zLink)%h(zFilename)</a> analyzed:</h2>
2469 @ <ol>
2470 for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
2471 @ <li><span style='background-color:%s(p->zBgColor);'>%s(p->zDate)
2472 @ check-in %z(href("%R/info/%!S",p->zMUuid))%S(p->zMUuid)</a>
2473
--- src/diff.c
+++ src/diff.c
@@ -2248,31 +2248,11 @@
2248 origid = zOrigin ? name_to_typed_rid(zOrigin, "ci") : 0;
2249
2250 /* Compute all direct ancestors of the check-in being analyzed into
2251 ** the "ancestor" table. */
2252 if( origid ){
2253 path_shortest_stored_in_ancestor_table(origid, cid);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2254 }else{
2255 compute_direct_ancestors(cid);
2256 }
2257
2258 /* Get filename ID */
@@ -2462,11 +2442,15 @@
2442 clr = gradient_color(clr1, clr2, ann.nVers-1, i);
2443 ann.aVers[i].zBgColor = mprintf("#%06x", clr);
2444 }
2445
2446 @ <div id="annotation_log" style='display:%s(showLog?"block":"none");'>
2447 if( zOrigin ){
2448 zLink = href("%R/finfo?name=%t&ci=%!S&orig=%!S",zFilename,zCI,zOrigin);
2449 }else{
2450 zLink = href("%R/finfo?name=%t&ci=%!S",zFilename,zCI);
2451 }
2452 @ <h2>Versions of %z(zLink)%h(zFilename)</a> analyzed:</h2>
2453 @ <ol>
2454 for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
2455 @ <li><span style='background-color:%s(p->zBgColor);'>%s(p->zDate)
2456 @ check-in %z(href("%R/info/%!S",p->zMUuid))%S(p->zMUuid)</a>
2457
+29 -10
--- src/finfo.c
+++ src/finfo.c
@@ -284,10 +284,12 @@
284284
** b=DATETIME Only show changes before DATETIME
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
+** orig=UUID If both ci and orig are supplied, only show those
290
+** changes on a direct path from orig to ci.
289291
** showid Show RID values for debugging
290292
**
291293
** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
292294
** year-month-day form, it may be truncated, and it may also name a
293295
** timezone offset from UTC as "-HH:MM" (westward) or "+HH:MM"
@@ -299,10 +301,11 @@
299301
char zPrevDate[20];
300302
const char *zA;
301303
const char *zB;
302304
int n;
303305
int baseCheckin;
306
+ int origCheckin = 0;
304307
int fnid;
305308
Blob title;
306309
Blob sql;
307310
HQuery url;
308311
GraphContext *pGraph;
@@ -331,11 +334,16 @@
331334
}
332335
if( g.perm.Admin ){
333336
style_submenu_element("MLink Table", "%R/mlink?name=%t", zFilename);
334337
}
335338
if( baseCheckin ){
336
- compute_direct_ancestors(baseCheckin);
339
+ if( P("orig")!=0 ){
340
+ origCheckin = name_to_typed_rid(P("orig"),"ci");
341
+ path_shortest_stored_in_ancestor_table(origCheckin, baseCheckin);
342
+ }else{
343
+ compute_direct_ancestors(baseCheckin);
344
+ }
337345
}
338346
url_add_parameter(&url, "name", zFilename);
339347
blob_zero(&sql);
340348
blob_append_sql(&sql,
341349
"SELECT"
@@ -398,21 +406,30 @@
398406
blob_reset(&sql);
399407
blob_zero(&title);
400408
if( baseCheckin ){
401409
char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin);
402410
char *zLink = href("%R/info/%!S", zUuid);
403
- if( n>0 ){
411
+ if( origCheckin ){
412
+ blob_appendf(&title, "Changes to file ");
413
+ }else if( n>0 ){
404414
blob_appendf(&title, "First %d ancestors of file ", n);
405415
}else{
406416
blob_appendf(&title, "Ancestors of file ");
407417
}
408418
blob_appendf(&title,"<a href='%R/finfo?name=%T'>%h</a>",
409419
zFilename, zFilename);
410420
if( fShowId ) blob_appendf(&title, " (%d)", fnid);
411
- blob_appendf(&title, " from check-in %z%S</a>", zLink, zUuid);
421
+ blob_append(&title, origCheckin ? " between " : " from ", -1);
422
+ blob_appendf(&title, "check-in %z%S</a>", zLink, zUuid);
412423
if( fShowId ) blob_appendf(&title, " (%d)", baseCheckin);
413424
fossil_free(zUuid);
425
+ if( origCheckin ){
426
+ zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", origCheckin);
427
+ zLink = href("%R/info/%!S", zUuid);
428
+ blob_appendf(&title, " and check-in %z%S</a>", zLink, zUuid);
429
+ fossil_free(zUuid);
430
+ }
414431
}else{
415432
blob_appendf(&title, "History of ");
416433
hyperlinked_path(zFilename, &title, 0, "tree", "");
417434
if( fShowId ) blob_appendf(&title, " (%d)", fnid);
418435
}
@@ -486,17 +503,19 @@
486503
@ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
487504
}else{
488505
@ <td class="timelineTableCell">
489506
}
490507
if( zUuid ){
491
- if( nParent==0 ){
492
- @ <b>Added</b>
493
- }else if( pfnid ){
494
- char *zPrevName = db_text(0, "SELECT name FROM filename WHERE fnid=%d",
495
- pfnid);
496
- @ <b>Renamed</b> from
497
- @ %z(href("%R/finfo?name=%t", zPrevName))%h(zPrevName)</a>
508
+ if( origCheckin==0 ){
509
+ if( nParent==0 ){
510
+ @ <b>Added</b>
511
+ }else if( pfnid ){
512
+ char *zPrevName = db_text(0,"SELECT name FROM filename WHERE fnid=%d",
513
+ pfnid);
514
+ @ <b>Renamed</b> from
515
+ @ %z(href("%R/finfo?name=%t", zPrevName))%h(zPrevName)</a>
516
+ }
498517
}
499518
@ %z(href("%R/artifact/%!S",zUuid))[%S(zUuid)]</a>
500519
if( fShowId ){
501520
int srcId = delta_source_rid(frid);
502521
if( srcId>0 ){
503522
--- src/finfo.c
+++ src/finfo.c
@@ -284,10 +284,12 @@
284 ** b=DATETIME Only show changes before DATETIME
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 ** showid Show RID values for debugging
290 **
291 ** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
292 ** year-month-day form, it may be truncated, and it may also name a
293 ** timezone offset from UTC as "-HH:MM" (westward) or "+HH:MM"
@@ -299,10 +301,11 @@
299 char zPrevDate[20];
300 const char *zA;
301 const char *zB;
302 int n;
303 int baseCheckin;
 
304 int fnid;
305 Blob title;
306 Blob sql;
307 HQuery url;
308 GraphContext *pGraph;
@@ -331,11 +334,16 @@
331 }
332 if( g.perm.Admin ){
333 style_submenu_element("MLink Table", "%R/mlink?name=%t", zFilename);
334 }
335 if( baseCheckin ){
336 compute_direct_ancestors(baseCheckin);
 
 
 
 
 
337 }
338 url_add_parameter(&url, "name", zFilename);
339 blob_zero(&sql);
340 blob_append_sql(&sql,
341 "SELECT"
@@ -398,21 +406,30 @@
398 blob_reset(&sql);
399 blob_zero(&title);
400 if( baseCheckin ){
401 char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin);
402 char *zLink = href("%R/info/%!S", zUuid);
403 if( n>0 ){
 
 
404 blob_appendf(&title, "First %d ancestors of file ", n);
405 }else{
406 blob_appendf(&title, "Ancestors of file ");
407 }
408 blob_appendf(&title,"<a href='%R/finfo?name=%T'>%h</a>",
409 zFilename, zFilename);
410 if( fShowId ) blob_appendf(&title, " (%d)", fnid);
411 blob_appendf(&title, " from check-in %z%S</a>", zLink, zUuid);
 
412 if( fShowId ) blob_appendf(&title, " (%d)", baseCheckin);
413 fossil_free(zUuid);
 
 
 
 
 
 
414 }else{
415 blob_appendf(&title, "History of ");
416 hyperlinked_path(zFilename, &title, 0, "tree", "");
417 if( fShowId ) blob_appendf(&title, " (%d)", fnid);
418 }
@@ -486,17 +503,19 @@
486 @ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
487 }else{
488 @ <td class="timelineTableCell">
489 }
490 if( zUuid ){
491 if( nParent==0 ){
492 @ <b>Added</b>
493 }else if( pfnid ){
494 char *zPrevName = db_text(0, "SELECT name FROM filename WHERE fnid=%d",
495 pfnid);
496 @ <b>Renamed</b> from
497 @ %z(href("%R/finfo?name=%t", zPrevName))%h(zPrevName)</a>
 
 
498 }
499 @ %z(href("%R/artifact/%!S",zUuid))[%S(zUuid)]</a>
500 if( fShowId ){
501 int srcId = delta_source_rid(frid);
502 if( srcId>0 ){
503
--- src/finfo.c
+++ src/finfo.c
@@ -284,10 +284,12 @@
284 ** b=DATETIME Only show changes before DATETIME
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 ** orig=UUID If both ci and orig are supplied, only show those
290 ** changes on a direct path from orig to ci.
291 ** showid Show RID values for debugging
292 **
293 ** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
294 ** year-month-day form, it may be truncated, and it may also name a
295 ** timezone offset from UTC as "-HH:MM" (westward) or "+HH:MM"
@@ -299,10 +301,11 @@
301 char zPrevDate[20];
302 const char *zA;
303 const char *zB;
304 int n;
305 int baseCheckin;
306 int origCheckin = 0;
307 int fnid;
308 Blob title;
309 Blob sql;
310 HQuery url;
311 GraphContext *pGraph;
@@ -331,11 +334,16 @@
334 }
335 if( g.perm.Admin ){
336 style_submenu_element("MLink Table", "%R/mlink?name=%t", zFilename);
337 }
338 if( baseCheckin ){
339 if( P("orig")!=0 ){
340 origCheckin = name_to_typed_rid(P("orig"),"ci");
341 path_shortest_stored_in_ancestor_table(origCheckin, baseCheckin);
342 }else{
343 compute_direct_ancestors(baseCheckin);
344 }
345 }
346 url_add_parameter(&url, "name", zFilename);
347 blob_zero(&sql);
348 blob_append_sql(&sql,
349 "SELECT"
@@ -398,21 +406,30 @@
406 blob_reset(&sql);
407 blob_zero(&title);
408 if( baseCheckin ){
409 char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin);
410 char *zLink = href("%R/info/%!S", zUuid);
411 if( origCheckin ){
412 blob_appendf(&title, "Changes to file ");
413 }else if( n>0 ){
414 blob_appendf(&title, "First %d ancestors of file ", n);
415 }else{
416 blob_appendf(&title, "Ancestors of file ");
417 }
418 blob_appendf(&title,"<a href='%R/finfo?name=%T'>%h</a>",
419 zFilename, zFilename);
420 if( fShowId ) blob_appendf(&title, " (%d)", fnid);
421 blob_append(&title, origCheckin ? " between " : " from ", -1);
422 blob_appendf(&title, "check-in %z%S</a>", zLink, zUuid);
423 if( fShowId ) blob_appendf(&title, " (%d)", baseCheckin);
424 fossil_free(zUuid);
425 if( origCheckin ){
426 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", origCheckin);
427 zLink = href("%R/info/%!S", zUuid);
428 blob_appendf(&title, " and check-in %z%S</a>", zLink, zUuid);
429 fossil_free(zUuid);
430 }
431 }else{
432 blob_appendf(&title, "History of ");
433 hyperlinked_path(zFilename, &title, 0, "tree", "");
434 if( fShowId ) blob_appendf(&title, " (%d)", fnid);
435 }
@@ -486,17 +503,19 @@
503 @ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
504 }else{
505 @ <td class="timelineTableCell">
506 }
507 if( zUuid ){
508 if( origCheckin==0 ){
509 if( nParent==0 ){
510 @ <b>Added</b>
511 }else if( pfnid ){
512 char *zPrevName = db_text(0,"SELECT name FROM filename WHERE fnid=%d",
513 pfnid);
514 @ <b>Renamed</b> from
515 @ %z(href("%R/finfo?name=%t", zPrevName))%h(zPrevName)</a>
516 }
517 }
518 @ %z(href("%R/artifact/%!S",zUuid))[%S(zUuid)]</a>
519 if( fShowId ){
520 int srcId = delta_source_rid(frid);
521 if( srcId>0 ){
522
+32
--- src/path.c
+++ src/path.c
@@ -192,10 +192,42 @@
192192
int i;
193193
if( path.nStep<2 ) return 0;
194194
for(p=path.pEnd, i=0; p && i<path.nStep/2; p=p->pFrom, i++){}
195195
return p;
196196
}
197
+
198
+/*
199
+** Compute the shortest path between two check-ins and then transfer
200
+** that path into the "ancestor" table. This is a utility used by
201
+** both /annotate and /finfo. See also: compute_direct_ancestors().
202
+*/
203
+void path_shortest_stored_in_ancestor_table(
204
+ int origid, /* RID for check-in at start of the path */
205
+ int cid /* RID for check-in at the end of the path */
206
+){
207
+ PathNode *pPath;
208
+ Blob sql;
209
+ int gen = 0;
210
+ char *zSep = "VALUES";
211
+ pPath = path_shortest(cid, origid, 1, 0);
212
+ db_multi_exec(
213
+ "CREATE TEMP TABLE IF NOT EXISTS ancestor("
214
+ " rid INT UNIQUE,"
215
+ " generation INTEGER PRIMARY KEY"
216
+ ");"
217
+ "DELETE FROM ancestor;"
218
+ );
219
+ blob_init(&sql, "INSERT INTO ancestor(rid, generation)", -1);
220
+ while( pPath ){
221
+ blob_append_sql(&sql, "%s(%d,%d)", zSep/*safe-for-%s*/, pPath->rid,++gen);
222
+ zSep = ",";
223
+ pPath = pPath->u.pTo;
224
+ }
225
+ path_reset();
226
+ db_multi_exec("%s", blob_sql_text(&sql));
227
+ blob_reset(&sql);
228
+}
197229
198230
/*
199231
** COMMAND: test-shortest-path
200232
**
201233
** Usage: %fossil test-shortest-path ?--no-merge? VERSION1 VERSION2
202234
--- src/path.c
+++ src/path.c
@@ -192,10 +192,42 @@
192 int i;
193 if( path.nStep<2 ) return 0;
194 for(p=path.pEnd, i=0; p && i<path.nStep/2; p=p->pFrom, i++){}
195 return p;
196 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
198 /*
199 ** COMMAND: test-shortest-path
200 **
201 ** Usage: %fossil test-shortest-path ?--no-merge? VERSION1 VERSION2
202
--- src/path.c
+++ src/path.c
@@ -192,10 +192,42 @@
192 int i;
193 if( path.nStep<2 ) return 0;
194 for(p=path.pEnd, i=0; p && i<path.nStep/2; p=p->pFrom, i++){}
195 return p;
196 }
197
198 /*
199 ** Compute the shortest path between two check-ins and then transfer
200 ** that path into the "ancestor" table. This is a utility used by
201 ** both /annotate and /finfo. See also: compute_direct_ancestors().
202 */
203 void path_shortest_stored_in_ancestor_table(
204 int origid, /* RID for check-in at start of the path */
205 int cid /* RID for check-in at the end of the path */
206 ){
207 PathNode *pPath;
208 Blob sql;
209 int gen = 0;
210 char *zSep = "VALUES";
211 pPath = path_shortest(cid, origid, 1, 0);
212 db_multi_exec(
213 "CREATE TEMP TABLE IF NOT EXISTS ancestor("
214 " rid INT UNIQUE,"
215 " generation INTEGER PRIMARY KEY"
216 ");"
217 "DELETE FROM ancestor;"
218 );
219 blob_init(&sql, "INSERT INTO ancestor(rid, generation)", -1);
220 while( pPath ){
221 blob_append_sql(&sql, "%s(%d,%d)", zSep/*safe-for-%s*/, pPath->rid,++gen);
222 zSep = ",";
223 pPath = pPath->u.pTo;
224 }
225 path_reset();
226 db_multi_exec("%s", blob_sql_text(&sql));
227 blob_reset(&sql);
228 }
229
230 /*
231 ** COMMAND: test-shortest-path
232 **
233 ** Usage: %fossil test-shortest-path ?--no-merge? VERSION1 VERSION2
234

Keyboard Shortcuts

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