Fossil SCM

Refactor the `-h' option to its own `lsh' subcommand sibling to `list|ls' to reuse their infrastructure and flags. To produce useful output with the `-r' option, the SQL query to generate the branch list is LIMIT'ed in an inner query, and then ORDER'ed again in an outer query.

florian 2022-08-02 10:27 ls-hot-branches
Commit dbd6efe2d89be79bade5e1eb358b5efa856938e1e0040d8043c7e4c00ffc951f
1 file changed +44 -20
+44 -20
--- src/branch.c
+++ src/branch.c
@@ -280,46 +280,60 @@
280280
#define BRL_BOTH 0x003 /* Show both open and closed branches */
281281
#define BRL_OPEN_CLOSED_MASK 0x003
282282
#define BRL_ORDERBY_MTIME 0x004 /* Sort by MTIME. (otherwise sort by name)*/
283283
#define BRL_REVERSE 0x008 /* Reverse the sort order */
284284
#define BRL_PRIVATE 0x010 /* Show only private branches */
285
-#define BRL_LIMIT 0x020 /* Limit entries to specified number */
286285
287286
#endif /* INTERFACE */
288287
289288
/*
290289
** Prepare a query that will list branches.
291290
**
292291
** If (which<0) then the query pulls only closed branches. If
293292
** (which>0) then the query pulls all (closed and opened)
294293
** branches. Else the query pulls currently-opened branches.
294
+**
295
+** If the BRL_ORDERBY_MTIME flag is set and nLimitMRU ("Limit Most Recently Used
296
+** style") is a non-zero number, the result is limited to nLimitMRU entries, and
297
+** the BRL_REVERSE flag is applied in an outer query after processing the limit,
298
+** so that it's possible to generate short lists with the most recently modified
299
+** branches sorted chronologically in either direction, as does the "branch lsh"
300
+** command.
301
+** For other cases, the outer query is also generated, but works as a no-op. The
302
+** code to build the outer query is marked with *//* OUTER QUERY *//* comments.
295303
*/
296304
void branch_prepare_list_query(
297305
Stmt *pQuery,
298306
int brFlags,
299307
const char *zBrNameGlob,
300
- int nLimit
308
+ int nLimitMRU
301309
){
302310
Blob sql;
303311
blob_init(&sql, 0, 0);
304312
brlist_create_temp_table();
313
+ /* Ignore nLimitMRU if no chronological sort requested. */
314
+ if( (brFlags & BRL_ORDERBY_MTIME)==0 ) nLimitMRU = 0;
315
+ /* Undocumented: invert negative values for nLimitMRU, so that command-line
316
+ ** arguments similar to `head -5' with "option numbers" are possible. */
317
+ if( nLimitMRU<0 ) nLimitMRU = -nLimitMRU;
318
+ blob_append_sql(&sql,"SELECT name, isprivate FROM ("); /* OUTER QUERY */
305319
switch( brFlags & BRL_OPEN_CLOSED_MASK ){
306320
case BRL_CLOSED_ONLY: {
307321
blob_append_sql(&sql,
308
- "SELECT name, isprivate FROM tmp_brlist WHERE isclosed"
322
+ "SELECT name, isprivate, mtime FROM tmp_brlist WHERE isclosed"
309323
);
310324
break;
311325
}
312326
case BRL_BOTH: {
313327
blob_append_sql(&sql,
314
- "SELECT name, isprivate FROM tmp_brlist WHERE 1"
328
+ "SELECT name, isprivate, mtime FROM tmp_brlist WHERE 1"
315329
);
316330
break;
317331
}
318332
case BRL_OPEN_ONLY: {
319333
blob_append_sql(&sql,
320
- "SELECT name, isprivate FROM tmp_brlist WHERE NOT isclosed"
334
+ "SELECT name, isprivate, mtime FROM tmp_brlist WHERE NOT isclosed"
321335
);
322336
break;
323337
}
324338
}
325339
if( brFlags & BRL_PRIVATE ) blob_append_sql(&sql, " AND isprivate");
@@ -327,15 +341,19 @@
327341
if( brFlags & BRL_ORDERBY_MTIME ){
328342
blob_append_sql(&sql, " ORDER BY -mtime");
329343
}else{
330344
blob_append_sql(&sql, " ORDER BY name COLLATE nocase");
331345
}
332
- if( brFlags & BRL_REVERSE ){
346
+ if( brFlags & BRL_REVERSE && !nLimitMRU ){
333347
blob_append_sql(&sql," DESC");
334348
}
335
- if( brFlags & BRL_LIMIT && nLimit>0 ){
336
- blob_append_sql(&sql," LIMIT %d",nLimit);
349
+ if( nLimitMRU ){
350
+ blob_append_sql(&sql," LIMIT %d",nLimitMRU);
351
+ }
352
+ blob_append_sql(&sql,")"); /* OUTER QUERY */
353
+ if( brFlags & BRL_REVERSE && nLimitMRU ){
354
+ blob_append_sql(&sql," ORDER BY mtime"); /* OUTER QUERY */
337355
}
338356
db_prepare_blob(pQuery, &sql);
339357
blob_reset(&sql);
340358
}
341359
@@ -594,25 +612,28 @@
594612
** > fossil branch info BRANCH-NAME
595613
**
596614
** Print information about a branch
597615
**
598616
** > fossil branch list|ls ?OPTIONS? ?GLOB?
617
+** > fossil branch lsh ?OPTIONS? ?LIMIT?
599618
**
600619
** List all branches. Options:
601620
** -a|--all List all branches. Default show only open branches
602621
** -c|--closed List closed branches.
603622
** -p List only private branches.
604623
** -r Reverse the sort order
605624
** -t Show recently changed branches first
606
-** -h ?N? Show N recently changed branches (or 5 if N omitted)
607625
**
608626
** The current branch is marked with an asterisk. Private branches are
609627
** marked with a hash sign.
610628
**
611
-** If GLOB is given, show only branches matching the pattern. With the
612
-** -h option set, no GLOB argument is allowed, but an (optional) number
613
-** of entries to output.
629
+** If GLOB is given, show only branches matching the pattern.
630
+**
631
+** The "lsh" variant of this subcommand shows recently changed branches,
632
+** and accepts an optional LIMIT argument (defaults to 5) to cap output,
633
+** but no GLOB argument. All other options are supported, with -t being
634
+** an implied no-op.
614635
**
615636
** > fossil branch new BRANCH-NAME BASIS ?OPTIONS?
616637
**
617638
** Create a new branch BRANCH-NAME off of check-in BASIS.
618639
** Supported options for this subcommand include:
@@ -663,30 +684,33 @@
663684
"SELECT datetime(mtime,toLocal()) FROM event"
664685
" WHERE objid=%d", rid);
665686
fossil_print("%s: open as of %s on %.16s\n", zBrName, zDate, zUuid);
666687
}
667688
}
668
- }else if( (strncmp(zCmd,"list",n)==0)||(strncmp(zCmd, "ls", n)==0) ){
689
+ }else if( strncmp(zCmd,"list",n)==0 ||
690
+ strncmp(zCmd, "ls", n)==0 ||
691
+ strcmp(zCmd, "lsh")==0 ){
669692
Stmt q;
670693
int vid;
671694
char *zCurrent = 0;
672695
const char *zBrNameGlob = 0;
673
- int nLimit = 5;
696
+ int nLimit = 0;
674697
int brFlags = BRL_OPEN_ONLY;
675698
if( find_option("all","a",0)!=0 ) brFlags = BRL_BOTH;
676699
if( find_option("closed","c",0)!=0 ) brFlags = BRL_CLOSED_ONLY;
677700
if( find_option("t",0,0)!=0 ) brFlags |= BRL_ORDERBY_MTIME;
678701
if( find_option("r",0,0)!=0 ) brFlags |= BRL_REVERSE;
679702
if( find_option("p",0,0)!=0 ) brFlags |= BRL_PRIVATE;
680
- if( find_option("h",0,0)!=0 ) brFlags |= BRL_LIMIT;
681
- if( (brFlags & BRL_LIMIT)==0 ){
682
- if( g.argc >= 4 ) zBrNameGlob = g.argv[3];
683
- }else{
703
+
704
+ if( strcmp(zCmd, "lsh")==0 ){
705
+ nLimit = 5;
684706
if( g.argc>4 || g.argc==4 && (nLimit = atoi(g.argv[3]))==0 ){
685
- fossil_fatal("only one numeric or no argument allowed following -h");
707
+ fossil_fatal("the lsh subcommand allows one optional numeric argument");
686708
}
687709
brFlags |= BRL_ORDERBY_MTIME;
710
+ }else{
711
+ if( g.argc >= 4 ) zBrNameGlob = g.argv[3];
688712
}
689713
690714
if( g.localOpen ){
691715
vid = db_lget_int("checkout", 0);
692716
zCurrent = db_text(0, "SELECT value FROM tagxref"
@@ -724,11 +748,11 @@
724748
usage("branch unhide branch-name(s)...");
725749
}
726750
branch_cmd_hide(3,0);
727751
}else{
728752
fossil_fatal("branch subcommand should be one of: "
729
- "close current hide info list ls new reopen unhide");
753
+ "close current hide info list ls lsh new reopen unhide");
730754
}
731755
}
732756
733757
/*
734758
** This is the new-style branch-list page that shows the branch names
735759
--- src/branch.c
+++ src/branch.c
@@ -280,46 +280,60 @@
280 #define BRL_BOTH 0x003 /* Show both open and closed branches */
281 #define BRL_OPEN_CLOSED_MASK 0x003
282 #define BRL_ORDERBY_MTIME 0x004 /* Sort by MTIME. (otherwise sort by name)*/
283 #define BRL_REVERSE 0x008 /* Reverse the sort order */
284 #define BRL_PRIVATE 0x010 /* Show only private branches */
285 #define BRL_LIMIT 0x020 /* Limit entries to specified number */
286
287 #endif /* INTERFACE */
288
289 /*
290 ** Prepare a query that will list branches.
291 **
292 ** If (which<0) then the query pulls only closed branches. If
293 ** (which>0) then the query pulls all (closed and opened)
294 ** branches. Else the query pulls currently-opened branches.
 
 
 
 
 
 
 
 
 
295 */
296 void branch_prepare_list_query(
297 Stmt *pQuery,
298 int brFlags,
299 const char *zBrNameGlob,
300 int nLimit
301 ){
302 Blob sql;
303 blob_init(&sql, 0, 0);
304 brlist_create_temp_table();
 
 
 
 
 
 
305 switch( brFlags & BRL_OPEN_CLOSED_MASK ){
306 case BRL_CLOSED_ONLY: {
307 blob_append_sql(&sql,
308 "SELECT name, isprivate FROM tmp_brlist WHERE isclosed"
309 );
310 break;
311 }
312 case BRL_BOTH: {
313 blob_append_sql(&sql,
314 "SELECT name, isprivate FROM tmp_brlist WHERE 1"
315 );
316 break;
317 }
318 case BRL_OPEN_ONLY: {
319 blob_append_sql(&sql,
320 "SELECT name, isprivate FROM tmp_brlist WHERE NOT isclosed"
321 );
322 break;
323 }
324 }
325 if( brFlags & BRL_PRIVATE ) blob_append_sql(&sql, " AND isprivate");
@@ -327,15 +341,19 @@
327 if( brFlags & BRL_ORDERBY_MTIME ){
328 blob_append_sql(&sql, " ORDER BY -mtime");
329 }else{
330 blob_append_sql(&sql, " ORDER BY name COLLATE nocase");
331 }
332 if( brFlags & BRL_REVERSE ){
333 blob_append_sql(&sql," DESC");
334 }
335 if( brFlags & BRL_LIMIT && nLimit>0 ){
336 blob_append_sql(&sql," LIMIT %d",nLimit);
 
 
 
 
337 }
338 db_prepare_blob(pQuery, &sql);
339 blob_reset(&sql);
340 }
341
@@ -594,25 +612,28 @@
594 ** > fossil branch info BRANCH-NAME
595 **
596 ** Print information about a branch
597 **
598 ** > fossil branch list|ls ?OPTIONS? ?GLOB?
 
