diff mercurial-common/src/python/load-substates-command.py @ 715:be86907926ae

new approach: remember hg sub-state file hash per commit, dump hash -> file, and log with refs
author eugene.petrenko@jetbrains.com
date Mon, 13 Jan 2014 18:51:13 +0100
parents 78266f6904df
children 0607a0504129
line wrap: on
line diff
--- a/mercurial-common/src/python/load-substates-command.py	Mon Jan 13 15:35:44 2014 +0100
+++ b/mercurial-common/src/python/load-substates-command.py	Mon Jan 13 18:51:13 2014 +0100
@@ -34,56 +34,86 @@
 
     ui.write("Fetching commits...")
 
+    NONE = "====="
+
     def b64(x):
       if x is None or x == "":
-        return "====="
-
+        return NONE
       return base64.b64encode( x )
 
     def fetch_commits():
       ui.write("Iterating over commits...\n")
       with open(outputFile + ".commits", "w", 5 * 1024 * 1024) as result:
-        result.write("format: prefix commitID commitHash num_parents parent branch num_tags tag user message date [.hgsub]\n")
+        result.write("format: prefix commitID commitHash num_parents parent branch num_tags tag user message date [.hgsub] [.hgsubstate]\n")
         result.flush()
 
+        commit_to_substates = {}
+
+        def update_sub_states(ctx):
+          def filenode(ctx, filename):
+            if filename in ctx.files():
+              try:
+                return node.hex(ctx.filenode(filename))
+              except:
+                # file could have been deleted => so there would be no filenode for it
+                return NONE
+            else:
+              return NONE
+
+          def notnull(a, ctx, i):
+            if a != NONE:
+              return a
+
+            for p in ctx.parents():
+              if commit_to_substates.has_key(p):
+                v = commit_to_substates[p][i]
+                if v != NONE:
+                  return v
+            return NONE
+
+          best_sub = notnull(filenode(ctx, ".hgsub"), ctx, 0)
+          best_state = notnull(filenode(ctx, ".hgsubstate"), ctx, 1)
+
+          commit_to_substates[ctx.node()] = (best_sub, best_state)
+
+          return (best_sub, best_state)
+
         for r in list(repo.changelog):
-          node = repo[r]
+          ctx = repo[r]
 
           result.write("$$@@@@ ")                           # magic
-          result.write( str( node.rev() ) )                 # commit Num
+          result.write( str( ctx.rev() ) )                 # commit Num
           result.write(" ")
-          result.write( node.hex() )                        # commit ID
+          result.write( ctx.hex() )                        # commit ID
           result.write(" ")
-          result.write( str( len( node.parents()) ) )       # num parents
+          result.write( str( len( ctx.parents()) ) )       # num parents
 
-          for p in node.parents():                          # parents
+          for p in ctx.parents():                          # parents
              result.write(" ")
              result.write(p.hex())
 
           result.write(" ")
-          result.write( b64( node.branch() ) )              # commit branch
+          result.write( b64( ctx.branch() ) )              # commit branch
 
           result.write(" ")
-          result.write( str( len( node.tags() ) ) )         # num tags
+          result.write( str( len( ctx.tags() ) ) )         # num tags
 
-          for tag in node.tags():                           # tags
+          for tag in ctx.tags():                           # tags
              result.write(" ")
              result.write( b64 ( tag ) )
 
           result.write(" ")                                 # user
-          result.write( b64( node.user()  ) )
+          result.write( b64( ctx.user()  ) )
 
           result.write(" ")                                 # message
-          result.write( b64( node.description() ) )
+          result.write( b64( ctx.description() ) )
 
           result.write(" ")                                 # date
-          result.write( util.datestr( node.date(), "%Y-%m-%dZ%H:%M:%ST%1%2") )
+          result.write( util.datestr( ctx.date(), "%Y-%m-%dZ%H:%M:%ST%1%2") )
 
-          if ".hgsub" in node.files() or ".hgsubstate" in node.files():
-            result.write(" .hgsub")
-          else:
-            result.write(" =====")
-
+          #resolve sub-repo mounts
+          (sub_node, state_node) = update_sub_states(ctx)
+          result.write(" " + sub_node + " " + state_node)
           result.write("\n")
 
         ui.write("Commits iteration completed")
@@ -96,7 +126,7 @@
 
         log = repo.file(filename)
         for r in log:
-           result.write("$$@@@@ " + node.hex(log.node(r)) + " " + b64(log.read(r)) + "\n")
+          result.write("$$@@@@ " + node.hex(log.node(r)) + " " + b64(log.read(r)) + "\n")
 
       ui.write("All revisions of file " + filename + " are fetched\n")