Fossil SCM

Add the "fossil bisect option linear on" command that allows the "fossil bisect run" command to invoke a test script on every check-in along a path between two boundary check-ins. The "linear" option resets automatically opon "fossil bisect reset".

drh 2022-06-05 19:43 trunk
Commit 42f61b677e451b1864676dca9481d32811b752921e0ff1247008b0d91b818340
3 files changed +8 -2 +10 +10
+8 -2
--- src/bisect.c
+++ src/bisect.c
@@ -81,10 +81,11 @@
8181
"skip\"" },
8282
{ "direct-only", "on", "Follow only primary parent-child links, not "
8383
"merges\n" },
8484
{ "display", "chart", "Command to run after \"next\". \"chart\", "
8585
"\"log\", \"status\", or \"none\"" },
86
+ { "linear", "off", "Do a linear scan rather than a true bisect" },
8687
};
8788
8889
/*
8990
** Return the value of a boolean bisect option.
9091
*/
@@ -375,11 +376,12 @@
375376
** Reset the bisect subsystem.
376377
*/
377378
void bisect_reset(void){
378379
db_multi_exec(
379380
"DELETE FROM vvar WHERE name IN "
380
- " ('bisect-good', 'bisect-bad', 'bisect-log', 'bisect-complete')"
381
+ " ('bisect-good', 'bisect-bad', 'bisect-log', 'bisect-complete',"
382
+ " 'bisect-linear')"
381383
);
382384
}
383385
384386
/*
385387
** fossil bisect run [OPTIONS] COMMAND
@@ -630,11 +632,15 @@
630632
if( strncmp(zCmd, "next", n)==0 ){
631633
PathNode *pMid;
632634
char *zDisplay = db_lget("bisect-display","chart");
633635
int m = (int)strlen(zDisplay);
634636
bisect_path();
635
- pMid = path_midpoint();
637
+ if( db_lget_boolean("bisect-linear",0) ){
638
+ pMid = path_next();
639
+ }else{
640
+ pMid = path_midpoint();
641
+ }
636642
if( pMid==0 ){
637643
fossil_print("bisect complete\n");
638644
db_lset_int("bisect-complete",1);
639645
}else{
640646
int nSpan = path_length_not_hidden();
641647
--- src/bisect.c
+++ src/bisect.c
@@ -81,10 +81,11 @@
81 "skip\"" },
82 { "direct-only", "on", "Follow only primary parent-child links, not "
83 "merges\n" },
84 { "display", "chart", "Command to run after \"next\". \"chart\", "
85 "\"log\", \"status\", or \"none\"" },
 
86 };
87
88 /*
89 ** Return the value of a boolean bisect option.
90 */
@@ -375,11 +376,12 @@
375 ** Reset the bisect subsystem.
376 */
377 void bisect_reset(void){
378 db_multi_exec(
379 "DELETE FROM vvar WHERE name IN "
380 " ('bisect-good', 'bisect-bad', 'bisect-log', 'bisect-complete')"
 
381 );
382 }
383
384 /*
385 ** fossil bisect run [OPTIONS] COMMAND
@@ -630,11 +632,15 @@
630 if( strncmp(zCmd, "next", n)==0 ){
631 PathNode *pMid;
632 char *zDisplay = db_lget("bisect-display","chart");
633 int m = (int)strlen(zDisplay);
634 bisect_path();
635 pMid = path_midpoint();
 
 
 
 
636 if( pMid==0 ){
637 fossil_print("bisect complete\n");
638 db_lset_int("bisect-complete",1);
639 }else{
640 int nSpan = path_length_not_hidden();
641
--- src/bisect.c
+++ src/bisect.c
@@ -81,10 +81,11 @@
81 "skip\"" },
82 { "direct-only", "on", "Follow only primary parent-child links, not "
83 "merges\n" },
84 { "display", "chart", "Command to run after \"next\". \"chart\", "
85 "\"log\", \"status\", or \"none\"" },
86 { "linear", "off", "Do a linear scan rather than a true bisect" },
87 };
88
89 /*
90 ** Return the value of a boolean bisect option.
91 */
@@ -375,11 +376,12 @@
376 ** Reset the bisect subsystem.
377 */
378 void bisect_reset(void){
379 db_multi_exec(
380 "DELETE FROM vvar WHERE name IN "
381 " ('bisect-good', 'bisect-bad', 'bisect-log', 'bisect-complete',"
382 " 'bisect-linear')"
383 );
384 }
385
386 /*
387 ** fossil bisect run [OPTIONS] COMMAND
@@ -630,11 +632,15 @@
632 if( strncmp(zCmd, "next", n)==0 ){
633 PathNode *pMid;
634 char *zDisplay = db_lget("bisect-display","chart");
635 int m = (int)strlen(zDisplay);
636 bisect_path();
637 if( db_lget_boolean("bisect-linear",0) ){
638 pMid = path_next();
639 }else{
640 pMid = path_midpoint();
641 }
642 if( pMid==0 ){
643 fossil_print("bisect complete\n");
644 db_lset_int("bisect-complete",1);
645 }else{
646 int nSpan = path_length_not_hidden();
647
+10
--- src/db.c
+++ src/db.c
@@ -3436,10 +3436,20 @@
34363436
void db_lset(const char *zName, const char *zValue){
34373437
db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%Q)", zName, zValue);
34383438
}
34393439
int db_lget_int(const char *zName, int dflt){
34403440
return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
3441
+}
3442
+int db_lget_boolean(const char *zName, int dflt){
3443
+ char *zVal = db_lget(zName, dflt ? "on" : "off");
3444
+ if( is_truth(zVal) ){
3445
+ dflt = 1;
3446
+ }else if( is_false(zVal) ){
3447
+ dflt = 0;
3448
+ }
3449
+ fossil_free(zVal);
3450
+ return dflt;
34413451
}
34423452
void db_lset_int(const char *zName, int value){
34433453
db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
34443454
}
34453455
34463456
--- src/db.c
+++ src/db.c
@@ -3436,10 +3436,20 @@
3436 void db_lset(const char *zName, const char *zValue){
3437 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%Q)", zName, zValue);
3438 }
3439 int db_lget_int(const char *zName, int dflt){
3440 return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
 
 
 
 
 
 
 
 
 
 
3441 }
3442 void db_lset_int(const char *zName, int value){
3443 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
3444 }
3445
3446
--- src/db.c
+++ src/db.c
@@ -3436,10 +3436,20 @@
3436 void db_lset(const char *zName, const char *zValue){
3437 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%Q)", zName, zValue);
3438 }
3439 int db_lget_int(const char *zName, int dflt){
3440 return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
3441 }
3442 int db_lget_boolean(const char *zName, int dflt){
3443 char *zVal = db_lget(zName, dflt ? "on" : "off");
3444 if( is_truth(zVal) ){
3445 dflt = 1;
3446 }else if( is_false(zVal) ){
3447 dflt = 0;
3448 }
3449 fossil_free(zVal);
3450 return dflt;
3451 }
3452 void db_lset_int(const char *zName, int value){
3453 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
3454 }
3455
3456
+10
--- src/path.c
+++ src/path.c
@@ -205,10 +205,20 @@
205205
for(p=path.pEnd, i=0; p && (p->isHidden || i<path.nNotHidden/2); p=p->pFrom){
206206
if( !p->isHidden ) i++;
207207
}
208208
return p;
209209
}
210
+
211
+/*
212
+** Find the next most recent node on a path.
213
+*/
214
+PathNode *path_next(void){
215
+ PathNode *p;
216
+ p = path.pStart;
217
+ if( p ) p = p->u.pTo;
218
+ return p;
219
+}
210220
211221
/*
212222
** Return an estimate of the number of comparisons remaining in order
213223
** to bisect path. This is based on the log2() of path.nStep.
214224
*/
215225
--- src/path.c
+++ src/path.c
@@ -205,10 +205,20 @@
205 for(p=path.pEnd, i=0; p && (p->isHidden || i<path.nNotHidden/2); p=p->pFrom){
206 if( !p->isHidden ) i++;
207 }
208 return p;
209 }
 
 
 
 
 
 
 
 
 
 
210
211 /*
212 ** Return an estimate of the number of comparisons remaining in order
213 ** to bisect path. This is based on the log2() of path.nStep.
214 */
215
--- src/path.c
+++ src/path.c
@@ -205,10 +205,20 @@
205 for(p=path.pEnd, i=0; p && (p->isHidden || i<path.nNotHidden/2); p=p->pFrom){
206 if( !p->isHidden ) i++;
207 }
208 return p;
209 }
210
211 /*
212 ** Find the next most recent node on a path.
213 */
214 PathNode *path_next(void){
215 PathNode *p;
216 p = path.pStart;
217 if( p ) p = p->u.pTo;
218 return p;
219 }
220
221 /*
222 ** Return an estimate of the number of comparisons remaining in order
223 ** to bisect path. This is based on the log2() of path.nStep.
224 */
225

Keyboard Shortcuts

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