mercurial/repair.py
changeset 5910 b9a830fa10f6
parent 5909 f45f7390c1c5
child 6147 53ae5af55db3
equal deleted inserted replaced
5909:f45f7390c1c5 5910:b9a830fa10f6
    29         os.mkdir(backupdir)
    29         os.mkdir(backupdir)
    30     name = os.path.join(backupdir, "%s-%s" % (short(node), suffix))
    30     name = os.path.join(backupdir, "%s-%s" % (short(node), suffix))
    31     repo.ui.warn("saving bundle to %s\n" % name)
    31     repo.ui.warn("saving bundle to %s\n" % name)
    32     return changegroup.writebundle(cg, name, "HG10BZ")
    32     return changegroup.writebundle(cg, name, "HG10BZ")
    33 
    33 
    34 def _collectfilenodes(repo, striprev):
    34 def _collectfiles(repo, striprev):
    35     """find out the first node that should be stripped from each filelog"""
    35     """find out the filelogs affected by the strip"""
    36     mm = repo.changectx(striprev).manifest()
    36     files = {}
    37     filenodes = {}
       
    38 
    37 
    39     for x in xrange(striprev, repo.changelog.count()):
    38     for x in xrange(striprev, repo.changelog.count()):
    40         for name in repo.changectx(x).files():
    39         for name in repo.changectx(x).files():
    41             if name in filenodes:
    40             if name in files:
    42                 continue
    41                 continue
    43             filenodes[name] = mm.get(name)
    42             files[name] = 1
    44 
    43 
    45     return filenodes
    44     files = files.keys()
       
    45     files.sort()
       
    46     return files
    46 
    47 
    47 def _collectextranodes(repo, files, link):
    48 def _collectextranodes(repo, files, link):
    48     """return the nodes that have to be saved before the strip"""
    49     """return the nodes that have to be saved before the strip"""
    49     def collectone(revlog):
    50     def collectone(revlog):
    50         extra = []
    51         extra = []
    77         extra = collectone(f)
    78         extra = collectone(f)
    78         if extra:
    79         if extra:
    79             extranodes[fname] = extra
    80             extranodes[fname] = extra
    80 
    81 
    81     return extranodes
    82     return extranodes
    82 
       
    83 def _stripall(repo, striprev, filenodes):
       
    84     """strip the requested nodes from the filelogs"""
       
    85     # we go in two steps here so the strip loop happens in a
       
    86     # sensible order.  When stripping many files, this helps keep
       
    87     # our disk access patterns under control.
       
    88 
       
    89     files = filenodes.keys()
       
    90     files.sort()
       
    91     for name in files:
       
    92         f = repo.file(name)
       
    93         fnode = filenodes[name]
       
    94         frev = 0
       
    95         if fnode is not None and fnode in f.nodemap:
       
    96             frev = f.rev(fnode)
       
    97         f.strip(frev, striprev)
       
    98 
    83 
    99 def strip(ui, repo, node, backup="all"):
    84 def strip(ui, repo, node, backup="all"):
   100     cl = repo.changelog
    85     cl = repo.changelog
   101     # TODO delete the undo files, and handle undo of merge sets
    86     # TODO delete the undo files, and handle undo of merge sets
   102     pp = cl.parents(node)
    87     pp = cl.parents(node)
   136             saveheads.append(h)
   121             saveheads.append(h)
   137             for x in r:
   122             for x in r:
   138                 if cl.rev(x) > striprev:
   123                 if cl.rev(x) > striprev:
   139                     savebases[x] = 1
   124                     savebases[x] = 1
   140 
   125 
   141     filenodes = _collectfilenodes(repo, striprev)
   126     files = _collectfiles(repo, striprev)
   142 
   127 
   143     extranodes = _collectextranodes(repo, filenodes, striprev)
   128     extranodes = _collectextranodes(repo, files, striprev)
   144 
   129 
   145     # create a changegroup for all the branches we need to keep
   130     # create a changegroup for all the branches we need to keep
   146     if backup == "all":
   131     if backup == "all":
   147         _bundle(repo, [node], cl.heads(), node, 'backup')
   132         _bundle(repo, [node], cl.heads(), node, 'backup')
   148     if saveheads or extranodes:
   133     if saveheads or extranodes:
   149         chgrpfile = _bundle(repo, savebases.keys(), saveheads, node, 'temp',
   134         chgrpfile = _bundle(repo, savebases.keys(), saveheads, node, 'temp',
   150                             extranodes)
   135                             extranodes)
   151 
   136 
   152     _stripall(repo, striprev, filenodes)
   137     cl.strip(striprev)
       
   138     repo.manifest.strip(striprev)
       
   139     for name in files:
       
   140         f = repo.file(name)
       
   141         f.strip(striprev)
   153 
   142 
   154     change = cl.read(node)
       
   155     cl.strip(striprev, striprev)
       
   156     repo.manifest.strip(repo.manifest.rev(change[0]), striprev)
       
   157     if saveheads or extranodes:
   143     if saveheads or extranodes:
   158         ui.status("adding branch\n")
   144         ui.status("adding branch\n")
   159         f = open(chgrpfile, "rb")
   145         f = open(chgrpfile, "rb")
   160         gen = changegroup.readbundle(f, chgrpfile)
   146         gen = changegroup.readbundle(f, chgrpfile)
   161         repo.addchangegroup(gen, 'strip', 'bundle:' + chgrpfile, True)
   147         repo.addchangegroup(gen, 'strip', 'bundle:' + chgrpfile, True)