Fossil SCM

Enhancements to the "bisect" command: Add "bisect log" and "bisect undo". The "bisect status" command is an alias for "bisect vlist". Show the adjacent good and bad versions on the final step of the bisect.

drh 2013-04-08 02:10 trunk
Commit 41c7ac29d7075ac003e1397d856d739a5b133493
1 file changed +140 -39
+140 -39
--- src/bisect.c
+++ src/bisect.c
@@ -35,23 +35,25 @@
3535
** Find the shortest path between bad and good.
3636
*/
3737
void bisect_path(void){
3838
PathNode *p;
3939
bisect.bad = db_lget_int("bisect-bad", 0);
40
- if( bisect.bad==0 ){
41
- fossil_fatal("no \"bad\" version has been identified");
42
- }
4340
bisect.good = db_lget_int("bisect-good", 0);
44
- if( bisect.good==0 ){
45
- fossil_fatal("no \"good\" version has been identified");
46
- }
47
- p = path_shortest(bisect.good, bisect.bad, bisect_option("direct-only"), 0);
48
- if( p==0 ){
49
- char *zBad = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", bisect.bad);
50
- char *zGood = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", bisect.good);
51
- fossil_fatal("no path from good ([%S]) to bad ([%S]) or back",
52
- zGood, zBad);
41
+ if( bisect.good>0 && bisect.bad==0 ){
42
+ path_shortest(bisect.good, bisect.good, 0, 0);
43
+ }else if( bisect.bad>0 && bisect.good==0 ){
44
+ path_shortest(bisect.bad, bisect.bad, 0, 0);
45
+ }else if( bisect.bad==0 && bisect.good==0 ){
46
+ fossil_fatal("neither \"good\" nor \"bad\" versions have been identified");
47
+ }else{
48
+ p = path_shortest(bisect.good, bisect.bad, bisect_option("direct-only"), 0);
49
+ if( p==0 ){
50
+ char *zBad = db_text(0,"SELECT uuid FROM blob WHERE rid=%d",bisect.bad);
51
+ char *zGood = db_text(0,"SELECT uuid FROM blob WHERE rid=%d",bisect.good);
52
+ fossil_fatal("no path from good ([%S]) to bad ([%S]) or back",
53
+ zGood, zBad);
54
+ }
5355
}
5456
}
5557
5658
/*
5759
** The set of all bisect options.
@@ -141,10 +143,32 @@
141143
}
142144
db_reset(&s);
143145
}
144146
db_finalize(&s);
145147
}
148
+
149
+/*
150
+** Append a new entry to the bisect log. Update the bisect-good or
151
+** bisect-bad values as appropriate.
152
+**
153
+** The bisect-log consists of a list of token. Each token is an
154
+** integer RID of a check-in. The RID is negative for "bad" check-ins
155
+** and positive for "good" check-ins.
156
+*/
157
+static void bisect_append_log(int rid){
158
+ if( rid<0 ){
159
+ if( db_lget_int("bisect-bad",0)==(-rid) ) return;
160
+ db_lset_int("bisect-bad", -rid);
161
+ }else{
162
+ if( db_lget_int("bisect-good",0)==rid ) return;
163
+ db_lset_int("bisect-good", rid);
164
+ }
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
+}
146170
147171
/*
148172
** COMMAND: bisect
149173
**
150174
** Usage: %fossil bisect SUBCOMMAND ...
@@ -159,10 +183,14 @@
159183
** fossil bisect good ?VERSION?
160184
**
161185
** Identify version VERSION as working. If VERSION is omitted,
162186
** the current checkout is marked as working.
163187
**
188
+** fossil bisect log
189
+**
190
+** Show a log of "good" and "bad" versions
191
+**
164192
** fossil bisect next
165193
**
166194
** Update to the next version that is halfway between the working and
167195
** non-working versions.
168196
**
@@ -174,72 +202,141 @@
174202
** fossil bisect reset
175203
**
176204
** Reinitialize a bisect session. This cancels prior bisect history
177205
** and allows a bisect session to start over from the beginning.
178206
**
179
-** fossil bisect vlist|ls ?--all?
207
+** fossil bisect vlist|ls|status ?--all?
180208
**
181209
** List the versions in between "bad" and "good".
210
+**
211
+** fossil bisect undo
212
+**
213
+** Undo the most recent "good" or "bad" command.
214
+**
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
182225
*/
183226
void bisect_cmd(void){
184227
int n;
185228
const char *zCmd;
229
+ int foundCmd = 0;
186230
db_must_be_within_tree();
187231
if( g.argc<3 ){
188
- usage("bisect SUBCOMMAND ARGS...");
232
+ usage("bad|good|log|next|options|reset|status|undo");
189233
}
190234
zCmd = g.argv[2];
191235
n = strlen(zCmd);
192236
if( n==0 ) zCmd = "-";
193237
if( memcmp(zCmd, "bad", n)==0 ){
194238
int ridBad;
239
+ foundCmd = 1;
195240
if( g.argc==3 ){
196241
ridBad = db_lget_int("checkout",0);
197242
}else{
198243
ridBad = name_to_typed_rid(g.argv[3], "ci");
199244
}
200
- db_lset_int("bisect-bad", ridBad);
201
- if( ridBad>0
202
- && bisect_option("auto-next")
203
- && db_lget_int("bisect-good",0)>0
204
- ){
205
- zCmd = "next";
206
- n = 4;
207
- }else{
208
- return;
245
+ if( ridBad>0 ){
246
+ bisect_append_log(-ridBad);
247
+ if( bisect_option("auto-next") && db_lget_int("bisect-good",0)>0 ){
248
+ zCmd = "next";
249
+ n = 4;
250
+ }
209251
}
210252
}else if( memcmp(zCmd, "good", n)==0 ){
211253
int ridGood;
254
+ foundCmd = 1;
212255
if( g.argc==3 ){
213256
ridGood = db_lget_int("checkout",0);
214257
}else{
215258
ridGood = name_to_typed_rid(g.argv[3], "ci");
216259
}
260
+ if( ridGood>0 ){
261
+ bisect_append_log(ridGood);
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
+ foundCmd = 1;
273
+ int cnt = 0, i;
274
+ db_begin_transaction();
275
+ zLog = db_lget("bisect-log","");
276
+ blob_init(&log, zLog, -1);
277
+ while( blob_token(&log, &id) ){ cnt++; }
278
+ if( cnt==0 ){
279
+ fossil_fatal("no previous bisect steps to undo");
280
+ }
281
+ blob_rewind(&log);
282
+ for(i=0; i<cnt-1; i++){
283
+ int rid;
284
+ blob_token(&log, &id);
285
+ rid = atoi(blob_str(&id));
286
+ if( rid<0 ) ridBad = -rid;
287
+ else ridGood = rid;
288
+ }
289
+ db_multi_exec(
290
+ "UPDATE vvar SET value=substr(value,1,%d) WHERE name='bisect-log'",
291
+ log.iCursor-1
292
+ );
293
+ db_lset_int("bisect-bad", ridBad);
217294
db_lset_int("bisect-good", ridGood);
218
- if( ridGood>0
219
- && bisect_option("auto-next")
220
- && db_lget_int("bisect-bad",0)>0
221
- ){
295
+ db_end_transaction(0);
296
+ if( ridBad && ridGood ){
222297
zCmd = "next";
223298
n = 4;
224
- }else{
225
- return;
226299
}
227300
}
301
+ /* No else here so that the above commands can morph themselves into
302
+ ** a "next" command */
228303
if( memcmp(zCmd, "next", n)==0 ){
229304
PathNode *pMid;
230305
bisect_path();
231306
pMid = path_midpoint();
232307
if( pMid==0 ){
233
- fossil_fatal("bisect is done - there are no more intermediate versions");
308
+ fossil_print("bisect complete\n");
309
+ }else{
310
+ g.argv[1] = "update";
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();
234315
}
235
- g.argv[1] = "update";
236
- g.argv[2] = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", pMid->rid);
237
- g.argc = 3;
238
- g.fNoSync = 1;
239
- update_cmd();
240316
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);
241338
}else if( memcmp(zCmd, "options", n)==0 ){
242339
if( g.argc==3 ){
243340
unsigned int i;
244341
for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){
245342
char *z = mprintf("bisect-%s", aBisectOption[i].zName);
@@ -268,14 +365,18 @@
268365
}else{
269366
usage("bisect option ?NAME? ?VALUE?");
270367
}
271368
}else if( memcmp(zCmd, "reset", n)==0 ){
272369
db_multi_exec(
273
- "DELETE FROM vvar WHERE name IN ('bisect-good', 'bisect-bad');"
370
+ "DELETE FROM vvar WHERE name IN "
371
+ " ('bisect-good', 'bisect-bad', 'bisect-log')"
274372
);
275
- }else if( memcmp(zCmd, "vlist", n)==0 || memcmp(zCmd, "ls", n)==0 ){
373
+ }else if( memcmp(zCmd, "vlist", n)==0
374
+ || memcmp(zCmd, "ls", n)==0
375
+ || memcmp(zCmd, "status", n)==0
376
+ ){
276377
int fAll = find_option("all", 0, 0)!=0;
277378
bisect_list(!fAll);
278
- }else{
279
- usage("bad|good|next|reset|vlist ...");
379
+ }else if( !foundCmd ){
380
+ usage("bad|good|log|next|options|reset|status|undo");
280381
}
281382
}
282383
--- src/bisect.c
+++ src/bisect.c
@@ -35,23 +35,25 @@
35 ** Find the shortest path between bad and good.
36 */
37 void bisect_path(void){
38 PathNode *p;
39 bisect.bad = db_lget_int("bisect-bad", 0);
40 if( bisect.bad==0 ){
41 fossil_fatal("no \"bad\" version has been identified");
42 }
43 bisect.good = db_lget_int("bisect-good", 0);
44 if( bisect.good==0 ){
45 fossil_fatal("no \"good\" version has been identified");
46 }
47 p = path_shortest(bisect.good, bisect.bad, bisect_option("direct-only"), 0);
48 if( p==0 ){
49 char *zBad = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", bisect.bad);
50 char *zGood = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", bisect.good);
51 fossil_fatal("no path from good ([%S]) to bad ([%S]) or back",
52 zGood, zBad);
 
 
 
 
 
53 }
54 }
55
56 /*
57 ** The set of all bisect options.
@@ -141,10 +143,32 @@
141 }
142 db_reset(&s);
143 }
144 db_finalize(&s);
145 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
147 /*
148 ** COMMAND: bisect
149 **
150 ** Usage: %fossil bisect SUBCOMMAND ...
@@ -159,10 +183,14 @@
159 ** fossil bisect good ?VERSION?
160 **
161 ** Identify version VERSION as working. If VERSION is omitted,
162 ** the current checkout is marked as working.
163 **
 
 
 
 
164 ** fossil bisect next
165 **
166 ** Update to the next version that is halfway between the working and
167 ** non-working versions.
168 **
@@ -174,72 +202,141 @@
174 ** fossil bisect reset
175 **
176 ** Reinitialize a bisect session. This cancels prior bisect history
177 ** and allows a bisect session to start over from the beginning.
178 **
179 ** fossil bisect vlist|ls ?--all?
180 **
181 ** List the versions in between "bad" and "good".
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182 */
183 void bisect_cmd(void){
184 int n;
185 const char *zCmd;
 
186 db_must_be_within_tree();
187 if( g.argc<3 ){
188 usage("bisect SUBCOMMAND ARGS...");
189 }
190 zCmd = g.argv[2];
191 n = strlen(zCmd);
192 if( n==0 ) zCmd = "-";
193 if( memcmp(zCmd, "bad", n)==0 ){
194 int ridBad;
 
195 if( g.argc==3 ){
196 ridBad = db_lget_int("checkout",0);
197 }else{
198 ridBad = name_to_typed_rid(g.argv[3], "ci");
199 }
200 db_lset_int("bisect-bad", ridBad);
201 if( ridBad>0
202 && bisect_option("auto-next")
203 && db_lget_int("bisect-good",0)>0
204 ){
205 zCmd = "next";
206 n = 4;
207 }else{
208 return;
209 }
210 }else if( memcmp(zCmd, "good", n)==0 ){
211 int ridGood;
 
212 if( g.argc==3 ){
213 ridGood = db_lget_int("checkout",0);
214 }else{
215 ridGood = name_to_typed_rid(g.argv[3], "ci");
216 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217 db_lset_int("bisect-good", ridGood);
218 if( ridGood>0
219 && bisect_option("auto-next")
220 && db_lget_int("bisect-bad",0)>0
221 ){
222 zCmd = "next";
223 n = 4;
224 }else{
225 return;
226 }
227 }
 
 
228 if( memcmp(zCmd, "next", n)==0 ){
229 PathNode *pMid;
230 bisect_path();
231 pMid = path_midpoint();
232 if( pMid==0 ){
233 fossil_fatal("bisect is done - there are no more intermediate versions");
 
 
 
 
 
 
234 }
235 g.argv[1] = "update";
236 g.argv[2] = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", pMid->rid);
237 g.argc = 3;
238 g.fNoSync = 1;
239 update_cmd();
240 bisect_list(1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241 }else if( memcmp(zCmd, "options", n)==0 ){
242 if( g.argc==3 ){
243 unsigned int i;
244 for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){
245 char *z = mprintf("bisect-%s", aBisectOption[i].zName);
@@ -268,14 +365,18 @@
268 }else{
269 usage("bisect option ?NAME? ?VALUE?");
270 }
271 }else if( memcmp(zCmd, "reset", n)==0 ){
272 db_multi_exec(
273 "DELETE FROM vvar WHERE name IN ('bisect-good', 'bisect-bad');"
 
274 );
275 }else if( memcmp(zCmd, "vlist", n)==0 || memcmp(zCmd, "ls", n)==0 ){
 
 
 
276 int fAll = find_option("all", 0, 0)!=0;
277 bisect_list(!fAll);
278 }else{
279 usage("bad|good|next|reset|vlist ...");
280 }
281 }
282
--- src/bisect.c
+++ src/bisect.c
@@ -35,23 +35,25 @@
35 ** Find the shortest path between bad and good.
36 */
37 void bisect_path(void){
38 PathNode *p;
39 bisect.bad = db_lget_int("bisect-bad", 0);
 
 
 
40 bisect.good = db_lget_int("bisect-good", 0);
41 if( bisect.good>0 && bisect.bad==0 ){
42 path_shortest(bisect.good, bisect.good, 0, 0);
43 }else if( bisect.bad>0 && bisect.good==0 ){
44 path_shortest(bisect.bad, bisect.bad, 0, 0);
45 }else if( bisect.bad==0 && bisect.good==0 ){
46 fossil_fatal("neither \"good\" nor \"bad\" versions have been identified");
47 }else{
48 p = path_shortest(bisect.good, bisect.bad, bisect_option("direct-only"), 0);
49 if( p==0 ){
50 char *zBad = db_text(0,"SELECT uuid FROM blob WHERE rid=%d",bisect.bad);
51 char *zGood = db_text(0,"SELECT uuid FROM blob WHERE rid=%d",bisect.good);
52 fossil_fatal("no path from good ([%S]) to bad ([%S]) or back",
53 zGood, zBad);
54 }
55 }
56 }
57
58 /*
59 ** The set of all bisect options.
@@ -141,10 +143,32 @@
143 }
144 db_reset(&s);
145 }
146 db_finalize(&s);
147 }
148
149 /*
150 ** Append a new entry to the bisect log. Update the bisect-good or
151 ** bisect-bad values as appropriate.
152 **
153 ** The bisect-log consists of a list of token. Each token is an
154 ** integer RID of a check-in. The RID is negative for "bad" check-ins
155 ** and positive for "good" check-ins.
156 */
157 static void bisect_append_log(int rid){
158 if( rid<0 ){
159 if( db_lget_int("bisect-bad",0)==(-rid) ) return;
160 db_lset_int("bisect-bad", -rid);
161 }else{
162 if( db_lget_int("bisect-good",0)==rid ) return;
163 db_lset_int("bisect-good", rid);
164 }
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 ...
@@ -159,10 +183,14 @@
183 ** fossil bisect good ?VERSION?
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.
196 **
@@ -174,72 +202,141 @@
202 ** fossil bisect reset
203 **
204 ** Reinitialize a bisect session. This cancels prior bisect history
205 ** and allows a bisect session to start over from the beginning.
206 **
207 ** fossil bisect vlist|ls|status ?--all?
208 **
209 ** List the versions in between "bad" and "good".
210 **
211 ** fossil bisect undo
212 **
213 ** Undo the most recent "good" or "bad" command.
214 **
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
225 */
226 void bisect_cmd(void){
227 int n;
228 const char *zCmd;
229 int foundCmd = 0;
230 db_must_be_within_tree();
231 if( g.argc<3 ){
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{
243 ridBad = name_to_typed_rid(g.argv[3], "ci");
244 }
245 if( ridBad>0 ){
246 bisect_append_log(-ridBad);
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{
258 ridGood = name_to_typed_rid(g.argv[3], "ci");
259 }
260 if( ridGood>0 ){
261 bisect_append_log(ridGood);
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 foundCmd = 1;
273 int cnt = 0, i;
274 db_begin_transaction();
275 zLog = db_lget("bisect-log","");
276 blob_init(&log, zLog, -1);
277 while( blob_token(&log, &id) ){ cnt++; }
278 if( cnt==0 ){
279 fossil_fatal("no previous bisect steps to undo");
280 }
281 blob_rewind(&log);
282 for(i=0; i<cnt-1; i++){
283 int rid;
284 blob_token(&log, &id);
285 rid = atoi(blob_str(&id));
286 if( rid<0 ) ridBad = -rid;
287 else ridGood = rid;
288 }
289 db_multi_exec(
290 "UPDATE vvar SET value=substr(value,1,%d) WHERE name='bisect-log'",
291 log.iCursor-1
292 );
293 db_lset_int("bisect-bad", ridBad);
294 db_lset_int("bisect-good", ridGood);
295 db_end_transaction(0);
296 if( ridBad && ridGood ){
 
 
297 zCmd = "next";
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{
310 g.argv[1] = "update";
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);
@@ -268,14 +365,18 @@
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", 0, 0)!=0;
378 bisect_list(!fAll);
379 }else if( !foundCmd ){
380 usage("bad|good|log|next|options|reset|status|undo");
381 }
382 }
383

Keyboard Shortcuts

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