view mercurial-common/src/python/load-substates-command.py @ 1124:a14a2f7e74d8 development/2024.03.x tip

2024.03.x branch is created
author Nadia Burnasheva <nadezhda.burnasheva@jetbrains.com>
date Thu, 15 Feb 2024 11:33:35 +0100
parents e7df2ef5064b
children
line wrap: on
line source
#!/usr/bin/env python
##
##    Copyright 2000-2014 JetBrains
##
##     Licensed under the Apache License, Version 2.0 (the "License");
##       you may not use this file except in compliance with the License.
##      You may obtain a copy of the License at
##
##          http://www.apache.org/licenses/LICENSE-2.0
##
##       Unless required by applicable law or agreed to in writing, software
##       distributed under the License is distributed on an "AS IS" BASIS,
##       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
##       See the License for the specific language governing permissions and
##       limitations under the License.
##
##
##  http://www.gnu.org/licenses/gpl-faq.html#GPLModuleLicense
##  http://www.gnu.org/licenses/license-list.html#apache2
##  http://en.wikipedia.org/wiki/Apache_License#GPL_compatibility
##
##
"""
load-substates-command
"""

import base64
from mercurial import util, node
from threading import Thread


def load_substates_command(ui, repo, outputFile, **opts):
    """Tons of docs"""

    ui.write("Fetching commits...")

    NONE = "====="

    def b64(x):
      if x is None or x == "":
        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] [.hgsubstate]\n")
        result.flush()

        commit_to_substates = {}

        def update_sub_states(ctx):
          def filenode(ctx, filename, i):
            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
                # this also means we should avoid parents as file source
                return NONE
            else:
              for p in ctx.parents():
                if commit_to_substates.has_key(p.hex()):
                  v = commit_to_substates[p.hex()][i]
                  if v != NONE:
                    return v
            return NONE

          best_sub = filenode(ctx, ".hgsub", 0)
          best_state = filenode(ctx, ".hgsubstate", 1)
          commit_to_substates[ctx.hex()] = (best_sub, best_state)
          return best_sub, best_state

        for r in list(repo.changelog):
          ctx = repo[r]

          result.write("$$@@@@ ")                           # magic
          result.write( str( ctx.rev() ) )                 # commit Num
          result.write(" ")
          result.write( ctx.hex() )                        # commit ID
          result.write(" ")
          result.write( str( len( ctx.parents()) ) )       # num parents

          for p in ctx.parents():                          # parents
             result.write(" ")
             result.write(p.hex())

          result.write(" ")
          result.write( b64( ctx.branch() ) )              # commit branch

          result.write(" ")
          result.write( str( len( ctx.tags() ) ) )         # num tags

          for tag in ctx.tags():                           # tags
             result.write(" ")
             result.write( b64 ( tag ) )

          result.write(" ")                                 # user
          result.write( b64( ctx.user()  ) )

          result.write(" ")                                 # message
          result.write( b64( ctx.description() ) )

          result.write(" ")                                 # date
          result.write( util.datestr( ctx.date(), "%Y-%m-%dZ%H:%M:%ST%1%2") )

          #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")

    def fetch_file_revisions(filename):
      ui.write("Fetching revisions of " + filename + " file\n")
      with open(outputFile + filename, "w", 5 * 1024 * 1024) as result:
        result.write("format: prefix commitID base64(" + filename + ")\n")
        result.flush()

        log = repo.file(filename)
        for r in log:
          result.write("$$@@@@ " + node.hex(log.node(r)) + " " + b64(log.read(r)) + "\n")

      ui.write("All revisions of file " + filename + " are fetched\n")

    tasks = [
        Thread(target=fetch_commits, args=[], name="Fetch commits graph"),
        Thread(target=fetch_file_revisions, args=[".hgsub"], name="Fetch .hgsub"),
        Thread(target=fetch_file_revisions, args=[".hgsubstate"], name="Fetch .hgsubstate"),
    ]

    for task in tasks:
        task.start()

    for task in tasks:
        task.join()

    ui.write("\n##Completed##\n")


#so here goes command registration and options
cmdtable = {
    b"load-substates": (load_substates_command, [ ], b" [options] OUTPUT_FILE")
}

load_substates_command.norepo = False
load_substates_command.optionalrepo = False
load_substates_command.inferrepo = False

testedwith = '4.2.1'
buglink = "upsource-support@jetbrains.com"