599 **
600 ** List all branches. Options:
601 ** -a|--all List all branches. Default show only open branches
602 ** -c|--closed List closed branches.
603 ** -p List only private branches.
604 ** -r Reverse the sort order
605 ** -t Show recently changed branches first
606 ** -h ?N? Show N recently changed branches (or 5 if N omitted)
607 **
608 ** The current branch is marked with an asterisk. Private branches are
609 ** marked with a hash sign.
610 **
611 ** If GLOB is given, show only branches matching the pattern. With the
612 ** -h option set, no GLOB argument is allowed, but an (optional) number
613 ** of entries to output.
 
 
 
614 **
615 ** > fossil branch new BRANCH-NAME BASIS ?OPTIONS?
616 **
617 ** Create a new branch BRANCH-NAME off of check-in BASIS.
618 ** Supported options for this subcommand include:
@@ -663,30 +684,33 @@
663 "SELECT datetime(mtime,toLocal()) FROM event"
664 " WHERE objid=%d", rid);
665 fossil_print("%s: open as of %s on %.16s\n", zBrName, zDate, zUuid);
666 }
667 }
668 }else if( (strncmp(zCmd,"list",n)==0)||(strncmp(zCmd, "ls", n)==0) ){
 
 
669 Stmt q;
670 int vid;
671 char *zCurrent = 0;
672 const char *zBrNameGlob = 0;
673 int nLimit = 5;
674 int brFlags = BRL_OPEN_ONLY;
675 if( find_option("all","a",0)!=0 ) brFlags = BRL_BOTH;
676 if( find_option("closed","c",0)!=0 ) brFlags = BRL_CLOSED_ONLY;
677 if( find_option("t",0,0)!=0 ) brFlags |= BRL_ORDERBY_MTIME;
678 if( find_option("r",0,0)!=0 ) brFlags |= BRL_REVERSE;
679 if( find_option("p",0,0)!=0 ) brFlags |= BRL_PRIVATE;
680 if( find_option("h",0,0)!=0 ) brFlags |= BRL_LIMIT;
681 if( (brFlags & BRL_LIMIT)==0 ){
682 if( g.argc >= 4 ) zBrNameGlob = g.argv[3];
683 }else{
684 if( g.argc>4 || g.argc==4 && (nLimit = atoi(g.argv[3]))==0 ){
685 fossil_fatal("only one numeric or no argument allowed following -h");
686 }
687 brFlags |= BRL_ORDERBY_MTIME;
 
 
688 }
689
690 if( g.localOpen ){
691 vid = db_lget_int("checkout", 0);
692 zCurrent = db_text(0, "SELECT value FROM tagxref"
@@ -724,11 +748,11 @@
724 usage("branch unhide branch-name(s)...");
725 }
726 branch_cmd_hide(3,0);
727 }else{
728 fossil_fatal("branch subcommand should be one of: "
729 "close current hide info list ls new reopen unhide");
730 }
731 }
732
733 /*
734 ** This is the new-style branch-list page that shows the branch names
735
--- src/branch.c
+++ src/branch.c
@@ -280,46 +280,60 @@
280 #define BRL_BOTH 0x003 /* Show both open and closed branches */
281 #define BRL_OPEN_CLOSED_MASK 0x003
282 #define BRL_ORDERBY_MTIME 0x004 /* Sort by MTIME. (otherwise sort by name)*/
283 #define BRL_REVERSE 0x008 /* Reverse the sort order */
284 #define BRL_PRIVATE 0x010 /* Show only private branches */
 
