Fossil SCM
Enhancements to the "bisect" command: (1) Create alias "ls" for the "vlist" subcommand. (2) Show an abbreviated listing unless the --all option is used. (3) Automatically show the abbreviated listing after each "next".
Commit
eec11147cf1570c73b322d49799310bb2f512b5e
Parent
16371dcb1b5b487…
2 files changed
+61
-28
+1
+61
-28
| --- src/bisect.c | ||
| +++ src/bisect.c | ||
| @@ -85,10 +85,66 @@ | ||
| 85 | 85 | } |
| 86 | 86 | } |
| 87 | 87 | assert( r>=0 ); |
| 88 | 88 | return r; |
| 89 | 89 | } |
| 90 | + | |
| 91 | +/* | |
| 92 | +** List a bisect path. | |
| 93 | +*/ | |
| 94 | +static void bisect_list(int abbreviated){ | |
| 95 | + PathNode *p; | |
| 96 | + int vid = db_lget_int("checkout", 0); | |
| 97 | + int n; | |
| 98 | + Stmt s; | |
| 99 | + int nStep; | |
| 100 | + int nHidden = 0; | |
| 101 | + bisect_path(); | |
| 102 | + db_prepare(&s, "SELECT blob.uuid, datetime(event.mtime) " | |
| 103 | + " FROM blob, event" | |
| 104 | + " WHERE blob.rid=:rid AND event.objid=:rid" | |
| 105 | + " AND event.type='ci'"); | |
| 106 | + nStep = path_length(); | |
| 107 | + if( abbreviated ){ | |
| 108 | + for(p=path_last(); p; p=p->pFrom) p->isHidden = 1; | |
| 109 | + for(p=path_last(), n=0; p; p=p->pFrom, n++){ | |
| 110 | + if( p->rid==bisect.good | |
| 111 | + || p->rid==bisect.bad | |
| 112 | + || p->rid==vid | |
| 113 | + || (nStep>1 && n==nStep/2) | |
| 114 | + ){ | |
| 115 | + p->isHidden = 0; | |
| 116 | + if( p->pFrom ) p->pFrom->isHidden = 0; | |
| 117 | + } | |
| 118 | + } | |
| 119 | + for(p=path_last(); p; p=p->pFrom){ | |
| 120 | + if( p->pFrom && p->pFrom->isHidden==0 ) p->isHidden = 0; | |
| 121 | + } | |
| 122 | + } | |
| 123 | + for(p=path_last(), n=0; p; p=p->pFrom, n++){ | |
| 124 | + if( p->isHidden && (nHidden || (p->pFrom && p->pFrom->isHidden)) ){ | |
| 125 | + nHidden++; | |
| 126 | + continue; | |
| 127 | + }else if( nHidden ){ | |
| 128 | + fossil_print(" ... eliding %d check-ins\n", nHidden); | |
| 129 | + nHidden = 0; | |
| 130 | + } | |
| 131 | + db_bind_int(&s, ":rid", p->rid); | |
| 132 | + if( db_step(&s)==SQLITE_ROW ){ | |
| 133 | + const char *zUuid = db_column_text(&s, 0); | |
| 134 | + const char *zDate = db_column_text(&s, 1); | |
| 135 | + fossil_print("%s %S", zDate, zUuid); | |
| 136 | + if( p->rid==bisect.good ) fossil_print(" GOOD"); | |
| 137 | + if( p->rid==bisect.bad ) fossil_print(" BAD"); | |
| 138 | + if( p->rid==vid ) fossil_print(" CURRENT"); | |
| 139 | + if( nStep>1 && n==nStep/2 ) fossil_print(" NEXT"); | |
| 140 | + fossil_print("\n"); | |
| 141 | + } | |
| 142 | + db_reset(&s); | |
| 143 | + } | |
| 144 | + db_finalize(&s); | |
| 145 | +} | |
| 90 | 146 | |
| 91 | 147 | /* |
| 92 | 148 | ** COMMAND: bisect |
| 93 | 149 | ** |
| 94 | 150 | ** Usage: %fossil bisect SUBCOMMAND ... |
| @@ -118,11 +174,11 @@ | ||
| 118 | 174 | ** fossil bisect reset |
| 119 | 175 | ** |
| 120 | 176 | ** Reinitialize a bisect session. This cancels prior bisect history |
| 121 | 177 | ** and allows a bisect session to start over from the beginning. |
| 122 | 178 | ** |
| 123 | -** fossil bisect vlist | |
| 179 | +** fossil bisect vlist|ls ?--all? | |
| 124 | 180 | ** |
| 125 | 181 | ** List the versions in between "bad" and "good". |
| 126 | 182 | */ |
| 127 | 183 | void bisect_cmd(void){ |
| 128 | 184 | int n; |
| @@ -179,10 +235,11 @@ | ||
| 179 | 235 | g.argv[1] = "update"; |
| 180 | 236 | g.argv[2] = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", pMid->rid); |
| 181 | 237 | g.argc = 3; |
| 182 | 238 | g.fNoSync = 1; |
| 183 | 239 | update_cmd(); |
| 240 | + bisect_list(1); | |
| 184 | 241 | }else if( memcmp(zCmd, "options", n)==0 ){ |
| 185 | 242 | if( g.argc==3 ){ |
| 186 | 243 | unsigned int i; |
| 187 | 244 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 188 | 245 | char *z = mprintf("bisect-%s", aBisectOption[i].zName); |
| @@ -213,36 +270,12 @@ | ||
| 213 | 270 | } |
| 214 | 271 | }else if( memcmp(zCmd, "reset", n)==0 ){ |
| 215 | 272 | db_multi_exec( |
| 216 | 273 | "DELETE FROM vvar WHERE name IN ('bisect-good', 'bisect-bad');" |
| 217 | 274 | ); |
| 218 | - }else if( memcmp(zCmd, "vlist", n)==0 ){ | |
| 219 | - PathNode *p; | |
| 220 | - int vid = db_lget_int("checkout", 0); | |
| 221 | - int n; | |
| 222 | - Stmt s; | |
| 223 | - int nStep; | |
| 224 | - bisect_path(); | |
| 225 | - db_prepare(&s, "SELECT substr(blob.uuid,1,20) || ' ' || " | |
| 226 | - " datetime(event.mtime) FROM blob, event" | |
| 227 | - " WHERE blob.rid=:rid AND event.objid=:rid" | |
| 228 | - " AND event.type='ci'"); | |
| 229 | - nStep = path_length(); | |
| 230 | - for(p=path_last(), n=0; p; p=p->pFrom, n++){ | |
| 231 | - const char *z; | |
| 232 | - db_bind_int(&s, ":rid", p->rid); | |
| 233 | - if( db_step(&s)==SQLITE_ROW ){ | |
| 234 | - z = db_column_text(&s, 0); | |
| 235 | - fossil_print("%s", z); | |
| 236 | - if( p->rid==bisect.good ) fossil_print(" GOOD"); | |
| 237 | - if( p->rid==bisect.bad ) fossil_print(" BAD"); | |
| 238 | - if( p->rid==vid ) fossil_print(" CURRENT"); | |
| 239 | - if( nStep>1 && n==nStep/2 ) fossil_print(" NEXT"); | |
| 240 | - fossil_print("\n"); | |
| 241 | - } | |
| 242 | - db_reset(&s); | |
| 243 | - } | |
| 244 | - db_finalize(&s); | |
| 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); | |
| 245 | 278 | }else{ |
| 246 | 279 | usage("bad|good|next|reset|vlist ..."); |
| 247 | 280 | } |
| 248 | 281 | } |
| 249 | 282 |
| --- src/bisect.c | |
| +++ src/bisect.c | |
| @@ -85,10 +85,66 @@ | |
| 85 | } |
| 86 | } |
| 87 | assert( r>=0 ); |
| 88 | return r; |
| 89 | } |
| 90 | |
| 91 | /* |
| 92 | ** COMMAND: bisect |
| 93 | ** |
| 94 | ** Usage: %fossil bisect SUBCOMMAND ... |
| @@ -118,11 +174,11 @@ | |
| 118 | ** fossil bisect reset |
| 119 | ** |
| 120 | ** Reinitialize a bisect session. This cancels prior bisect history |
| 121 | ** and allows a bisect session to start over from the beginning. |
| 122 | ** |
| 123 | ** fossil bisect vlist |
| 124 | ** |
| 125 | ** List the versions in between "bad" and "good". |
| 126 | */ |
| 127 | void bisect_cmd(void){ |
| 128 | int n; |
| @@ -179,10 +235,11 @@ | |
| 179 | g.argv[1] = "update"; |
| 180 | g.argv[2] = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", pMid->rid); |
| 181 | g.argc = 3; |
| 182 | g.fNoSync = 1; |
| 183 | update_cmd(); |
| 184 | }else if( memcmp(zCmd, "options", n)==0 ){ |
| 185 | if( g.argc==3 ){ |
| 186 | unsigned int i; |
| 187 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 188 | char *z = mprintf("bisect-%s", aBisectOption[i].zName); |
| @@ -213,36 +270,12 @@ | |
| 213 | } |
| 214 | }else if( memcmp(zCmd, "reset", n)==0 ){ |
| 215 | db_multi_exec( |
| 216 | "DELETE FROM vvar WHERE name IN ('bisect-good', 'bisect-bad');" |
| 217 | ); |
| 218 | }else if( memcmp(zCmd, "vlist", n)==0 ){ |
| 219 | PathNode *p; |
| 220 | int vid = db_lget_int("checkout", 0); |
| 221 | int n; |
| 222 | Stmt s; |
| 223 | int nStep; |
| 224 | bisect_path(); |
| 225 | db_prepare(&s, "SELECT substr(blob.uuid,1,20) || ' ' || " |
| 226 | " datetime(event.mtime) FROM blob, event" |
| 227 | " WHERE blob.rid=:rid AND event.objid=:rid" |
| 228 | " AND event.type='ci'"); |
| 229 | nStep = path_length(); |
| 230 | for(p=path_last(), n=0; p; p=p->pFrom, n++){ |
| 231 | const char *z; |
| 232 | db_bind_int(&s, ":rid", p->rid); |
| 233 | if( db_step(&s)==SQLITE_ROW ){ |
| 234 | z = db_column_text(&s, 0); |
| 235 | fossil_print("%s", z); |
| 236 | if( p->rid==bisect.good ) fossil_print(" GOOD"); |
| 237 | if( p->rid==bisect.bad ) fossil_print(" BAD"); |
| 238 | if( p->rid==vid ) fossil_print(" CURRENT"); |
| 239 | if( nStep>1 && n==nStep/2 ) fossil_print(" NEXT"); |
| 240 | fossil_print("\n"); |
| 241 | } |
| 242 | db_reset(&s); |
| 243 | } |
| 244 | db_finalize(&s); |
| 245 | }else{ |
| 246 | usage("bad|good|next|reset|vlist ..."); |
| 247 | } |
| 248 | } |
| 249 |
| --- src/bisect.c | |
| +++ src/bisect.c | |
| @@ -85,10 +85,66 @@ | |
| 85 | } |
| 86 | } |
| 87 | assert( r>=0 ); |
| 88 | return r; |
| 89 | } |
| 90 | |
| 91 | /* |
| 92 | ** List a bisect path. |
| 93 | */ |
| 94 | static void bisect_list(int abbreviated){ |
| 95 | PathNode *p; |
| 96 | int vid = db_lget_int("checkout", 0); |
| 97 | int n; |
| 98 | Stmt s; |
| 99 | int nStep; |
| 100 | int nHidden = 0; |
| 101 | bisect_path(); |
| 102 | db_prepare(&s, "SELECT blob.uuid, datetime(event.mtime) " |
| 103 | " FROM blob, event" |
| 104 | " WHERE blob.rid=:rid AND event.objid=:rid" |
| 105 | " AND event.type='ci'"); |
| 106 | nStep = path_length(); |
| 107 | if( abbreviated ){ |
| 108 | for(p=path_last(); p; p=p->pFrom) p->isHidden = 1; |
| 109 | for(p=path_last(), n=0; p; p=p->pFrom, n++){ |
| 110 | if( p->rid==bisect.good |
| 111 | || p->rid==bisect.bad |
| 112 | || p->rid==vid |
| 113 | || (nStep>1 && n==nStep/2) |
| 114 | ){ |
| 115 | p->isHidden = 0; |
| 116 | if( p->pFrom ) p->pFrom->isHidden = 0; |
| 117 | } |
| 118 | } |
| 119 | for(p=path_last(); p; p=p->pFrom){ |
| 120 | if( p->pFrom && p->pFrom->isHidden==0 ) p->isHidden = 0; |
| 121 | } |
| 122 | } |
| 123 | for(p=path_last(), n=0; p; p=p->pFrom, n++){ |
| 124 | if( p->isHidden && (nHidden || (p->pFrom && p->pFrom->isHidden)) ){ |
| 125 | nHidden++; |
| 126 | continue; |
| 127 | }else if( nHidden ){ |
| 128 | fossil_print(" ... eliding %d check-ins\n", nHidden); |
| 129 | nHidden = 0; |
| 130 | } |
| 131 | db_bind_int(&s, ":rid", p->rid); |
| 132 | if( db_step(&s)==SQLITE_ROW ){ |
| 133 | const char *zUuid = db_column_text(&s, 0); |
| 134 | const char *zDate = db_column_text(&s, 1); |
| 135 | fossil_print("%s %S", zDate, zUuid); |
| 136 | if( p->rid==bisect.good ) fossil_print(" GOOD"); |
| 137 | if( p->rid==bisect.bad ) fossil_print(" BAD"); |
| 138 | if( p->rid==vid ) fossil_print(" CURRENT"); |
| 139 | if( nStep>1 && n==nStep/2 ) fossil_print(" NEXT"); |
| 140 | fossil_print("\n"); |
| 141 | } |
| 142 | db_reset(&s); |
| 143 | } |
| 144 | db_finalize(&s); |
| 145 | } |
| 146 | |
| 147 | /* |
| 148 | ** COMMAND: bisect |
| 149 | ** |
| 150 | ** Usage: %fossil bisect SUBCOMMAND ... |
| @@ -118,11 +174,11 @@ | |
| 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; |
| @@ -179,10 +235,11 @@ | |
| 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); |
| @@ -213,36 +270,12 @@ | |
| 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 |
+1
| --- src/path.c | ||
| +++ src/path.c | ||
| @@ -26,10 +26,11 @@ | ||
| 26 | 26 | */ |
| 27 | 27 | struct PathNode { |
| 28 | 28 | int rid; /* ID for this node */ |
| 29 | 29 | u8 fromIsParent; /* True if pFrom is the parent of rid */ |
| 30 | 30 | u8 isPrim; /* True if primary side of common ancestor */ |
| 31 | + u8 isHidden; /* Abbreviate output in "fossil bisect ls" */ | |
| 31 | 32 | PathNode *pFrom; /* Node we came from */ |
| 32 | 33 | union { |
| 33 | 34 | PathNode *pPeer; /* List of nodes of the same generation */ |
| 34 | 35 | PathNode *pTo; /* Next on path from beginning to end */ |
| 35 | 36 | } u; |
| 36 | 37 |
| --- src/path.c | |
| +++ src/path.c | |
| @@ -26,10 +26,11 @@ | |
| 26 | */ |
| 27 | struct PathNode { |
| 28 | int rid; /* ID for this node */ |
| 29 | u8 fromIsParent; /* True if pFrom is the parent of rid */ |
| 30 | u8 isPrim; /* True if primary side of common ancestor */ |
| 31 | PathNode *pFrom; /* Node we came from */ |
| 32 | union { |
| 33 | PathNode *pPeer; /* List of nodes of the same generation */ |
| 34 | PathNode *pTo; /* Next on path from beginning to end */ |
| 35 | } u; |
| 36 |
| --- src/path.c | |
| +++ src/path.c | |
| @@ -26,10 +26,11 @@ | |
| 26 | */ |
| 27 | struct PathNode { |
| 28 | int rid; /* ID for this node */ |
| 29 | u8 fromIsParent; /* True if pFrom is the parent of rid */ |
| 30 | u8 isPrim; /* True if primary side of common ancestor */ |
| 31 | u8 isHidden; /* Abbreviate output in "fossil bisect ls" */ |
| 32 | PathNode *pFrom; /* Node we came from */ |
| 33 | union { |
| 34 | PathNode *pPeer; /* List of nodes of the same generation */ |
| 35 | PathNode *pTo; /* Next on path from beginning to end */ |
| 36 | } u; |
| 37 |