Fossil SCM
Updates to the "bisect" command. Add "bisect chart". Add the "display" option to choose the display to occur after "bisect next". Default the display to "chart".
Commit
0a7af8d3a87cc966895f0bbfbd937515f6c662ec
Parent
c92f0a9afd7ae6d…
1 file changed
+81
-32
+81
-32
| --- src/bisect.c | ||
| +++ src/bisect.c | ||
| @@ -65,10 +65,12 @@ | ||
| 65 | 65 | } aBisectOption[] = { |
| 66 | 66 | { "auto-next", "on", "Automatically run \"bisect next\" after each " |
| 67 | 67 | "\"bisect good\" or \"bisect bad\"" }, |
| 68 | 68 | { "direct-only", "on", "Follow only primary parent-child links, not " |
| 69 | 69 | "merges\n" }, |
| 70 | + { "display", "chart", "Command to run after \"next\". \"chart\", " | |
| 71 | + "\"log\", \"status\", or \"none\"" }, | |
| 70 | 72 | }; |
| 71 | 73 | |
| 72 | 74 | /* |
| 73 | 75 | ** Return the value of a boolean bisect option. |
| 74 | 76 | */ |
| @@ -165,10 +167,61 @@ | ||
| 165 | 167 | db_multi_exec( |
| 166 | 168 | "REPLACE INTO vvar(name,value) VALUES('bisect-log'," |
| 167 | 169 | "COALESCE((SELECT value||' ' FROM vvar WHERE name='bisect-log'),'')" |
| 168 | 170 | " || '%d')", rid); |
| 169 | 171 | } |
| 172 | + | |
| 173 | +/* | |
| 174 | +** Show a chart of bisect "good" and "bad" versions. The chart can be | |
| 175 | +** sorted either chronologically by bisect time, or by check-in time. | |
| 176 | +*/ | |
| 177 | +static void bisect_chart(int sortByCkinTime){ | |
| 178 | + char *zLog = db_lget("bisect-log",""); | |
| 179 | + Blob log, id; | |
| 180 | + Stmt q; | |
| 181 | + int cnt = 0; | |
| 182 | + blob_init(&log, zLog, -1); | |
| 183 | + db_multi_exec( | |
| 184 | + "CREATE TEMP TABLE bilog(" | |
| 185 | + " seq INTEGER PRIMARY KEY," /* Sequence of events */ | |
| 186 | + " stat TEXT," /* Type of occurrence */ | |
| 187 | + " rid INTEGER" /* Check-in number */ | |
| 188 | + ");" | |
| 189 | + ); | |
| 190 | + db_prepare(&q, "INSERT OR IGNORE INTO bilog(seq,stat,rid)" | |
| 191 | + " VALUES(:seq,:stat,:rid)"); | |
| 192 | + while( blob_token(&log, &id) ){ | |
| 193 | + int rid = atoi(blob_str(&id)); | |
| 194 | + db_bind_int(&q, ":seq", ++cnt); | |
| 195 | + db_bind_text(&q, ":stat", rid>0 ? "GOOD" : "BAD"); | |
| 196 | + db_bind_int(&q, ":rid", rid>=0 ? rid : -rid); | |
| 197 | + db_step(&q); | |
| 198 | + db_reset(&q); | |
| 199 | + } | |
| 200 | + db_bind_int(&q, ":seq", ++cnt); | |
| 201 | + db_bind_text(&q, ":stat", "CURRENT"); | |
| 202 | + db_bind_int(&q, ":rid", db_lget_int("checkout", 0)); | |
| 203 | + db_step(&q); | |
| 204 | + db_finalize(&q); | |
| 205 | + db_prepare(&q, | |
| 206 | + "SELECT bilog.seq, bilog.stat," | |
| 207 | + " substr(blob.uuid,1,16), datetime(event.mtime)" | |
| 208 | + " FROM bilog, blob, event" | |
| 209 | + " WHERE blob.rid=bilog.rid AND event.objid=bilog.rid" | |
| 210 | + " AND event.type='ci'" | |
| 211 | + " ORDER BY %s", | |
| 212 | + (sortByCkinTime ? "event.mtime DESC" : "bilog.rowid ASC") | |
| 213 | + ); | |
| 214 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 215 | + fossil_print("%3d %-7s %s %s\n", | |
| 216 | + db_column_int(&q, 0), | |
| 217 | + db_column_text(&q, 1), | |
| 218 | + db_column_text(&q, 3), | |
| 219 | + db_column_text(&q, 2)); | |
| 220 | + } | |
| 221 | + db_finalize(&q); | |
| 222 | +} | |
| 170 | 223 | |
| 171 | 224 | /* |
| 172 | 225 | ** COMMAND: bisect |
| 173 | 226 | ** |
| 174 | 227 | ** Usage: %fossil bisect SUBCOMMAND ... |
| @@ -184,12 +237,15 @@ | ||
| 184 | 237 | ** |
| 185 | 238 | ** Identify version VERSION as working. If VERSION is omitted, |
| 186 | 239 | ** the current checkout is marked as working. |
| 187 | 240 | ** |
| 188 | 241 | ** fossil bisect log |
| 242 | +** fossil bisect chart | |
| 189 | 243 | ** |
| 190 | -** Show a log of "good" and "bad" versions | |
| 244 | +** Show a log of "good" and "bad" versions. "bisect log" shows the | |
| 245 | +** events in the order that they were tested. "bisect chart" shows | |
| 246 | +** them in order of check-in. | |
| 191 | 247 | ** |
| 192 | 248 | ** fossil bisect next |
| 193 | 249 | ** |
| 194 | 250 | ** Update to the next version that is halfway between the working and |
| 195 | 251 | ** non-working versions. |
| @@ -215,10 +271,11 @@ | ||
| 215 | 271 | ** Summary: |
| 216 | 272 | ** |
| 217 | 273 | ** fossil bisect bad ?VERSION? |
| 218 | 274 | ** fossil bisect good ?VERSION? |
| 219 | 275 | ** fossil bisect log |
| 276 | +** fossil bisect chart | |
| 220 | 277 | ** fossil bisect next |
| 221 | 278 | ** fossil bisect options |
| 222 | 279 | ** fossil bisect reset |
| 223 | 280 | ** fossil bisect status |
| 224 | 281 | ** fossil bisect undo |
| @@ -232,11 +289,11 @@ | ||
| 232 | 289 | usage("bad|good|log|next|options|reset|status|undo"); |
| 233 | 290 | } |
| 234 | 291 | zCmd = g.argv[2]; |
| 235 | 292 | n = strlen(zCmd); |
| 236 | 293 | if( n==0 ) zCmd = "-"; |
| 237 | - if( memcmp(zCmd, "bad", n)==0 ){ | |
| 294 | + if( strncmp(zCmd, "bad", n)==0 ){ | |
| 238 | 295 | int ridBad; |
| 239 | 296 | foundCmd = 1; |
| 240 | 297 | if( g.argc==3 ){ |
| 241 | 298 | ridBad = db_lget_int("checkout",0); |
| 242 | 299 | }else{ |
| @@ -247,11 +304,11 @@ | ||
| 247 | 304 | if( bisect_option("auto-next") && db_lget_int("bisect-good",0)>0 ){ |
| 248 | 305 | zCmd = "next"; |
| 249 | 306 | n = 4; |
| 250 | 307 | } |
| 251 | 308 | } |
| 252 | - }else if( memcmp(zCmd, "good", n)==0 ){ | |
| 309 | + }else if( strncmp(zCmd, "good", n)==0 ){ | |
| 253 | 310 | int ridGood; |
| 254 | 311 | foundCmd = 1; |
| 255 | 312 | if( g.argc==3 ){ |
| 256 | 313 | ridGood = db_lget_int("checkout",0); |
| 257 | 314 | }else{ |
| @@ -262,11 +319,11 @@ | ||
| 262 | 319 | if( bisect_option("auto-next") && db_lget_int("bisect-bad",0)>0 ){ |
| 263 | 320 | zCmd = "next"; |
| 264 | 321 | n = 4; |
| 265 | 322 | } |
| 266 | 323 | } |
| 267 | - }else if( memcmp(zCmd, "undo", n)==0 ){ | |
| 324 | + }else if( strncmp(zCmd, "undo", n)==0 ){ | |
| 268 | 325 | char *zLog; |
| 269 | 326 | Blob log, id; |
| 270 | 327 | int ridBad = 0; |
| 271 | 328 | int ridGood = 0; |
| 272 | 329 | int cnt = 0, i; |
| @@ -298,12 +355,14 @@ | ||
| 298 | 355 | n = 4; |
| 299 | 356 | } |
| 300 | 357 | } |
| 301 | 358 | /* No else here so that the above commands can morph themselves into |
| 302 | 359 | ** a "next" command */ |
| 303 | - if( memcmp(zCmd, "next", n)==0 ){ | |
| 360 | + if( strncmp(zCmd, "next", n)==0 ){ | |
| 304 | 361 | PathNode *pMid; |
| 362 | + char *zDisplay = db_lget("bisect-display","chart"); | |
| 363 | + int m = (int)strlen(zDisplay); | |
| 305 | 364 | bisect_path(); |
| 306 | 365 | pMid = path_midpoint(); |
| 307 | 366 | if( pMid==0 ){ |
| 308 | 367 | fossil_print("bisect complete\n"); |
| 309 | 368 | }else{ |
| @@ -311,33 +370,23 @@ | ||
| 311 | 370 | g.argv[2] = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", pMid->rid); |
| 312 | 371 | g.argc = 3; |
| 313 | 372 | g.fNoSync = 1; |
| 314 | 373 | update_cmd(); |
| 315 | 374 | } |
| 316 | - bisect_list(1); | |
| 317 | - }else if( memcmp(zCmd, "log", n)==0 ){ | |
| 318 | - char *zLog = db_lget("bisect-log",""); | |
| 319 | - Blob log, id; | |
| 320 | - Stmt q; | |
| 321 | - int cnt = 0; | |
| 322 | - blob_init(&log, zLog, -1); | |
| 323 | - db_prepare(&q, "SELECT substr(blob.uuid,1,16), datetime(event.mtime)" | |
| 324 | - " FROM blob, event" | |
| 325 | - " WHERE blob.rid=:rid AND event.objid=:rid" | |
| 326 | - " AND event.type='ci'"); | |
| 327 | - while( blob_token(&log, &id) ){ | |
| 328 | - int rid = atoi(blob_str(&id)); | |
| 329 | - db_bind_int(&q, ":rid", rid<0 ? -rid : rid); | |
| 330 | - if( db_step(&q)==SQLITE_ROW ){ | |
| 331 | - cnt++; | |
| 332 | - fossil_print("%3d %-4s %s %s\n", cnt, rid<0 ? "BAD" : "GOOD", | |
| 333 | - db_column_text(&q, 1), db_column_text(&q, 0)); | |
| 334 | - } | |
| 335 | - db_reset(&q); | |
| 336 | - } | |
| 337 | - db_finalize(&q); | |
| 338 | - }else if( memcmp(zCmd, "options", n)==0 ){ | |
| 375 | + | |
| 376 | + if( strncmp(zDisplay,"chart",m)==0 ){ | |
| 377 | + bisect_chart(1); | |
| 378 | + }else if( strncmp(zDisplay, "log", m)==0 ){ | |
| 379 | + bisect_chart(0); | |
| 380 | + }else if( strncmp(zDisplay, "status", m)==0 ){ | |
| 381 | + bisect_list(1); | |
| 382 | + } | |
| 383 | + }else if( strncmp(zCmd, "log", n)==0 ){ | |
| 384 | + bisect_chart(0); | |
| 385 | + }else if( strncmp(zCmd, "chart", n)==0 ){ | |
| 386 | + bisect_chart(1); | |
| 387 | + }else if( strncmp(zCmd, "options", n)==0 ){ | |
| 339 | 388 | if( g.argc==3 ){ |
| 340 | 389 | unsigned int i; |
| 341 | 390 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 342 | 391 | char *z = mprintf("bisect-%s", aBisectOption[i].zName); |
| 343 | 392 | fossil_print(" %-15s %-6s ", aBisectOption[i].zName, |
| @@ -363,20 +412,20 @@ | ||
| 363 | 412 | fossil_fatal("no such bisect option: %s", g.argv[3]); |
| 364 | 413 | } |
| 365 | 414 | }else{ |
| 366 | 415 | usage("bisect option ?NAME? ?VALUE?"); |
| 367 | 416 | } |
| 368 | - }else if( memcmp(zCmd, "reset", n)==0 ){ | |
| 417 | + }else if( strncmp(zCmd, "reset", n)==0 ){ | |
| 369 | 418 | db_multi_exec( |
| 370 | 419 | "DELETE FROM vvar WHERE name IN " |
| 371 | 420 | " ('bisect-good', 'bisect-bad', 'bisect-log')" |
| 372 | 421 | ); |
| 373 | - }else if( memcmp(zCmd, "vlist", n)==0 | |
| 374 | - || memcmp(zCmd, "ls", n)==0 | |
| 375 | - || memcmp(zCmd, "status", n)==0 | |
| 422 | + }else if( strncmp(zCmd, "vlist", n)==0 | |
| 423 | + || strncmp(zCmd, "ls", n)==0 | |
| 424 | + || strncmp(zCmd, "status", n)==0 | |
| 376 | 425 | ){ |
| 377 | 426 | int fAll = find_option("all", "a", 0)!=0; |
| 378 | 427 | bisect_list(!fAll); |
| 379 | 428 | }else if( !foundCmd ){ |
| 380 | 429 | usage("bad|good|log|next|options|reset|status|undo"); |
| 381 | 430 | } |
| 382 | 431 | } |
| 383 | 432 |
| --- src/bisect.c | |
| +++ src/bisect.c | |
| @@ -65,10 +65,12 @@ | |
| 65 | } aBisectOption[] = { |
| 66 | { "auto-next", "on", "Automatically run \"bisect next\" after each " |
| 67 | "\"bisect good\" or \"bisect bad\"" }, |
| 68 | { "direct-only", "on", "Follow only primary parent-child links, not " |
| 69 | "merges\n" }, |
| 70 | }; |
| 71 | |
| 72 | /* |
| 73 | ** Return the value of a boolean bisect option. |
| 74 | */ |
| @@ -165,10 +167,61 @@ | |
| 165 | db_multi_exec( |
| 166 | "REPLACE INTO vvar(name,value) VALUES('bisect-log'," |
| 167 | "COALESCE((SELECT value||' ' FROM vvar WHERE name='bisect-log'),'')" |
| 168 | " || '%d')", rid); |
| 169 | } |
| 170 | |
| 171 | /* |
| 172 | ** COMMAND: bisect |
| 173 | ** |
| 174 | ** Usage: %fossil bisect SUBCOMMAND ... |
| @@ -184,12 +237,15 @@ | |
| 184 | ** |
| 185 | ** Identify version VERSION as working. If VERSION is omitted, |
| 186 | ** the current checkout is marked as working. |
| 187 | ** |
| 188 | ** fossil bisect log |
| 189 | ** |
| 190 | ** Show a log of "good" and "bad" versions |
| 191 | ** |
| 192 | ** fossil bisect next |
| 193 | ** |
| 194 | ** Update to the next version that is halfway between the working and |
| 195 | ** non-working versions. |
| @@ -215,10 +271,11 @@ | |
| 215 | ** Summary: |
| 216 | ** |
| 217 | ** fossil bisect bad ?VERSION? |
| 218 | ** fossil bisect good ?VERSION? |
| 219 | ** fossil bisect log |
| 220 | ** fossil bisect next |
| 221 | ** fossil bisect options |
| 222 | ** fossil bisect reset |
| 223 | ** fossil bisect status |
| 224 | ** fossil bisect undo |
| @@ -232,11 +289,11 @@ | |
| 232 | usage("bad|good|log|next|options|reset|status|undo"); |
| 233 | } |
| 234 | zCmd = g.argv[2]; |
| 235 | n = strlen(zCmd); |
| 236 | if( n==0 ) zCmd = "-"; |
| 237 | if( memcmp(zCmd, "bad", n)==0 ){ |
| 238 | int ridBad; |
| 239 | foundCmd = 1; |
| 240 | if( g.argc==3 ){ |
| 241 | ridBad = db_lget_int("checkout",0); |
| 242 | }else{ |
| @@ -247,11 +304,11 @@ | |
| 247 | if( bisect_option("auto-next") && db_lget_int("bisect-good",0)>0 ){ |
| 248 | zCmd = "next"; |
| 249 | n = 4; |
| 250 | } |
| 251 | } |
| 252 | }else if( memcmp(zCmd, "good", n)==0 ){ |
| 253 | int ridGood; |
| 254 | foundCmd = 1; |
| 255 | if( g.argc==3 ){ |
| 256 | ridGood = db_lget_int("checkout",0); |
| 257 | }else{ |
| @@ -262,11 +319,11 @@ | |
| 262 | if( bisect_option("auto-next") && db_lget_int("bisect-bad",0)>0 ){ |
| 263 | zCmd = "next"; |
| 264 | n = 4; |
| 265 | } |
| 266 | } |
| 267 | }else if( memcmp(zCmd, "undo", n)==0 ){ |
| 268 | char *zLog; |
| 269 | Blob log, id; |
| 270 | int ridBad = 0; |
| 271 | int ridGood = 0; |
| 272 | int cnt = 0, i; |
| @@ -298,12 +355,14 @@ | |
| 298 | n = 4; |
| 299 | } |
| 300 | } |
| 301 | /* No else here so that the above commands can morph themselves into |
| 302 | ** a "next" command */ |
| 303 | if( memcmp(zCmd, "next", n)==0 ){ |
| 304 | PathNode *pMid; |
| 305 | bisect_path(); |
| 306 | pMid = path_midpoint(); |
| 307 | if( pMid==0 ){ |
| 308 | fossil_print("bisect complete\n"); |
| 309 | }else{ |
| @@ -311,33 +370,23 @@ | |
| 311 | g.argv[2] = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", pMid->rid); |
| 312 | g.argc = 3; |
| 313 | g.fNoSync = 1; |
| 314 | update_cmd(); |
| 315 | } |
| 316 | bisect_list(1); |
| 317 | }else if( memcmp(zCmd, "log", n)==0 ){ |
| 318 | char *zLog = db_lget("bisect-log",""); |
| 319 | Blob log, id; |
| 320 | Stmt q; |
| 321 | int cnt = 0; |
| 322 | blob_init(&log, zLog, -1); |
| 323 | db_prepare(&q, "SELECT substr(blob.uuid,1,16), datetime(event.mtime)" |
| 324 | " FROM blob, event" |
| 325 | " WHERE blob.rid=:rid AND event.objid=:rid" |
| 326 | " AND event.type='ci'"); |
| 327 | while( blob_token(&log, &id) ){ |
| 328 | int rid = atoi(blob_str(&id)); |
| 329 | db_bind_int(&q, ":rid", rid<0 ? -rid : rid); |
| 330 | if( db_step(&q)==SQLITE_ROW ){ |
| 331 | cnt++; |
| 332 | fossil_print("%3d %-4s %s %s\n", cnt, rid<0 ? "BAD" : "GOOD", |
| 333 | db_column_text(&q, 1), db_column_text(&q, 0)); |
| 334 | } |
| 335 | db_reset(&q); |
| 336 | } |
| 337 | db_finalize(&q); |
| 338 | }else if( memcmp(zCmd, "options", n)==0 ){ |
| 339 | if( g.argc==3 ){ |
| 340 | unsigned int i; |
| 341 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 342 | char *z = mprintf("bisect-%s", aBisectOption[i].zName); |
| 343 | fossil_print(" %-15s %-6s ", aBisectOption[i].zName, |
| @@ -363,20 +412,20 @@ | |
| 363 | fossil_fatal("no such bisect option: %s", g.argv[3]); |
| 364 | } |
| 365 | }else{ |
| 366 | usage("bisect option ?NAME? ?VALUE?"); |
| 367 | } |
| 368 | }else if( memcmp(zCmd, "reset", n)==0 ){ |
| 369 | db_multi_exec( |
| 370 | "DELETE FROM vvar WHERE name IN " |
| 371 | " ('bisect-good', 'bisect-bad', 'bisect-log')" |
| 372 | ); |
| 373 | }else if( memcmp(zCmd, "vlist", n)==0 |
| 374 | || memcmp(zCmd, "ls", n)==0 |
| 375 | || memcmp(zCmd, "status", n)==0 |
| 376 | ){ |
| 377 | int fAll = find_option("all", "a", 0)!=0; |
| 378 | bisect_list(!fAll); |
| 379 | }else if( !foundCmd ){ |
| 380 | usage("bad|good|log|next|options|reset|status|undo"); |
| 381 | } |
| 382 | } |
| 383 |
| --- src/bisect.c | |
| +++ src/bisect.c | |
| @@ -65,10 +65,12 @@ | |
| 65 | } aBisectOption[] = { |
| 66 | { "auto-next", "on", "Automatically run \"bisect next\" after each " |
| 67 | "\"bisect good\" or \"bisect bad\"" }, |
| 68 | { "direct-only", "on", "Follow only primary parent-child links, not " |
| 69 | "merges\n" }, |
| 70 | { "display", "chart", "Command to run after \"next\". \"chart\", " |
| 71 | "\"log\", \"status\", or \"none\"" }, |
| 72 | }; |
| 73 | |
| 74 | /* |
| 75 | ** Return the value of a boolean bisect option. |
| 76 | */ |
| @@ -165,10 +167,61 @@ | |
| 167 | db_multi_exec( |
| 168 | "REPLACE INTO vvar(name,value) VALUES('bisect-log'," |
| 169 | "COALESCE((SELECT value||' ' FROM vvar WHERE name='bisect-log'),'')" |
| 170 | " || '%d')", rid); |
| 171 | } |
| 172 | |
| 173 | /* |
| 174 | ** Show a chart of bisect "good" and "bad" versions. The chart can be |
| 175 | ** sorted either chronologically by bisect time, or by check-in time. |
| 176 | */ |
| 177 | static void bisect_chart(int sortByCkinTime){ |
| 178 | char *zLog = db_lget("bisect-log",""); |
| 179 | Blob log, id; |
| 180 | Stmt q; |
| 181 | int cnt = 0; |
| 182 | blob_init(&log, zLog, -1); |
| 183 | db_multi_exec( |
| 184 | "CREATE TEMP TABLE bilog(" |
| 185 | " seq INTEGER PRIMARY KEY," /* Sequence of events */ |
| 186 | " stat TEXT," /* Type of occurrence */ |
| 187 | " rid INTEGER" /* Check-in number */ |
| 188 | ");" |
| 189 | ); |
| 190 | db_prepare(&q, "INSERT OR IGNORE INTO bilog(seq,stat,rid)" |
| 191 | " VALUES(:seq,:stat,:rid)"); |
| 192 | while( blob_token(&log, &id) ){ |
| 193 | int rid = atoi(blob_str(&id)); |
| 194 | db_bind_int(&q, ":seq", ++cnt); |
| 195 | db_bind_text(&q, ":stat", rid>0 ? "GOOD" : "BAD"); |
| 196 | db_bind_int(&q, ":rid", rid>=0 ? rid : -rid); |
| 197 | db_step(&q); |
| 198 | db_reset(&q); |
| 199 | } |
| 200 | db_bind_int(&q, ":seq", ++cnt); |
| 201 | db_bind_text(&q, ":stat", "CURRENT"); |
| 202 | db_bind_int(&q, ":rid", db_lget_int("checkout", 0)); |
| 203 | db_step(&q); |
| 204 | db_finalize(&q); |
| 205 | db_prepare(&q, |
| 206 | "SELECT bilog.seq, bilog.stat," |
| 207 | " substr(blob.uuid,1,16), datetime(event.mtime)" |
| 208 | " FROM bilog, blob, event" |
| 209 | " WHERE blob.rid=bilog.rid AND event.objid=bilog.rid" |
| 210 | " AND event.type='ci'" |
| 211 | " ORDER BY %s", |
| 212 | (sortByCkinTime ? "event.mtime DESC" : "bilog.rowid ASC") |
| 213 | ); |
| 214 | while( db_step(&q)==SQLITE_ROW ){ |
| 215 | fossil_print("%3d %-7s %s %s\n", |
| 216 | db_column_int(&q, 0), |
| 217 | db_column_text(&q, 1), |
| 218 | db_column_text(&q, 3), |
| 219 | db_column_text(&q, 2)); |
| 220 | } |
| 221 | db_finalize(&q); |
| 222 | } |
| 223 | |
| 224 | /* |
| 225 | ** COMMAND: bisect |
| 226 | ** |
| 227 | ** Usage: %fossil bisect SUBCOMMAND ... |
| @@ -184,12 +237,15 @@ | |
| 237 | ** |
| 238 | ** Identify version VERSION as working. If VERSION is omitted, |
| 239 | ** the current checkout is marked as working. |
| 240 | ** |
| 241 | ** fossil bisect log |
| 242 | ** fossil bisect chart |
| 243 | ** |
| 244 | ** Show a log of "good" and "bad" versions. "bisect log" shows the |
| 245 | ** events in the order that they were tested. "bisect chart" shows |
| 246 | ** them in order of check-in. |
| 247 | ** |
| 248 | ** fossil bisect next |
| 249 | ** |
| 250 | ** Update to the next version that is halfway between the working and |
| 251 | ** non-working versions. |
| @@ -215,10 +271,11 @@ | |
| 271 | ** Summary: |
| 272 | ** |
| 273 | ** fossil bisect bad ?VERSION? |
| 274 | ** fossil bisect good ?VERSION? |
| 275 | ** fossil bisect log |
| 276 | ** fossil bisect chart |
| 277 | ** fossil bisect next |
| 278 | ** fossil bisect options |
| 279 | ** fossil bisect reset |
| 280 | ** fossil bisect status |
| 281 | ** fossil bisect undo |
| @@ -232,11 +289,11 @@ | |
| 289 | usage("bad|good|log|next|options|reset|status|undo"); |
| 290 | } |
| 291 | zCmd = g.argv[2]; |
| 292 | n = strlen(zCmd); |
| 293 | if( n==0 ) zCmd = "-"; |
| 294 | if( strncmp(zCmd, "bad", n)==0 ){ |
| 295 | int ridBad; |
| 296 | foundCmd = 1; |
| 297 | if( g.argc==3 ){ |
| 298 | ridBad = db_lget_int("checkout",0); |
| 299 | }else{ |
| @@ -247,11 +304,11 @@ | |
| 304 | if( bisect_option("auto-next") && db_lget_int("bisect-good",0)>0 ){ |
| 305 | zCmd = "next"; |
| 306 | n = 4; |
| 307 | } |
| 308 | } |
| 309 | }else if( strncmp(zCmd, "good", n)==0 ){ |
| 310 | int ridGood; |
| 311 | foundCmd = 1; |
| 312 | if( g.argc==3 ){ |
| 313 | ridGood = db_lget_int("checkout",0); |
| 314 | }else{ |
| @@ -262,11 +319,11 @@ | |
| 319 | if( bisect_option("auto-next") && db_lget_int("bisect-bad",0)>0 ){ |
| 320 | zCmd = "next"; |
| 321 | n = 4; |
| 322 | } |
| 323 | } |
| 324 | }else if( strncmp(zCmd, "undo", n)==0 ){ |
| 325 | char *zLog; |
| 326 | Blob log, id; |
| 327 | int ridBad = 0; |
| 328 | int ridGood = 0; |
| 329 | int cnt = 0, i; |
| @@ -298,12 +355,14 @@ | |
| 355 | n = 4; |
| 356 | } |
| 357 | } |
| 358 | /* No else here so that the above commands can morph themselves into |
| 359 | ** a "next" command */ |
| 360 | if( strncmp(zCmd, "next", n)==0 ){ |
| 361 | PathNode *pMid; |
| 362 | char *zDisplay = db_lget("bisect-display","chart"); |
| 363 | int m = (int)strlen(zDisplay); |
| 364 | bisect_path(); |
| 365 | pMid = path_midpoint(); |
| 366 | if( pMid==0 ){ |
| 367 | fossil_print("bisect complete\n"); |
| 368 | }else{ |
| @@ -311,33 +370,23 @@ | |
| 370 | g.argv[2] = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", pMid->rid); |
| 371 | g.argc = 3; |
| 372 | g.fNoSync = 1; |
| 373 | update_cmd(); |
| 374 | } |
| 375 | |
| 376 | if( strncmp(zDisplay,"chart",m)==0 ){ |
| 377 | bisect_chart(1); |
| 378 | }else if( strncmp(zDisplay, "log", m)==0 ){ |
| 379 | bisect_chart(0); |
| 380 | }else if( strncmp(zDisplay, "status", m)==0 ){ |
| 381 | bisect_list(1); |
| 382 | } |
| 383 | }else if( strncmp(zCmd, "log", n)==0 ){ |
| 384 | bisect_chart(0); |
| 385 | }else if( strncmp(zCmd, "chart", n)==0 ){ |
| 386 | bisect_chart(1); |
| 387 | }else if( strncmp(zCmd, "options", n)==0 ){ |
| 388 | if( g.argc==3 ){ |
| 389 | unsigned int i; |
| 390 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 391 | char *z = mprintf("bisect-%s", aBisectOption[i].zName); |
| 392 | fossil_print(" %-15s %-6s ", aBisectOption[i].zName, |
| @@ -363,20 +412,20 @@ | |
| 412 | fossil_fatal("no such bisect option: %s", g.argv[3]); |
| 413 | } |
| 414 | }else{ |
| 415 | usage("bisect option ?NAME? ?VALUE?"); |
| 416 | } |
| 417 | }else if( strncmp(zCmd, "reset", n)==0 ){ |
| 418 | db_multi_exec( |
| 419 | "DELETE FROM vvar WHERE name IN " |
| 420 | " ('bisect-good', 'bisect-bad', 'bisect-log')" |
| 421 | ); |
| 422 | }else if( strncmp(zCmd, "vlist", n)==0 |
| 423 | || strncmp(zCmd, "ls", n)==0 |
| 424 | || strncmp(zCmd, "status", n)==0 |
| 425 | ){ |
| 426 | int fAll = find_option("all", "a", 0)!=0; |
| 427 | bisect_list(!fAll); |
| 428 | }else if( !foundCmd ){ |
| 429 | usage("bad|good|log|next|options|reset|status|undo"); |
| 430 | } |
| 431 | } |
| 432 |