Fossil SCM

Enhance the "fossil branch ls" command with two new options. The -t option sorts the branch list with the most recent branch first. The -r option reverses the sort order.

drh 2018-11-02 16:10 trunk
Commit db2682dc1af582013db841b1d79f4a3cb69157780ffe969dc3139fafd7db3e8f
1 file changed +74 -56
+74 -56
--- src/branch.c
+++ src/branch.c
@@ -178,21 +178,64 @@
178178
db_end_transaction(0);
179179
180180
/* Do an autosync push, if requested */
181181
if( !isPrivate ) autosync_loop(SYNC_PUSH, db_get_int("autosync-tries",1),0);
182182
}
183
+
184
+/*
185
+** Create a TEMP table named "tmp_brlist" with 7 columns:
186
+**
187
+** name Name of the branch
188
+** mtime Time of last checkin on this branch
189
+** isclosed True if the branch is closed
190
+** mergeto Another branch this branch was merged into
191
+** nckin Number of checkins on this branch
192
+** ckin Hash of the last checkin on this branch
193
+** bgclr Background color for this branch
194
+*/
195
+static const char createBrlistQuery[] =
196
+@ CREATE TEMP TABLE IF NOT EXISTS tmp_brlist AS
197
+@ SELECT
198
+@ tagxref.value AS name,
199
+@ max(event.mtime) AS mtime,
200
+@ EXISTS(SELECT 1 FROM tagxref AS tx
201
+@ WHERE tx.rid=tagxref.rid
202
+@ AND tx.tagid=(SELECT tagid FROM tag WHERE tagname='closed')
203
+@ AND tx.tagtype>0) AS isclosed,
204
+@ (SELECT tagxref.value
205
+@ FROM plink CROSS JOIN tagxref
206
+@ WHERE plink.pid=event.objid
207
+@ AND tagxref.rid=plink.cid
208
+@ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch')
209
+@ AND tagtype>0) AS mergeto,
210
+@ count(*) AS nckin,
211
+@ (SELECT uuid FROM blob WHERE rid=tagxref.rid) AS ckin,
212
+@ event.bgcolor AS bgclr
213
+@ FROM tagxref, tag, event
214
+@ WHERE tagxref.tagid=tag.tagid
215
+@ AND tagxref.tagtype>0
216
+@ AND tag.tagname='branch'
217
+@ AND event.objid=tagxref.rid
218
+@ GROUP BY 1;
219
+;
220
+
221
+/* Call this routine to create the TEMP table */
222
+static void brlist_create_temp_table(void){
223
+ db_multi_exec(createBrlistQuery/*works-like:""*/);
224
+}
225
+
183226
184227
#if INTERFACE
185228
/*
186229
** Allows bits in the mBplqFlags parameter to branch_prepare_list_query().
187230
*/
188231
#define BRL_CLOSED_ONLY 0x001 /* Show only closed branches */
189232
#define BRL_OPEN_ONLY 0x002 /* Show only open branches */
190233
#define BRL_BOTH 0x003 /* Show both open and closed branches */
191234
#define BRL_OPEN_CLOSED_MASK 0x003
192
-#define BRL_MTIME 0x004 /* Include lastest check-in time */
193
-#define BRL_ORDERBY_MTIME 0x008 /* Sort by MTIME. (otherwise sort by name)*/
235
+#define BRL_ORDERBY_MTIME 0x004 /* Sort by MTIME. (otherwise sort by name)*/
236
+#define BRL_REVERSE 0x008 /* Reverse the sort order */
194237
195238
#endif /* INTERFACE */
196239
197240
/*
198241
** Prepare a query that will list branches.
@@ -200,47 +243,43 @@
200243
** If (which<0) then the query pulls only closed branches. If
201244
** (which>0) then the query pulls all (closed and opened)
202245
** branches. Else the query pulls currently-opened branches.
203246
*/
204247
void branch_prepare_list_query(Stmt *pQuery, int brFlags){
248
+ Blob sql;
249
+ blob_init(&sql, 0, 0);
250
+ brlist_create_temp_table();
205251
switch( brFlags & BRL_OPEN_CLOSED_MASK ){
206252
case BRL_CLOSED_ONLY: {
207
- db_prepare(pQuery,
208
- "SELECT value FROM tagxref"
209
- " WHERE tagid=%d AND value NOT NULL "
210
- "EXCEPT "
211
- "SELECT value FROM tagxref"
212
- " WHERE tagid=%d"
213
- " AND rid IN leaf"
214
- " AND NOT %z"
215
- " ORDER BY value COLLATE nocase /*sort*/",
216
- TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
253
+ blob_append_sql(&sql,
254
+ "SELECT name FROM tmp_brlist WHERE isclosed"
217255
);
218256
break;
219257
}
220258
case BRL_BOTH: {
221
- db_prepare(pQuery,
222
- "SELECT DISTINCT value FROM tagxref"
223
- " WHERE tagid=%d AND value NOT NULL"
224
- " AND rid IN leaf"
225
- " ORDER BY value COLLATE nocase /*sort*/",
226
- TAG_BRANCH
259
+ blob_append_sql(&sql,
260
+ "SELECT name FROM tmp_brlist"
227261
);
228262
break;
229263
}
230264
case BRL_OPEN_ONLY: {
231
- db_prepare(pQuery,
232
- "SELECT DISTINCT value FROM tagxref"
233
- " WHERE tagid=%d AND value NOT NULL"
234
- " AND rid IN leaf"
235
- " AND NOT %z"
236
- " ORDER BY value COLLATE nocase /*sort*/",
237
- TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
265
+ blob_append_sql(&sql,
266
+ "SELECT name FROM tmp_brlist WHERE NOT isclosed"
238267
);
239268
break;
240269
}
241270
}
271
+ if( brFlags & BRL_ORDERBY_MTIME ){
272
+ blob_append_sql(&sql, " ORDER BY -mtime");
273
+ }else{
274
+ blob_append_sql(&sql, " ORDER BY name COLLATE nocase");
275
+ }
276
+ if( brFlags & BRL_REVERSE ){
277
+ blob_append_sql(&sql," DESC");
278
+ }
279
+ db_prepare_blob(pQuery, &sql);
280
+ blob_reset(&sql);
242281
}
243282
244283
/*
245284
** If the branch named in the argument is open, return a RID for one of
246285
** the open leaves of that branch. If the branch does not exists or is
@@ -276,15 +315,17 @@
276315
**
277316
** fossil branch info BRANCH-NAME
278317
**
279318
** Print information about a branch
280319
**
281
-** fossil branch list|ls ?-a|--all|-c|--closed?
320
+** fossil branch list|ls ?OPTIONS?
282321
**
283
-** List all branches. Use -a or --all to list all branches and
284
-** -c or --closed to list all closed branches. The default is to
285
-** show only open branches.
322
+** List all branches. Options:
323
+** -a|--all List all branches. Default show only open branches
324
+** -c|--closed List closed branches.
325
+** -r Reverse the sort order
326
+** -t Show recently changed branches first
286327
**
287328
** fossil branch new BRANCH-NAME BASIS ?OPTIONS?
288329
**
289330
** Create a new branch BRANCH-NAME off of check-in BASIS.
290331
** Supported options for this subcommand include:
@@ -345,10 +386,12 @@
345386
int vid;
346387
char *zCurrent = 0;
347388
int brFlags = BRL_OPEN_ONLY;
348389
if( find_option("all","a",0)!=0 ) brFlags = BRL_BOTH;
349390
if( find_option("closed","c",0)!=0 ) brFlags = BRL_CLOSED_ONLY;
391
+ if( find_option("t",0,0)!=0 ) brFlags |= BRL_ORDERBY_MTIME;
392
+ if( find_option("r",0,0)!=0 ) brFlags |= BRL_REVERSE;
350393
351394
if( g.localOpen ){
352395
vid = db_lget_int("checkout", 0);
353396
zCurrent = db_text(0, "SELECT value FROM tagxref"
354397
" WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH);
@@ -366,36 +409,10 @@
366409
fossil_fatal("branch subcommand should be one of: "
367410
"current info list ls new");
368411
}
369412
}
370413
371
-static const char brlistQuery[] =
372
-@ SELECT
373
-@ tagxref.value,
374
-@ max(event.mtime),
375
-@ EXISTS(SELECT 1 FROM tagxref AS tx
376
-@ WHERE tx.rid=tagxref.rid
377
-@ AND tx.tagid=(SELECT tagid FROM tag WHERE tagname='closed')
378
-@ AND tx.tagtype>0),
379
-@ (SELECT tagxref.value
380
-@ FROM plink CROSS JOIN tagxref
381
-@ WHERE plink.pid=event.objid
382
-@ AND tagxref.rid=plink.cid
383
-@ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch')
384
-@ AND tagtype>0),
385
-@ count(*),
386
-@ (SELECT uuid FROM blob WHERE rid=tagxref.rid),
387
-@ event.bgcolor
388
-@ FROM tagxref, tag, event
389
-@ WHERE tagxref.tagid=tag.tagid
390
-@ AND tagxref.tagtype>0
391
-@ AND tag.tagname='branch'
392
-@ AND event.objid=tagxref.rid
393
-@ GROUP BY 1
394
-@ ORDER BY 2 DESC;
395
-;
396
-
397414
/*
398415
** This is the new-style branch-list page that shows the branch names
399416
** together with their ages (time of last check-in) and whether or not
400417
** they are closed or merged to another branch.
401418
**
@@ -411,11 +428,12 @@
411428
style_header("Branches");
412429
style_adunit_config(ADUNIT_RIGHT_OK);
413430
style_submenu_checkbox("colors", "Use Branch Colors", 0, 0);
414431
login_anonymous_available();
415432
416
- db_prepare(&q, brlistQuery/*works-like:""*/);
433
+ brlist_create_temp_table();
434
+ db_prepare(&q, "SELECT * FROM tmp_brlist");
417435
rNow = db_double(0.0, "SELECT julianday('now')");
418436
@ <div class="brlist">
419437
@ <table class='sortable' data-column-types='tkNtt' data-init-sort='2'>
420438
@ <thead><tr>
421439
@ <th>Branch Name</th>
422440
--- src/branch.c
+++ src/branch.c
@@ -178,21 +178,64 @@
178 db_end_transaction(0);
179
180 /* Do an autosync push, if requested */
181 if( !isPrivate ) autosync_loop(SYNC_PUSH, db_get_int("autosync-tries",1),0);
182 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
184 #if INTERFACE
185 /*
186 ** Allows bits in the mBplqFlags parameter to branch_prepare_list_query().
187 */
188 #define BRL_CLOSED_ONLY 0x001 /* Show only closed branches */
189 #define BRL_OPEN_ONLY 0x002 /* Show only open branches */
190 #define BRL_BOTH 0x003 /* Show both open and closed branches */
191 #define BRL_OPEN_CLOSED_MASK 0x003
192 #define BRL_MTIME 0x004 /* Include lastest check-in time */
193 #define BRL_ORDERBY_MTIME 0x008 /* Sort by MTIME. (otherwise sort by name)*/
194
195 #endif /* INTERFACE */
196
197 /*
198 ** Prepare a query that will list branches.
@@ -200,47 +243,43 @@
200 ** If (which<0) then the query pulls only closed branches. If
201 ** (which>0) then the query pulls all (closed and opened)
202 ** branches. Else the query pulls currently-opened branches.
203 */
204 void branch_prepare_list_query(Stmt *pQuery, int brFlags){
 
 
 
205 switch( brFlags & BRL_OPEN_CLOSED_MASK ){
206 case BRL_CLOSED_ONLY: {
207 db_prepare(pQuery,
208 "SELECT value FROM tagxref"
209 " WHERE tagid=%d AND value NOT NULL "
210 "EXCEPT "
211 "SELECT value FROM tagxref"
212 " WHERE tagid=%d"
213 " AND rid IN leaf"
214 " AND NOT %z"
215 " ORDER BY value COLLATE nocase /*sort*/",
216 TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
217 );
218 break;
219 }
220 case BRL_BOTH: {
221 db_prepare(pQuery,
222 "SELECT DISTINCT value FROM tagxref"
223 " WHERE tagid=%d AND value NOT NULL"
224 " AND rid IN leaf"
225 " ORDER BY value COLLATE nocase /*sort*/",
226 TAG_BRANCH
227 );
228 break;
229 }
230 case BRL_OPEN_ONLY: {
231 db_prepare(pQuery,
232 "SELECT DISTINCT value FROM tagxref"
233 " WHERE tagid=%d AND value NOT NULL"
234 " AND rid IN leaf"
235 " AND NOT %z"
236 " ORDER BY value COLLATE nocase /*sort*/",
237 TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
238 );
239 break;
240 }
241 }
 
 
 
 
 
 
 
 
 
 
242 }
243
244 /*
245 ** If the branch named in the argument is open, return a RID for one of
246 ** the open leaves of that branch. If the branch does not exists or is
@@ -276,15 +315,17 @@
276 **
277 ** fossil branch info BRANCH-NAME
278 **
279 ** Print information about a branch
280 **
281 ** fossil branch list|ls ?-a|--all|-c|--closed?
282 **
283 ** List all branches. Use -a or --all to list all branches and
284 ** -c or --closed to list all closed branches. The default is to
285 ** show only open branches.
 
 
286 **
287 ** fossil branch new BRANCH-NAME BASIS ?OPTIONS?
288 **
289 ** Create a new branch BRANCH-NAME off of check-in BASIS.
290 ** Supported options for this subcommand include:
@@ -345,10 +386,12 @@
345 int vid;
346 char *zCurrent = 0;
347 int brFlags = BRL_OPEN_ONLY;
348 if( find_option("all","a",0)!=0 ) brFlags = BRL_BOTH;
349 if( find_option("closed","c",0)!=0 ) brFlags = BRL_CLOSED_ONLY;
 
 
350
351 if( g.localOpen ){
352 vid = db_lget_int("checkout", 0);
353 zCurrent = db_text(0, "SELECT value FROM tagxref"
354 " WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH);
@@ -366,36 +409,10 @@
366 fossil_fatal("branch subcommand should be one of: "
367 "current info list ls new");
368 }
369 }
370
371 static const char brlistQuery[] =
372 @ SELECT
373 @ tagxref.value,
374 @ max(event.mtime),
375 @ EXISTS(SELECT 1 FROM tagxref AS tx
376 @ WHERE tx.rid=tagxref.rid
377 @ AND tx.tagid=(SELECT tagid FROM tag WHERE tagname='closed')
378 @ AND tx.tagtype>0),
379 @ (SELECT tagxref.value
380 @ FROM plink CROSS JOIN tagxref
381 @ WHERE plink.pid=event.objid
382 @ AND tagxref.rid=plink.cid
383 @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch')
384 @ AND tagtype>0),
385 @ count(*),
386 @ (SELECT uuid FROM blob WHERE rid=tagxref.rid),
387 @ event.bgcolor
388 @ FROM tagxref, tag, event
389 @ WHERE tagxref.tagid=tag.tagid
390 @ AND tagxref.tagtype>0
391 @ AND tag.tagname='branch'
392 @ AND event.objid=tagxref.rid
393 @ GROUP BY 1
394 @ ORDER BY 2 DESC;
395 ;
396
397 /*
398 ** This is the new-style branch-list page that shows the branch names
399 ** together with their ages (time of last check-in) and whether or not
400 ** they are closed or merged to another branch.
401 **
@@ -411,11 +428,12 @@
411 style_header("Branches");
412 style_adunit_config(ADUNIT_RIGHT_OK);
413 style_submenu_checkbox("colors", "Use Branch Colors", 0, 0);
414 login_anonymous_available();
415
416 db_prepare(&q, brlistQuery/*works-like:""*/);
 
417 rNow = db_double(0.0, "SELECT julianday('now')");
418 @ <div class="brlist">
419 @ <table class='sortable' data-column-types='tkNtt' data-init-sort='2'>
420 @ <thead><tr>
421 @ <th>Branch Name</th>
422
--- src/branch.c
+++ src/branch.c
@@ -178,21 +178,64 @@
178 db_end_transaction(0);
179
180 /* Do an autosync push, if requested */
181 if( !isPrivate ) autosync_loop(SYNC_PUSH, db_get_int("autosync-tries",1),0);
182 }
183
184 /*
185 ** Create a TEMP table named "tmp_brlist" with 7 columns:
186 **
187 ** name Name of the branch
188 ** mtime Time of last checkin on this branch
189 ** isclosed True if the branch is closed
190 ** mergeto Another branch this branch was merged into
191 ** nckin Number of checkins on this branch
192 ** ckin Hash of the last checkin on this branch
193 ** bgclr Background color for this branch
194 */
195 static const char createBrlistQuery[] =
196 @ CREATE TEMP TABLE IF NOT EXISTS tmp_brlist AS
197 @ SELECT
198 @ tagxref.value AS name,
199 @ max(event.mtime) AS mtime,
200 @ EXISTS(SELECT 1 FROM tagxref AS tx
201 @ WHERE tx.rid=tagxref.rid
202 @ AND tx.tagid=(SELECT tagid FROM tag WHERE tagname='closed')
203 @ AND tx.tagtype>0) AS isclosed,
204 @ (SELECT tagxref.value
205 @ FROM plink CROSS JOIN tagxref
206 @ WHERE plink.pid=event.objid
207 @ AND tagxref.rid=plink.cid
208 @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch')
209 @ AND tagtype>0) AS mergeto,
210 @ count(*) AS nckin,
211 @ (SELECT uuid FROM blob WHERE rid=tagxref.rid) AS ckin,
212 @ event.bgcolor AS bgclr
213 @ FROM tagxref, tag, event
214 @ WHERE tagxref.tagid=tag.tagid
215 @ AND tagxref.tagtype>0
216 @ AND tag.tagname='branch'
217 @ AND event.objid=tagxref.rid
218 @ GROUP BY 1;
219 ;
220
221 /* Call this routine to create the TEMP table */
222 static void brlist_create_temp_table(void){
223 db_multi_exec(createBrlistQuery/*works-like:""*/);
224 }
225
226
227 #if INTERFACE
228 /*
229 ** Allows bits in the mBplqFlags parameter to branch_prepare_list_query().
230 */
231 #define BRL_CLOSED_ONLY 0x001 /* Show only closed branches */
232 #define BRL_OPEN_ONLY 0x002 /* Show only open branches */
233 #define BRL_BOTH 0x003 /* Show both open and closed branches */
234 #define BRL_OPEN_CLOSED_MASK 0x003
235 #define BRL_ORDERBY_MTIME 0x004 /* Sort by MTIME. (otherwise sort by name)*/
236 #define BRL_REVERSE 0x008 /* Reverse the sort order */
237
238 #endif /* INTERFACE */
239
240 /*
241 ** Prepare a query that will list branches.
@@ -200,47 +243,43 @@
243 ** If (which<0) then the query pulls only closed branches. If
244 ** (which>0) then the query pulls all (closed and opened)
245 ** branches. Else the query pulls currently-opened branches.
246 */
247 void branch_prepare_list_query(Stmt *pQuery, int brFlags){
248 Blob sql;
249 blob_init(&sql, 0, 0);
250 brlist_create_temp_table();
251 switch( brFlags & BRL_OPEN_CLOSED_MASK ){
252 case BRL_CLOSED_ONLY: {
253 blob_append_sql(&sql,
254 "SELECT name FROM tmp_brlist WHERE isclosed"
 
 
 
 
 
 
 
 
255 );
256 break;
257 }
258 case BRL_BOTH: {
259 blob_append_sql(&sql,
260 "SELECT name FROM tmp_brlist"
 
 
 
 
261 );
262 break;
263 }
264 case BRL_OPEN_ONLY: {
265 blob_append_sql(&sql,
266 "SELECT name FROM tmp_brlist WHERE NOT isclosed"
 
 
 
 
 
267 );
268 break;
269 }
270 }
271 if( brFlags & BRL_ORDERBY_MTIME ){
272 blob_append_sql(&sql, " ORDER BY -mtime");
273 }else{
274 blob_append_sql(&sql, " ORDER BY name COLLATE nocase");
275 }
276 if( brFlags & BRL_REVERSE ){
277 blob_append_sql(&sql," DESC");
278 }
279 db_prepare_blob(pQuery, &sql);
280 blob_reset(&sql);
281 }
282
283 /*
284 ** If the branch named in the argument is open, return a RID for one of
285 ** the open leaves of that branch. If the branch does not exists or is
@@ -276,15 +315,17 @@
315 **
316 ** fossil branch info BRANCH-NAME
317 **
318 ** Print information about a branch
319 **
320 ** fossil branch list|ls ?OPTIONS?
321 **
322 ** List all branches. Options:
323 ** -a|--all List all branches. Default show only open branches
324 ** -c|--closed List closed branches.
325 ** -r Reverse the sort order
326 ** -t Show recently changed branches first
327 **
328 ** fossil branch new BRANCH-NAME BASIS ?OPTIONS?
329 **
330 ** Create a new branch BRANCH-NAME off of check-in BASIS.
331 ** Supported options for this subcommand include:
@@ -345,10 +386,12 @@
386 int vid;
387 char *zCurrent = 0;
388 int brFlags = BRL_OPEN_ONLY;
389 if( find_option("all","a",0)!=0 ) brFlags = BRL_BOTH;
390 if( find_option("closed","c",0)!=0 ) brFlags = BRL_CLOSED_ONLY;
391 if( find_option("t",0,0)!=0 ) brFlags |= BRL_ORDERBY_MTIME;
392 if( find_option("r",0,0)!=0 ) brFlags |= BRL_REVERSE;
393
394 if( g.localOpen ){
395 vid = db_lget_int("checkout", 0);
396 zCurrent = db_text(0, "SELECT value FROM tagxref"
397 " WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH);
@@ -366,36 +409,10 @@
409 fossil_fatal("branch subcommand should be one of: "
410 "current info list ls new");
411 }
412 }
413
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
414 /*
415 ** This is the new-style branch-list page that shows the branch names
416 ** together with their ages (time of last check-in) and whether or not
417 ** they are closed or merged to another branch.
418 **
@@ -411,11 +428,12 @@
428 style_header("Branches");
429 style_adunit_config(ADUNIT_RIGHT_OK);
430 style_submenu_checkbox("colors", "Use Branch Colors", 0, 0);
431 login_anonymous_available();
432
433 brlist_create_temp_table();
434 db_prepare(&q, "SELECT * FROM tmp_brlist");
435 rNow = db_double(0.0, "SELECT julianday('now')");
436 @ <div class="brlist">
437 @ <table class='sortable' data-column-types='tkNtt' data-init-sort='2'>
438 @ <thead><tr>
439 @ <th>Branch Name</th>
440

Keyboard Shortcuts

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