285
286 #endif /* INTERFACE */
287
288 /*
289 ** Prepare a query that will list branches.
290 **
291 ** If (which<0) then the query pulls only closed branches. If
292 ** (which>0) then the query pulls all (closed and opened)
293 ** branches. Else the query pulls currently-opened branches.
294 **
295 ** If the BRL_ORDERBY_MTIME flag is set and nLimitMRU ("Limit Most Recently Used
296 ** style") is a non-zero number, the result is limited to nLimitMRU entries, and
297 ** the BRL_REVERSE flag is applied in an outer query after processing the limit,
298 ** so that it's possible to generate short lists with the most recently modified
299 ** branches sorted chronologically in either direction, as does the "branch lsh"
300 ** command.
301 ** For other cases, the outer query is also generated, but works as a no-op. The
302 ** code to build the outer query is marked with *//* OUTER QUERY *//* comments.
303 */
304 void branch_prepare_list_query(
305 Stmt *pQuery,
306 int brFlags,
307 const char *zBrNameGlob,
308 int nLimitMRU
309 ){
310 Blob sql;
311 blob_init(&sql, 0, 0);
312 brlist_create_temp_table();
313 /* Ignore nLimitMRU if no chronological sort requested. */
314 if( (brFlags & BRL_ORDERBY_MTIME)==0 ) nLimitMRU = 0;
315 /* Undocumented: invert negative values for nLimitMRU, so that command-line
316 ** arguments similar to `head -5' with "option numbers" are possible. */
317 if( nLimitMRU<0 ) nLimitMRU = -nLimitMRU;
318 blob_append_sql(&sql,"SELECT name, isprivate FROM ("); /* OUTER QUERY */
319 switch( brFlags & BRL_OPEN_CLOSED_MASK ){
320 case BRL_CLOSED_ONLY: {
321 blob_append_sql(&sql,
322 "SELECT name, isprivate, mtime FROM tmp_brlist WHERE isclosed"
323 );
324 break;
325 }
326 case BRL_BOTH: {
327 blob_append_sql(&sql,
328 "SELECT name, isprivate, mtime FROM tmp_brlist WHERE 1"
329 );
330 break;
331 }
332 case BRL_OPEN_ONLY: {
333 blob_append_sql(&sql,
334 "SELECT name, isprivate, mtime FROM tmp_brlist WHERE NOT isclosed"
335 );
336 break;
337 }
338 }
339 if( brFlags & BRL_PRIVATE ) blob_append_sql(&sql, " AND isprivate");
@@ -327,15 +341,19 @@
341 if( brFlags & BRL_ORDERBY_MTIME ){
342 blob_append_sql(&sql, " ORDER BY -mtime");
343 }else{
344 blob_append_sql(&sql, " ORDER BY name COLLATE nocase");
345 }
346 if( brFlags & BRL_REVERSE && !nLimitMRU ){
347 blob_append_sql(&sql," DESC");
348 }
349 if( nLimitMRU ){
350 blob_append_sql(&sql," LIMIT %d",nLimitMRU);
351 }
352 blob_append_sql(&sql,")"); /* OUTER QUERY */
353 if( brFlags & BRL_REVERSE && nLimitMRU ){
354 blob_append_sql(&sql," ORDER BY mtime"); /* OUTER QUERY */
355 }
356 db_prepare_blob(pQuery, &sql);
357 blob_reset(&sql);
358 }
359
@@ -594,25 +612,28 @@
612 ** > fossil branch info BRANCH-NAME
613 **
614 ** Print information about a branch
615 **
616 ** > fossil branch list|ls ?OPTIONS? ?GLOB?
617 ** > fossil branch lsh ?OPTIONS? ?LIMIT?
618 **
619 ** List all branches. Options:
620 ** -a|--all List all branches. Default show only open branches
621 ** -c|--closed List closed branches.
622 ** -p List only private branches.
623 ** -r Reverse the sort order
624 ** -t Show recently changed branches first
 
