mercurial/hg.py
changeset 46 93e868fa0db8
parent 44 e825a68d7227
child 48 9f64181ff9a9
equal deleted inserted replaced
45:f2b2d5daec30 46:93e868fa0db8
   556 
   556 
   557     def remove(self, list):
   557     def remove(self, list):
   558         dl = self.opener("to-remove", "a")
   558         dl = self.opener("to-remove", "a")
   559         for f in list:
   559         for f in list:
   560             dl.write(f + "\n")
   560             dl.write(f + "\n")
       
   561 
       
   562     def newer(self, node):
       
   563         nodes = []
       
   564         for i in xrange(self.changelog.rev(node) + 1, self.changelog.count()):
       
   565             nodes.append(self.changelog.node(i))
       
   566 
       
   567         return nodes
       
   568 
       
   569     def changegroup(self, nodes):
       
   570         # construct the link map
       
   571         linkmap = {}
       
   572         for n in nodes:
       
   573             linkmap[self.changelog.rev(n)] = n
       
   574 
       
   575         # construct a list of all changed files
       
   576         changed = {}
       
   577         for n in nodes:
       
   578             c = self.changelog.read(n)
       
   579             for f in c[3]:
       
   580                 changed[f] = 1
       
   581         changed = changed.keys()
       
   582         changed.sort()
       
   583 
       
   584         # the changegroup is changesets + manifests + all file revs
       
   585         cg = []
       
   586         revs = [ self.changelog.rev(n) for n in nodes ]
       
   587 
       
   588         g = self.changelog.group(linkmap)
       
   589         cg.append(g)
       
   590         g = self.manifest.group(linkmap)
       
   591         cg.append(g)
       
   592 
       
   593         for f in changed:
       
   594             g = self.file(f).group(linkmap)
       
   595             if not g: raise "couldn't find change to %s" % f
       
   596             l = struct.pack(">l", len(f))
       
   597             cg += [l, f, g]
       
   598 
       
   599         return compress("".join(cg))
       
   600 
       
   601     def addchangegroup(self, data):
       
   602         data = decompress(data)
       
   603         def getlen(data, pos):
       
   604             return struct.unpack(">l", data[pos:pos + 4])[0]
       
   605         
       
   606         tr = self.transaction()
       
   607         simple = True
       
   608 
       
   609         print "merging changesets"
       
   610         # pull off the changeset group
       
   611         l = getlen(data, 0)
       
   612         csg = data[0:l]
       
   613         pos = l
       
   614         co = self.changelog.tip()
       
   615         cn = self.changelog.addgroup(csg, lambda x: self.changelog.count(), tr)
       
   616 
       
   617         print "merging manifests"
       
   618         # pull off the manifest group
       
   619         l = getlen(data, pos)
       
   620         mfg = data[pos: pos + l]
       
   621         pos += l
       
   622         mo = self.manifest.tip()
       
   623         mn = self.manifest.addgroup(mfg, lambda x: self.changelog.rev(x), tr)
       
   624 
       
   625         # do we need a resolve?
       
   626         if self.changelog.ancestor(co, cn) != co:
       
   627             print "NEED RESOLVE"
       
   628             simple = False
       
   629             resolverev = self.changelog.count()
       
   630 
       
   631         # process the files
       
   632         print "merging files"
       
   633         new = {}
       
   634         while pos < len(data):
       
   635             l = getlen(data, pos)
       
   636             pos += 4
       
   637             f = data[pos:pos + l]
       
   638             pos += l
       
   639 
       
   640             l = getlen(data, pos)
       
   641             fg = data[pos: pos + l]
       
   642             pos += l
       
   643 
       
   644             fl = self.file(f)
       
   645             o = fl.tip()
       
   646             n = fl.addgroup(fg, lambda x: self.changelog.rev(x), tr)
       
   647             if not simple:
       
   648                 new[fl] = fl.resolvedag(o, n, tr, resolverev)
       
   649 
       
   650         # For simple merges, we don't need to resolve manifests or changesets
       
   651         if simple:
       
   652             tr.close()
       
   653             return
       
   654 
       
   655         # resolve the manifest to point to all the merged files
       
   656         self.ui.status("resolving manifests\n")
       
   657         ma = self.manifest.ancestor(mm, mo)
       
   658         mmap = self.manifest.read(mm) # mine
       
   659         omap = self.manifest.read(mo) # other
       
   660         amap = self.manifest.read(ma) # ancestor
       
   661         nmap = {}
       
   662 
       
   663         for f, mid in mmap.iteritems():
       
   664             if f in omap:
       
   665                 if mid != omap[f]: 
       
   666                     nmap[f] = new.get(f, mid) # use merged version
       
   667                 else:
       
   668                     nmap[f] = new.get(f, mid) # they're the same
       
   669                 del omap[f]
       
   670             elif f in amap:
       
   671                 if mid != amap[f]: 
       
   672                     pass # we should prompt here
       
   673                 else:
       
   674                     pass # other deleted it
       
   675             else:
       
   676                 nmap[f] = new.get(f, mid) # we created it
       
   677                 
       
   678         del mmap
       
   679 
       
   680         for f, oid in omap.iteritems():
       
   681             if f in amap:
       
   682                 if oid != amap[f]:
       
   683                     pass # this is the nasty case, we should prompt
       
   684                 else:
       
   685                     pass # probably safe
       
   686             else:
       
   687                 nmap[f] = new.get(f, oid) # remote created it
       
   688 
       
   689         del omap
       
   690         del amap
       
   691 
       
   692         node = self.manifest.add(nmap, tr, resolverev, mm, mo)
       
   693 
       
   694         # Now all files and manifests are merged, we add the changed files
       
   695         # and manifest id to the changelog
       
   696         self.ui.status("committing merge changeset\n")
       
   697         new = new.keys()
       
   698         new.sort()
       
   699         if co == cn: cn = -1
       
   700 
       
   701         edittext = "\n"+"".join(["HG: changed %s\n" % f for f in new])
       
   702         edittext = self.ui.edit(edittext)
       
   703         n = self.changelog.add(node, new, edittext, tr, co, cn)
       
   704 
       
   705         tr.close()
   561 
   706 
   562 class ui:
   707 class ui:
   563     def __init__(self, verbose=False, debug=False):
   708     def __init__(self, verbose=False, debug=False):
   564         self.verbose = verbose
   709         self.verbose = verbose
   565     def write(self, *args):
   710     def write(self, *args):