Fossil SCM

Provide a link to the reverse annotation for an /fdiff of two versions of the same file. Improvements to the description of a reverse annotation.

drh 2017-09-26 03:56 trunk
Commit f52a544942a7fae8a31ef6290f392ef011f0e8e695f8a590c7624ca9b00e2b55
2 files changed +16 -5 +26
+16 -5
--- src/diff.c
+++ src/diff.c
@@ -2084,10 +2084,12 @@
20842084
short int iVers; /* Level at which tag was set */
20852085
} *aOrig;
20862086
int nOrig; /* Number of elements in aOrig[] */
20872087
int nVers; /* Number of versions analyzed */
20882088
int bMoreToDo; /* True if the limit was reached */
2089
+ int origId; /* RID for the zOrigin version */
2090
+ int showId; /* RID for the version being analyzed */
20892091
struct AnnVers {
20902092
const char *zFUuid; /* File being analyzed */
20912093
const char *zMUuid; /* Check-in containing the file */
20922094
const char *zDate; /* Date of the check-in */
20932095
const char *zBgColor; /* Suggested background color */
@@ -2246,27 +2248,27 @@
22462248
origid = zOrigin ? name_to_typed_rid(zOrigin, "ci") : 0;
22472249
22482250
/* Compute all direct ancestors of the check-in being analyzed into
22492251
** the "ancestor" table. */
22502252
if( origid ){
2251
- PathNode *p;
2253
+ PathNode *pPath;
22522254
Blob sql;
22532255
int gen = 0;
22542256
char *zSep = "VALUES";
2255
- p = path_shortest(cid, origid, 1, 0);
2257
+ pPath = path_shortest(cid, origid, 1, 0);
22562258
db_multi_exec(
22572259
"CREATE TEMP TABLE IF NOT EXISTS ancestor("
22582260
" rid INT UNIQUE,"
22592261
" generation INTEGER PRIMARY KEY"
22602262
");"
22612263
"DELETE FROM ancestor;"
22622264
);
22632265
blob_init(&sql, "INSERT INTO ancestor(rid, generation)", -1);
2264
- while( p ){
2265
- blob_append_sql(&sql, "%s(%d,%d)", zSep/*safe-for-%s*/, p->rid, ++gen);
2266
+ while( pPath ){
2267
+ blob_append_sql(&sql, "%s(%d,%d)", zSep/*safe-for-%s*/, pPath->rid,++gen);
22662268
zSep = ",";
2267
- p = p->u.pTo;
2269
+ pPath = pPath->u.pTo;
22682270
}
22692271
path_reset();
22702272
db_multi_exec("%s", blob_sql_text(&sql));
22712273
blob_reset(&sql);
22722274
}else{
@@ -2309,10 +2311,12 @@
23092311
fossil_fatal("unable to retrieve content of artifact #%d", rid);
23102312
}
23112313
blob_to_utf8_no_bom(&toAnnotate, 0);
23122314
annotation_start(p, &toAnnotate, annFlags);
23132315
p->bMoreToDo = origid!=0;
2316
+ p->origId = origid;
2317
+ p->showId = cid;
23142318
}
23152319
p->aVers = fossil_realloc(p->aVers, (p->nVers+1)*sizeof(p->aVers[0]));
23162320
p->aVers[p->nVers].zFUuid = fossil_strdup(db_column_text(&q, 0));
23172321
p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1));
23182322
p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2));
@@ -2479,13 +2483,20 @@
24792483
@ w.style.display = x ? "block" : "none";
24802484
@ }
24812485
@ </script>
24822486
24832487
if( !ann.bMoreToDo ){
2488
+ assert( ann.origId==0 ); /* bMoreToDo always set for a point-to-point */
24842489
@ <h2>Origin for each line in
24852490
@ %z(href("%R/finfo?name=%h&ci=%!S", zFilename, zCI))%h(zFilename)</a>
24862491
@ from check-in %z(href("%R/info/%!S",zCI))%S(zCI)</a>:</h2>
2492
+ }else if( ann.origId>0 ){
2493
+ @ <h2>Lines of
2494
+ @ %z(href("%R/finfo?name=%h&ci=%!S", zFilename, zCI))%h(zFilename)</a>
2495
+ @ from check-in %z(href("%R/info/%!S",zCI))%S(zCI)</a>
2496
+ @ that are changed by the sequence of edits moving toward
2497
+ @ check-in %z(href("%R/info/%!S",zOrigin))%S(zOrigin)</a>:</h2>
24872498
}else{
24882499
@ <h2>Lines added by the %d(ann.nVers) most recent ancestors of
24892500
@ %z(href("%R/finfo?name=%h&ci=%!S", zFilename, zCI))%h(zFilename)</a>
24902501
@ from check-in %z(href("%R/info/%!S",zCI))%S(zCI)</a>:</h2>
24912502
}
24922503
--- src/diff.c
+++ src/diff.c
@@ -2084,10 +2084,12 @@
2084 short int iVers; /* Level at which tag was set */
2085 } *aOrig;
2086 int nOrig; /* Number of elements in aOrig[] */
2087 int nVers; /* Number of versions analyzed */
2088 int bMoreToDo; /* True if the limit was reached */
 
 
2089 struct AnnVers {
2090 const char *zFUuid; /* File being analyzed */
2091 const char *zMUuid; /* Check-in containing the file */
2092 const char *zDate; /* Date of the check-in */
2093 const char *zBgColor; /* Suggested background color */
@@ -2246,27 +2248,27 @@
2246 origid = zOrigin ? name_to_typed_rid(zOrigin, "ci") : 0;
2247
2248 /* Compute all direct ancestors of the check-in being analyzed into
2249 ** the "ancestor" table. */
2250 if( origid ){
2251 PathNode *p;
2252 Blob sql;
2253 int gen = 0;
2254 char *zSep = "VALUES";
2255 p = path_shortest(cid, origid, 1, 0);
2256 db_multi_exec(
2257 "CREATE TEMP TABLE IF NOT EXISTS ancestor("
2258 " rid INT UNIQUE,"
2259 " generation INTEGER PRIMARY KEY"
2260 ");"
2261 "DELETE FROM ancestor;"
2262 );
2263 blob_init(&sql, "INSERT INTO ancestor(rid, generation)", -1);
2264 while( p ){
2265 blob_append_sql(&sql, "%s(%d,%d)", zSep/*safe-for-%s*/, p->rid, ++gen);
2266 zSep = ",";
2267 p = p->u.pTo;
2268 }
2269 path_reset();
2270 db_multi_exec("%s", blob_sql_text(&sql));
2271 blob_reset(&sql);
2272 }else{
@@ -2309,10 +2311,12 @@
2309 fossil_fatal("unable to retrieve content of artifact #%d", rid);
2310 }
2311 blob_to_utf8_no_bom(&toAnnotate, 0);
2312 annotation_start(p, &toAnnotate, annFlags);
2313 p->bMoreToDo = origid!=0;
 
 
2314 }
2315 p->aVers = fossil_realloc(p->aVers, (p->nVers+1)*sizeof(p->aVers[0]));
2316 p->aVers[p->nVers].zFUuid = fossil_strdup(db_column_text(&q, 0));
2317 p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1));
2318 p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2));
@@ -2479,13 +2483,20 @@
2479 @ w.style.display = x ? "block" : "none";
2480 @ }
2481 @ </script>
2482
2483 if( !ann.bMoreToDo ){
 
2484 @ <h2>Origin for each line in
2485 @ %z(href("%R/finfo?name=%h&ci=%!S", zFilename, zCI))%h(zFilename)</a>
2486 @ from check-in %z(href("%R/info/%!S",zCI))%S(zCI)</a>:</h2>
 
 
 
 
 
 
2487 }else{
2488 @ <h2>Lines added by the %d(ann.nVers) most recent ancestors of
2489 @ %z(href("%R/finfo?name=%h&ci=%!S", zFilename, zCI))%h(zFilename)</a>
2490 @ from check-in %z(href("%R/info/%!S",zCI))%S(zCI)</a>:</h2>
2491 }
2492
--- src/diff.c
+++ src/diff.c
@@ -2084,10 +2084,12 @@
2084 short int iVers; /* Level at which tag was set */
2085 } *aOrig;
2086 int nOrig; /* Number of elements in aOrig[] */
2087 int nVers; /* Number of versions analyzed */
2088 int bMoreToDo; /* True if the limit was reached */
2089 int origId; /* RID for the zOrigin version */
2090 int showId; /* RID for the version being analyzed */
2091 struct AnnVers {
2092 const char *zFUuid; /* File being analyzed */
2093 const char *zMUuid; /* Check-in containing the file */
2094 const char *zDate; /* Date of the check-in */
2095 const char *zBgColor; /* Suggested background color */
@@ -2246,27 +2248,27 @@
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{
@@ -2309,10 +2311,12 @@
2311 fossil_fatal("unable to retrieve content of artifact #%d", rid);
2312 }
2313 blob_to_utf8_no_bom(&toAnnotate, 0);
2314 annotation_start(p, &toAnnotate, annFlags);
2315 p->bMoreToDo = origid!=0;
2316 p->origId = origid;
2317 p->showId = cid;
2318 }
2319 p->aVers = fossil_realloc(p->aVers, (p->nVers+1)*sizeof(p->aVers[0]));
2320 p->aVers[p->nVers].zFUuid = fossil_strdup(db_column_text(&q, 0));
2321 p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1));
2322 p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2));
@@ -2479,13 +2483,20 @@
2483 @ w.style.display = x ? "block" : "none";
2484 @ }
2485 @ </script>
2486
2487 if( !ann.bMoreToDo ){
2488 assert( ann.origId==0 ); /* bMoreToDo always set for a point-to-point */
2489 @ <h2>Origin for each line in
2490 @ %z(href("%R/finfo?name=%h&ci=%!S", zFilename, zCI))%h(zFilename)</a>
2491 @ from check-in %z(href("%R/info/%!S",zCI))%S(zCI)</a>:</h2>
2492 }else if( ann.origId>0 ){
2493 @ <h2>Lines of
2494 @ %z(href("%R/finfo?name=%h&ci=%!S", zFilename, zCI))%h(zFilename)</a>
2495 @ from check-in %z(href("%R/info/%!S",zCI))%S(zCI)</a>
2496 @ that are changed by the sequence of edits moving toward
2497 @ check-in %z(href("%R/info/%!S",zOrigin))%S(zOrigin)</a>:</h2>
2498 }else{
2499 @ <h2>Lines added by the %d(ann.nVers) most recent ancestors of
2500 @ %z(href("%R/finfo?name=%h&ci=%!S", zFilename, zCI))%h(zFilename)</a>
2501 @ from check-in %z(href("%R/info/%!S",zCI))%S(zCI)</a>:</h2>
2502 }
2503
+26
--- src/info.c
+++ src/info.c
@@ -1561,12 +1561,38 @@
15611561
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
15621562
if( P("from") && P("to") ){
15631563
v1 = artifact_from_ci_and_filename(0, "from");
15641564
v2 = artifact_from_ci_and_filename(0, "to");
15651565
}else{
1566
+ Stmt q;
15661567
v1 = name_to_rid_www("v1");
15671568
v2 = name_to_rid_www("v2");
1569
+
1570
+ /* If the two file versions being compared both have the same
1571
+ ** filename, then offer an "Annotate" link that constructs an
1572
+ ** annotation between those version. */
1573
+ db_prepare(&q,
1574
+ "SELECT (SELECT substr(uuid,1,20) FROM blob WHERE rid=a.mid),"
1575
+ " (SELECT substr(uuid,1,20) FROM blob WHERE rid=b.mid),"
1576
+ " (SELECT name FROM filename WHERE filename.fnid=a.fnid)"
1577
+ " FROM mlink a, mlink b"
1578
+ " WHERE a.fid=%d"
1579
+ " AND b.fid=%d"
1580
+ " AND a.fnid=b.fnid"
1581
+ " AND a.fid!=a.pid"
1582
+ " AND b.fid!=b.pid",
1583
+ v1, v2
1584
+ );
1585
+ if( db_step(&q)==SQLITE_ROW ){
1586
+ const char *zOrig = db_column_text(&q, 0);
1587
+ const char *zCkin = db_column_text(&q, 1);
1588
+ const char *zFN = db_column_text(&q, 2);
1589
+ style_submenu_element("Annotate",
1590
+ "%R/annotate?origin=%s&checkin=%s&filename=%T",
1591
+ zOrig, zCkin, zFN);
1592
+ }
1593
+ db_finalize(&q);
15681594
}
15691595
if( v1==0 || v2==0 ) fossil_redirect_home();
15701596
zRe = P("regex");
15711597
if( zRe ) re_compile(&pRe, zRe, 0);
15721598
if( verbose ) objdescFlags |= OBJDESC_DETAIL;
15731599
--- src/info.c
+++ src/info.c
@@ -1561,12 +1561,38 @@
1561 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1562 if( P("from") && P("to") ){
1563 v1 = artifact_from_ci_and_filename(0, "from");
1564 v2 = artifact_from_ci_and_filename(0, "to");
1565 }else{
 
1566 v1 = name_to_rid_www("v1");
1567 v2 = name_to_rid_www("v2");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1568 }
1569 if( v1==0 || v2==0 ) fossil_redirect_home();
1570 zRe = P("regex");
1571 if( zRe ) re_compile(&pRe, zRe, 0);
1572 if( verbose ) objdescFlags |= OBJDESC_DETAIL;
1573
--- src/info.c
+++ src/info.c
@@ -1561,12 +1561,38 @@
1561 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1562 if( P("from") && P("to") ){
1563 v1 = artifact_from_ci_and_filename(0, "from");
1564 v2 = artifact_from_ci_and_filename(0, "to");
1565 }else{
1566 Stmt q;
1567 v1 = name_to_rid_www("v1");
1568 v2 = name_to_rid_www("v2");
1569
1570 /* If the two file versions being compared both have the same
1571 ** filename, then offer an "Annotate" link that constructs an
1572 ** annotation between those version. */
1573 db_prepare(&q,
1574 "SELECT (SELECT substr(uuid,1,20) FROM blob WHERE rid=a.mid),"
1575 " (SELECT substr(uuid,1,20) FROM blob WHERE rid=b.mid),"
1576 " (SELECT name FROM filename WHERE filename.fnid=a.fnid)"
1577 " FROM mlink a, mlink b"
1578 " WHERE a.fid=%d"
1579 " AND b.fid=%d"
1580 " AND a.fnid=b.fnid"
1581 " AND a.fid!=a.pid"
1582 " AND b.fid!=b.pid",
1583 v1, v2
1584 );
1585 if( db_step(&q)==SQLITE_ROW ){
1586 const char *zOrig = db_column_text(&q, 0);
1587 const char *zCkin = db_column_text(&q, 1);
1588 const char *zFN = db_column_text(&q, 2);
1589 style_submenu_element("Annotate",
1590 "%R/annotate?origin=%s&checkin=%s&filename=%T",
1591 zOrig, zCkin, zFN);
1592 }
1593 db_finalize(&q);
1594 }
1595 if( v1==0 || v2==0 ) fossil_redirect_home();
1596 zRe = P("regex");
1597 if( zRe ) re_compile(&pRe, zRe, 0);
1598 if( verbose ) objdescFlags |= OBJDESC_DETAIL;
1599

Keyboard Shortcuts

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