Fossil SCM
On the "vinfo" page, add a link to a timeline of all other check-ins with the same tag.
Commit
fecb3e5cc90bf751160b0c6140da725a48f2a802
Parent
3b3116e4909ddca…
4 files changed
+30
+11
+1
-1
+14
-1
+30
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -212,5 +212,35 @@ | ||
| 212 | 212 | }else{ |
| 213 | 213 | fossil_panic("branch subcommand should be one of: " |
| 214 | 214 | "new list"); |
| 215 | 215 | } |
| 216 | 216 | } |
| 217 | + | |
| 218 | +/* | |
| 219 | +** WEBPAGE: brlist | |
| 220 | +** | |
| 221 | +** Show a timeline of all branches | |
| 222 | +*/ | |
| 223 | +void brlist_page(void){ | |
| 224 | + Stmt q; | |
| 225 | + | |
| 226 | + login_check_credentials(); | |
| 227 | + if( !g.okRead ){ login_needed(); return; } | |
| 228 | + | |
| 229 | + style_header("Branches"); | |
| 230 | + login_anonymous_available(); | |
| 231 | + db_prepare(&q, | |
| 232 | + "%s AND blob.rid IN (SELECT rid FROM tagxref WHERE tagtype>0 AND tagid=%d)" | |
| 233 | + " ORDER BY event.mtime DESC", | |
| 234 | + timeline_query_for_www(), TAG_NEWBRANCH | |
| 235 | + ); | |
| 236 | + www_print_timeline(&q); | |
| 237 | + db_finalize(&q); | |
| 238 | + @ <br clear="both"> | |
| 239 | + @ <script> | |
| 240 | + @ function xin(id){ | |
| 241 | + @ } | |
| 242 | + @ function xout(id){ | |
| 243 | + @ } | |
| 244 | + @ </script> | |
| 245 | + style_footer(); | |
| 246 | +} | |
| 217 | 247 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -212,5 +212,35 @@ | |
| 212 | }else{ |
| 213 | fossil_panic("branch subcommand should be one of: " |
| 214 | "new list"); |
| 215 | } |
| 216 | } |
| 217 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -212,5 +212,35 @@ | |
| 212 | }else{ |
| 213 | fossil_panic("branch subcommand should be one of: " |
| 214 | "new list"); |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | /* |
| 219 | ** WEBPAGE: brlist |
| 220 | ** |
| 221 | ** Show a timeline of all branches |
| 222 | */ |
| 223 | void brlist_page(void){ |
| 224 | Stmt q; |
| 225 | |
| 226 | login_check_credentials(); |
| 227 | if( !g.okRead ){ login_needed(); return; } |
| 228 | |
| 229 | style_header("Branches"); |
| 230 | login_anonymous_available(); |
| 231 | db_prepare(&q, |
| 232 | "%s AND blob.rid IN (SELECT rid FROM tagxref WHERE tagtype>0 AND tagid=%d)" |
| 233 | " ORDER BY event.mtime DESC", |
| 234 | timeline_query_for_www(), TAG_NEWBRANCH |
| 235 | ); |
| 236 | www_print_timeline(&q); |
| 237 | db_finalize(&q); |
| 238 | @ <br clear="both"> |
| 239 | @ <script> |
| 240 | @ function xin(id){ |
| 241 | @ } |
| 242 | @ function xout(id){ |
| 243 | @ } |
| 244 | @ </script> |
| 245 | style_footer(); |
| 246 | } |
| 247 |
+11
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -369,14 +369,25 @@ | ||
| 369 | 369 | } |
| 370 | 370 | @ </td></tr> |
| 371 | 371 | if( g.okHistory ){ |
| 372 | 372 | char *zShortUuid = mprintf("%.10s", zUuid); |
| 373 | 373 | const char *zProjName = db_get("project-name", "unnamed"); |
| 374 | + Stmt q; | |
| 374 | 375 | @ <tr><th>Timelines:</th><td> |
| 375 | 376 | @ <a href="%s(g.zBaseURL)/timeline?p=%d(rid)">ancestors</a> |
| 376 | 377 | @ | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)">descendants</a> |
| 377 | 378 | @ | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)&p=%d(rid)">both</a> |
| 379 | + db_prepare(&q, "SELECT tag.tagid, tag.tagname FROM tagxref, tag " | |
| 380 | + " WHERE rid=%d AND tagtype>0 " | |
| 381 | + " AND tag.tagid=tagxref.tagid " | |
| 382 | + " AND +tag.tagname GLOB 'sym-*'", rid); | |
| 383 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 384 | + int tagid = db_column_int(&q, 0); | |
| 385 | + const char *zTagName = db_column_text(&q, 1); | |
| 386 | + @ | <a href="%s(g.zBaseURL)/timeline?t=%d(tagid)">%h(&zTagName[4])</a> | |
| 387 | + } | |
| 388 | + db_finalize(&q); | |
| 378 | 389 | @ </td></tr> |
| 379 | 390 | @ <tr><th>Commands:</th> |
| 380 | 391 | @ <td> |
| 381 | 392 | @ <a href="%s(g.zBaseURL)/vdiff/%d(rid)">diff</a> |
| 382 | 393 | @ | <a href="%s(g.zBaseURL)/zip/%s(zProjName)-%s(zShortUuid).zip?uuid=%s(zUuid)"> |
| 383 | 394 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -369,14 +369,25 @@ | |
| 369 | } |
| 370 | @ </td></tr> |
| 371 | if( g.okHistory ){ |
| 372 | char *zShortUuid = mprintf("%.10s", zUuid); |
| 373 | const char *zProjName = db_get("project-name", "unnamed"); |
| 374 | @ <tr><th>Timelines:</th><td> |
| 375 | @ <a href="%s(g.zBaseURL)/timeline?p=%d(rid)">ancestors</a> |
| 376 | @ | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)">descendants</a> |
| 377 | @ | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)&p=%d(rid)">both</a> |
| 378 | @ </td></tr> |
| 379 | @ <tr><th>Commands:</th> |
| 380 | @ <td> |
| 381 | @ <a href="%s(g.zBaseURL)/vdiff/%d(rid)">diff</a> |
| 382 | @ | <a href="%s(g.zBaseURL)/zip/%s(zProjName)-%s(zShortUuid).zip?uuid=%s(zUuid)"> |
| 383 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -369,14 +369,25 @@ | |
| 369 | } |
| 370 | @ </td></tr> |
| 371 | if( g.okHistory ){ |
| 372 | char *zShortUuid = mprintf("%.10s", zUuid); |
| 373 | const char *zProjName = db_get("project-name", "unnamed"); |
| 374 | Stmt q; |
| 375 | @ <tr><th>Timelines:</th><td> |
| 376 | @ <a href="%s(g.zBaseURL)/timeline?p=%d(rid)">ancestors</a> |
| 377 | @ | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)">descendants</a> |
| 378 | @ | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)&p=%d(rid)">both</a> |
| 379 | db_prepare(&q, "SELECT tag.tagid, tag.tagname FROM tagxref, tag " |
| 380 | " WHERE rid=%d AND tagtype>0 " |
| 381 | " AND tag.tagid=tagxref.tagid " |
| 382 | " AND +tag.tagname GLOB 'sym-*'", rid); |
| 383 | while( db_step(&q)==SQLITE_ROW ){ |
| 384 | int tagid = db_column_int(&q, 0); |
| 385 | const char *zTagName = db_column_text(&q, 1); |
| 386 | @ | <a href="%s(g.zBaseURL)/timeline?t=%d(tagid)">%h(&zTagName[4])</a> |
| 387 | } |
| 388 | db_finalize(&q); |
| 389 | @ </td></tr> |
| 390 | @ <tr><th>Commands:</th> |
| 391 | @ <td> |
| 392 | @ <a href="%s(g.zBaseURL)/vdiff/%d(rid)">diff</a> |
| 393 | @ | <a href="%s(g.zBaseURL)/zip/%s(zProjName)-%s(zShortUuid).zip?uuid=%s(zUuid)"> |
| 394 |
+1
-1
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -193,11 +193,11 @@ | ||
| 193 | 193 | @ html "<a href='$baseurl/dir'>Files</a>" |
| 194 | 194 | @ } |
| 195 | 195 | @ if {[hascap o]} { |
| 196 | 196 | @ html "<a href='$baseurl/leaves'>Leaves</a>" |
| 197 | 197 | @ html "<a href='$baseurl/timeline'>Timeline</a>" |
| 198 | -@ html "<a href='$baseurl/tagview'>Tags</a>" | |
| 198 | +@ html "<a href='$baseurl/brlist'>Branches</a>" | |
| 199 | 199 | @ } |
| 200 | 200 | @ if {[hascap r]} { |
| 201 | 201 | @ html "<a href='$baseurl/reportlist'>Bugs</a>" |
| 202 | 202 | @ } |
| 203 | 203 | @ if {[hascap j]} { |
| 204 | 204 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -193,11 +193,11 @@ | |
| 193 | @ html "<a href='$baseurl/dir'>Files</a>" |
| 194 | @ } |
| 195 | @ if {[hascap o]} { |
| 196 | @ html "<a href='$baseurl/leaves'>Leaves</a>" |
| 197 | @ html "<a href='$baseurl/timeline'>Timeline</a>" |
| 198 | @ html "<a href='$baseurl/tagview'>Tags</a>" |
| 199 | @ } |
| 200 | @ if {[hascap r]} { |
| 201 | @ html "<a href='$baseurl/reportlist'>Bugs</a>" |
| 202 | @ } |
| 203 | @ if {[hascap j]} { |
| 204 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -193,11 +193,11 @@ | |
| 193 | @ html "<a href='$baseurl/dir'>Files</a>" |
| 194 | @ } |
| 195 | @ if {[hascap o]} { |
| 196 | @ html "<a href='$baseurl/leaves'>Leaves</a>" |
| 197 | @ html "<a href='$baseurl/timeline'>Timeline</a>" |
| 198 | @ html "<a href='$baseurl/brlist'>Branches</a>" |
| 199 | @ } |
| 200 | @ if {[hascap r]} { |
| 201 | @ html "<a href='$baseurl/reportlist'>Bugs</a>" |
| 202 | @ } |
| 203 | @ if {[hascap j]} { |
| 204 |
+14
-1
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -270,10 +270,11 @@ | ||
| 270 | 270 | ** a=TIMESTAMP after this date |
| 271 | 271 | ** b=TIMESTAMP before this date. |
| 272 | 272 | ** n=COUNT number of events in output |
| 273 | 273 | ** p=RID artifact RID and up to COUNT parents and ancestors |
| 274 | 274 | ** d=RID artifact RID and up to COUNT descendants |
| 275 | +** t=TAGID show only check-ins with the given tagid | |
| 275 | 276 | ** u=USER only if belonging to this user |
| 276 | 277 | ** y=TYPE 'ci', 'w', 't' |
| 277 | 278 | ** |
| 278 | 279 | ** p= and d= can appear individually or together. If either p= or d= |
| 279 | 280 | ** appear, then u=, y=, a=, and b= are ignored. |
| @@ -288,10 +289,11 @@ | ||
| 288 | 289 | Blob sql; /* text of SQL used to generate timeline */ |
| 289 | 290 | Blob desc; /* Description of the timeline */ |
| 290 | 291 | int nEntry = atoi(PD("n","20")); /* Max number of entries on timeline */ |
| 291 | 292 | int p_rid = atoi(PD("p","0")); /* artifact p and its parents */ |
| 292 | 293 | int d_rid = atoi(PD("d","0")); /* artifact d and its descendants */ |
| 294 | + int tagid = atoi(PD("t","0")); /* Show checkins of a given tag */ | |
| 293 | 295 | const char *zUser = P("u"); /* All entries by this user if not NULL */ |
| 294 | 296 | const char *zType = PD("y","all"); /* Type of events. All if NULL */ |
| 295 | 297 | const char *zAfter = P("a"); /* Events after this time */ |
| 296 | 298 | const char *zBefore = P("b"); /* Events before this time */ |
| 297 | 299 | HQuery url; /* URL for various branch links */ |
| @@ -343,11 +345,22 @@ | ||
| 343 | 345 | blob_appendf(&desc, " of <a href='%s/info/%s'>[%.10s]</a>", |
| 344 | 346 | g.zBaseURL, zUuid, zUuid); |
| 345 | 347 | }else{ |
| 346 | 348 | blob_appendf(&desc, " of [%.10s]", zUuid); |
| 347 | 349 | } |
| 348 | - db_prepare(&q, "SELECT * FROM timeline ORDER BY timestamp DESC"); | |
| 350 | + }else if( tagid>0 ){ | |
| 351 | + /* If t= is present, ignore all other parameters. Show everything | |
| 352 | + ** with that tag. */ | |
| 353 | + blob_appendf(&sql, " AND event.type='ci'"); | |
| 354 | + blob_appendf(&sql, " AND EXISTS (SELECT 1 FROM tagxref WHERE tagid=%d" | |
| 355 | + " AND tagtype>0 AND rid=blob.rid)", | |
| 356 | + tagid); | |
| 357 | + db_multi_exec("%s", blob_str(&sql)); | |
| 358 | + blob_appendf(&desc, "All check-ins tagged with \"%h\"", | |
| 359 | + db_text("??", "SELECT substr(tagname,5) FROM tag WHERE tagid=%d", | |
| 360 | + tagid) | |
| 361 | + ); | |
| 349 | 362 | }else{ |
| 350 | 363 | int n; |
| 351 | 364 | const char *zEType = "event"; |
| 352 | 365 | char *zDate; |
| 353 | 366 | char *zNEntry = mprintf("%d", nEntry); |
| 354 | 367 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -270,10 +270,11 @@ | |
| 270 | ** a=TIMESTAMP after this date |
| 271 | ** b=TIMESTAMP before this date. |
| 272 | ** n=COUNT number of events in output |
| 273 | ** p=RID artifact RID and up to COUNT parents and ancestors |
| 274 | ** d=RID artifact RID and up to COUNT descendants |
| 275 | ** u=USER only if belonging to this user |
| 276 | ** y=TYPE 'ci', 'w', 't' |
| 277 | ** |
| 278 | ** p= and d= can appear individually or together. If either p= or d= |
| 279 | ** appear, then u=, y=, a=, and b= are ignored. |
| @@ -288,10 +289,11 @@ | |
| 288 | Blob sql; /* text of SQL used to generate timeline */ |
| 289 | Blob desc; /* Description of the timeline */ |
| 290 | int nEntry = atoi(PD("n","20")); /* Max number of entries on timeline */ |
| 291 | int p_rid = atoi(PD("p","0")); /* artifact p and its parents */ |
| 292 | int d_rid = atoi(PD("d","0")); /* artifact d and its descendants */ |
| 293 | const char *zUser = P("u"); /* All entries by this user if not NULL */ |
| 294 | const char *zType = PD("y","all"); /* Type of events. All if NULL */ |
| 295 | const char *zAfter = P("a"); /* Events after this time */ |
| 296 | const char *zBefore = P("b"); /* Events before this time */ |
| 297 | HQuery url; /* URL for various branch links */ |
| @@ -343,11 +345,22 @@ | |
| 343 | blob_appendf(&desc, " of <a href='%s/info/%s'>[%.10s]</a>", |
| 344 | g.zBaseURL, zUuid, zUuid); |
| 345 | }else{ |
| 346 | blob_appendf(&desc, " of [%.10s]", zUuid); |
| 347 | } |
| 348 | db_prepare(&q, "SELECT * FROM timeline ORDER BY timestamp DESC"); |
| 349 | }else{ |
| 350 | int n; |
| 351 | const char *zEType = "event"; |
| 352 | char *zDate; |
| 353 | char *zNEntry = mprintf("%d", nEntry); |
| 354 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -270,10 +270,11 @@ | |
| 270 | ** a=TIMESTAMP after this date |
| 271 | ** b=TIMESTAMP before this date. |
| 272 | ** n=COUNT number of events in output |
| 273 | ** p=RID artifact RID and up to COUNT parents and ancestors |
| 274 | ** d=RID artifact RID and up to COUNT descendants |
| 275 | ** t=TAGID show only check-ins with the given tagid |
| 276 | ** u=USER only if belonging to this user |
| 277 | ** y=TYPE 'ci', 'w', 't' |
| 278 | ** |
| 279 | ** p= and d= can appear individually or together. If either p= or d= |
| 280 | ** appear, then u=, y=, a=, and b= are ignored. |
| @@ -288,10 +289,11 @@ | |
| 289 | Blob sql; /* text of SQL used to generate timeline */ |
| 290 | Blob desc; /* Description of the timeline */ |
| 291 | int nEntry = atoi(PD("n","20")); /* Max number of entries on timeline */ |
| 292 | int p_rid = atoi(PD("p","0")); /* artifact p and its parents */ |
| 293 | int d_rid = atoi(PD("d","0")); /* artifact d and its descendants */ |
| 294 | int tagid = atoi(PD("t","0")); /* Show checkins of a given tag */ |
| 295 | const char *zUser = P("u"); /* All entries by this user if not NULL */ |
| 296 | const char *zType = PD("y","all"); /* Type of events. All if NULL */ |
| 297 | const char *zAfter = P("a"); /* Events after this time */ |
| 298 | const char *zBefore = P("b"); /* Events before this time */ |
| 299 | HQuery url; /* URL for various branch links */ |
| @@ -343,11 +345,22 @@ | |
| 345 | blob_appendf(&desc, " of <a href='%s/info/%s'>[%.10s]</a>", |
| 346 | g.zBaseURL, zUuid, zUuid); |
| 347 | }else{ |
| 348 | blob_appendf(&desc, " of [%.10s]", zUuid); |
| 349 | } |
| 350 | }else if( tagid>0 ){ |
| 351 | /* If t= is present, ignore all other parameters. Show everything |
| 352 | ** with that tag. */ |
| 353 | blob_appendf(&sql, " AND event.type='ci'"); |
| 354 | blob_appendf(&sql, " AND EXISTS (SELECT 1 FROM tagxref WHERE tagid=%d" |
| 355 | " AND tagtype>0 AND rid=blob.rid)", |
| 356 | tagid); |
| 357 | db_multi_exec("%s", blob_str(&sql)); |
| 358 | blob_appendf(&desc, "All check-ins tagged with \"%h\"", |
| 359 | db_text("??", "SELECT substr(tagname,5) FROM tag WHERE tagid=%d", |
| 360 | tagid) |
| 361 | ); |
| 362 | }else{ |
| 363 | int n; |
| 364 | const char *zEType = "event"; |
| 365 | char *zDate; |
| 366 | char *zNEntry = mprintf("%d", nEntry); |
| 367 |