git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[StGit RFC] Make "stg branch -l" faster by getting all git config information in one call

From
David Kågedal <davidk@lysator.liu.se>
Date
Dec 13, 2007, 13:38 UTC
Message-ID
<20071213133653.13925.89254.stgit@krank>
This isn't a real patch yet, but it is good enough for my usage.

I have a fair amount of branches, and I noticed that "stg branch -l" takes ridiculously long to finish. The problem is that it creates stack objects for all branches, and indiviudally extract information about them one after one. With 20 branches, it took almost 2 seconds to run. Compare that with the 0.01 seconds it takes to run "git branch".

I made a patch that uses "git config --get-regexp" to get the description and stgit.stackformatversion options for all branches at once, and ignore the "protected" flag that I don't use. With this change, I'm almost down to half a second, which almost makes it usable.

There are still a bunch of redundant invokations of git, but python startup times are hard to get around.

Maybe someone can help me find a quicker replacement for the get_protected call?

---
 stgit/commands/branch.py |   39 ++++++++++++++++++++++++++++++---------
 1 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/stgit/commands/branch.py b/stgit/commands/branch.py
index 50684bb..f4b0c33 100644
--- a/stgit/commands/branch.py
+++ b/stgit/commands/branch.py
@@ -72,21 +72,21 @@ options = [make_option('-c', '--create',
 def __is_current_branch(branch_name):
     return crt_series.get_name() == branch_name
 
-def __print_branch(branch_name, length):
+def __print_branch(branch_name, description, version, length):
     initialized = ' '
     current = ' '
     protected = ' '
 
-    branch = stack.Series(branch_name)
+    #branch = stack.Series(branch_name)
 
-    if branch.is_initialised():
+    if version != None:
         initialized = 's'
     if __is_current_branch(branch_name):
         current = '>'
-    if branch.get_protected():
-        protected = 'p'
+    #if branch.get_protected():
+    #    protected = 'p'
     out.stdout(current + ' ' + initialized + protected + '\t'
-               + branch_name.ljust(length) + '  | ' + branch.get_description())
+               + branch_name.ljust(length) + '  | ' + (description or ''))
 
 def __delete_branch(doomed_name, force = False):
     doomed = stack.Series(doomed_name)
@@ -100,6 +100,23 @@ def __delete_branch(doomed_name, force = False):
     doomed.delete(force)
     out.done()
 
+class FormatException(StgException):
+    pass
+
+def __get_all_branch_config(key):
+    key = re.escape(key)
+    lines = git.GRun('config', '--get-regexp',
+                     r'branch\..*\.'+key).returns([0,1]).output_lines()
+    val_re = re.compile(r'branch\.(.*)\.%s (.*)' % key)
+    result = {}
+    for line in lines:
+        m = val_re.match(line)
+        if not m:
+            raise FormatException("unknown output from git config")
+        branch, data = m.groups()
+        result[branch] = data
+    return result
+
 def func(parser, options, args):
 
     if options.create:
@@ -198,11 +215,15 @@ def func(parser, options, args):
         branches = git.get_heads()
         branches.sort()
 
+        descriptions = __get_all_branch_config('description')
+        versions = __get_all_branch_config('stgit.stackformatversion')
+
         if branches:
             out.info('Available branches:')
-            max_len = max([len(i) for i in branches])
-            for i in branches:
-                __print_branch(i, max_len)
+            max_len = max(len(i) for i in branches)
+            for branch in branches:
+                __print_branch(branch, descriptions.get(branch),
+                               versions.get(branch), max_len)
         else:
             out.info('No branches')
         return
Next: David Kågedal
Message 1 of 13 in “[StGit RFC] Make "stg branch -l" faster by getting all git config information in one call”
  1. David KågedalDec 13, 2007
  2. git config --get-regexp exit statusDavid Kågedal, Dec 13, 2007
  3. Junio C HamanoDec 13, 2007
  4. Catalin MarinasDec 13, 2007
  5. David KågedalDec 13, 2007
  6. David KågedalDec 13, 2007
  7. Catalin MarinasDec 13, 2007
  8. David KågedalDec 13, 2007
  9. Karl HasselströmDec 13, 2007
  10. Karl HasselströmDec 13, 2007
  11. Catalin MarinasDec 13, 2007
  12. David KågedalDec 13, 2007
  13. Karl HasselströmDec 13, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.