625 **
626 ** The current branch is marked with an asterisk. Private branches are
627 ** marked with a hash sign.
628 **
629 ** If GLOB is given, show only branches matching the pattern.
630 **
631 ** The "lsh" variant of this subcommand shows recently changed branches,
632 ** and accepts an optional LIMIT argument (defaults to 5) to cap output,
633 ** but no GLOB argument. All other options are supported, with -t being
634 ** an implied no-op.
635 **
636 ** > fossil branch new BRANCH-NAME BASIS ?OPTIONS?
637 **
638 ** Create a new branch BRANCH-NAME off of check-in BASIS.
639 ** Supported options for this subcommand include:
@@ -663,30 +684,33 @@
684 "SELECT datetime(mtime,toLocal()) FROM event"
685 " WHERE objid=%d", rid);
686 fossil_print("%s: open as of %s on %.16s\n", zBrName, zDate, zUuid);
687 }
688 }
689 }else if( strncmp(zCmd,"list",n)==0 ||
690 strncmp(zCmd, "ls", n)==0 ||
691 strcmp(zCmd, "lsh")==0 ){
692 Stmt q;
693 int vid;
694 char *zCurrent = 0;
695 const char *zBrNameGlob = 0;
696 int nLimit = 0;
697 int brFlags = BRL_OPEN_ONLY;
698 if( find_option("all","a",0)!=0 ) brFlags = BRL_BOTH;
699 if( find_option("closed","c",0)!=0 ) brFlags = BRL_CLOSED_ONLY;
700 if( find_option("t",0,0)!=0 ) brFlags |= BRL_ORDERBY_MTIME;
701 if( find_option("r",0,0)!=0 ) brFlags |= BRL_REVERSE;
702 if( find_option("p",0,0)!=0 ) brFlags |= BRL_PRIVATE;
703
704 if( strcmp(zCmd, "lsh")==0 ){
705 nLimit = 5;
 
706 if( g.argc>4 || g.argc==4 && (nLimit = atoi(g.argv[3]))==0 ){
707 fossil_fatal("the lsh subcommand allows one optional numeric argument");
708 }
709 brFlags |= BRL_ORDERBY_MTIME;
710 }else{
711 if( g.argc >= 4 ) zBrNameGlob = g.argv[3];
712 }
713
714 if( g.localOpen ){
715 vid = db_lget_int("checkout", 0);
716 zCurrent = db_text(0, "SELECT value FROM tagxref"
@@ -724,11 +748,11 @@
748 usage("branch unhide branch-name(s)...");
749 }
750 branch_cmd_hide(3,0);
751 }else{
752 fossil_fatal("branch subcommand should be one of: "
753 "close current hide info list ls lsh new reopen unhide");
754 }
755 }
756
757 /*
758 ** This is the new-style branch-list page that shows the branch names
759

Keyboard Shortcuts

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