hgext/transplant.py
changeset 3759 e96f97ca0358
parent 3758 889f7e74a0d9
child 3827 2db191165e9a
equal deleted inserted replaced
3758:889f7e74a0d9 3759:e96f97ca0358
   138                                  % (rev, revlog.short(node)))
   138                                  % (rev, revlog.short(node)))
   139                     patchfile = None
   139                     patchfile = None
   140                 else:
   140                 else:
   141                     fd, patchfile = tempfile.mkstemp(prefix='hg-transplant-')
   141                     fd, patchfile = tempfile.mkstemp(prefix='hg-transplant-')
   142                     fp = os.fdopen(fd, 'w')
   142                     fp = os.fdopen(fd, 'w')
   143                     patch.export(source, [node], fp=fp, opts=diffopts)
   143                     patch.diff(source, parents[0], node, fp=fp, opts=diffopts)
   144                     fp.close()
   144                     fp.close()
   145 
   145 
   146                 del revmap[rev]
   146                 del revmap[rev]
   147                 if patchfile or domerge:
   147                 if patchfile or domerge:
   148                     try:
   148                     try:
   169 
   169 
   170     def filter(self, filter, changelog, patchfile):
   170     def filter(self, filter, changelog, patchfile):
   171         '''arbitrarily rewrite changeset before applying it'''
   171         '''arbitrarily rewrite changeset before applying it'''
   172 
   172 
   173         self.ui.status('filtering %s\n' % patchfile)
   173         self.ui.status('filtering %s\n' % patchfile)
   174         util.system('%s %s' % (filter, util.shellquote(patchfile)),
   174         user, date, msg = (changelog[1], changelog[2], changelog[4])
   175                     environ={'HGUSER': changelog[1]},
   175 
   176                     onerr=util.Abort, errprefix=_('filter failed'))
   176         fd, headerfile = tempfile.mkstemp(prefix='hg-transplant-')
       
   177         fp = os.fdopen(fd, 'w')
       
   178         fp.write("# HG changeset patch\n")
       
   179         fp.write("# User %s\n" % user)
       
   180         fp.write("# Date %d %d\n" % date)
       
   181         fp.write(changelog[4].rstrip())
       
   182         fp.write("\n\n")
       
   183         fp.close()
       
   184 
       
   185         try:
       
   186             util.system('%s %s %s' % (filter, util.shellquote(headerfile),
       
   187                                    util.shellquote(patchfile)),
       
   188                         environ={'HGUSER': changelog[1]},
       
   189                         onerr=util.Abort, errprefix=_('filter failed'))
       
   190             user, date, msg = self.parselog(file(headerfile))[1:4]
       
   191         finally:
       
   192             os.unlink(headerfile)
       
   193 
       
   194         return (user, date, msg)
   177 
   195 
   178     def applyone(self, repo, node, cl, patchfile, merge=False, log=False,
   196     def applyone(self, repo, node, cl, patchfile, merge=False, log=False,
   179                  filter=None, lock=None, wlock=None):
   197                  filter=None, lock=None, wlock=None):
   180         '''apply the patch in patchfile to the repository as a transplant'''
   198         '''apply the patch in patchfile to the repository as a transplant'''
   181         (manifest, user, (time, timezone), files, message) = cl[:5]
   199         (manifest, user, (time, timezone), files, message) = cl[:5]
   182         date = "%d %d" % (time, timezone)
   200         date = "%d %d" % (time, timezone)
   183         extra = {'transplant_source': node}
   201         extra = {'transplant_source': node}
   184         if filter:
   202         if filter:
   185             self.filter(filter, cl, patchfile)
   203             (user, date, message) = self.filter(filter, cl, patchfile)
   186             patchfile, message, user, date = patch.extract(self.ui, file(patchfile))
       
   187 
   204 
   188         if log:
   205         if log:
   189             message += '\n(transplanted from %s)' % revlog.hex(node)
   206             message += '\n(transplanted from %s)' % revlog.hex(node)
   190 
   207 
   191         self.ui.status(_('applying %s\n') % revlog.short(node))
   208         self.ui.status(_('applying %s\n') % revlog.short(node))
   202                     if not files:
   219                     if not files:
   203                         self.ui.warn(_('%s: empty changeset') % revlog.hex(node))
   220                         self.ui.warn(_('%s: empty changeset') % revlog.hex(node))
   204                         return
   221                         return
   205                 finally:
   222                 finally:
   206                     files = patch.updatedir(self.ui, repo, files, wlock=wlock)
   223                     files = patch.updatedir(self.ui, repo, files, wlock=wlock)
   207                 if filter:
       
   208                     os.unlink(patchfile)
       
   209             except Exception, inst:
   224             except Exception, inst:
   210                 if filter:
   225                 if filter:
   211                     os.unlink(patchfile)
   226                     os.unlink(patchfile)
   212                 seriespath = os.path.join(self.path, 'series')
   227                 seriespath = os.path.join(self.path, 'series')
   213                 if os.path.exists(seriespath):
   228                 if os.path.exists(seriespath):
   300             series.write('# Merges\n')
   315             series.write('# Merges\n')
   301             for m in merges:
   316             for m in merges:
   302                 series.write(revlog.hex(m) + '\n')
   317                 series.write(revlog.hex(m) + '\n')
   303         series.close()
   318         series.close()
   304 
   319 
       
   320     def parselog(self, fp):
       
   321         parents = []
       
   322         message = []
       
   323         node = revlog.nullid
       
   324         inmsg = False
       
   325         for line in fp.read().splitlines():
       
   326             if inmsg:
       
   327                 message.append(line)
       
   328             elif line.startswith('# User '):
       
   329                 user = line[7:]
       
   330             elif line.startswith('# Date '):
       
   331                 date = line[7:]
       
   332             elif line.startswith('# Node ID '):
       
   333                 node = revlog.bin(line[10:])
       
   334             elif line.startswith('# Parent '):
       
   335                 parents.append(revlog.bin(line[9:]))
       
   336             elif not line.startswith('#'):
       
   337                 inmsg = True
       
   338                 message.append(line)
       
   339         return (node, user, date, '\n'.join(message), parents)
       
   340             
   305     def log(self, user, date, message, p1, p2, merge=False):
   341     def log(self, user, date, message, p1, p2, merge=False):
   306         '''journal changelog metadata for later recover'''
   342         '''journal changelog metadata for later recover'''
   307 
   343 
   308         if not os.path.isdir(self.path):
   344         if not os.path.isdir(self.path):
   309             os.mkdir(self.path)
   345             os.mkdir(self.path)
   316             fp.write('# Parent ' + revlog.hex(p2) + '\n')
   352             fp.write('# Parent ' + revlog.hex(p2) + '\n')
   317         fp.write(message.rstrip() + '\n')
   353         fp.write(message.rstrip() + '\n')
   318         fp.close()
   354         fp.close()
   319 
   355 
   320     def readlog(self):
   356     def readlog(self):
   321         parents = []
   357         return self.parselog(self.opener('journal'))
   322         message = []
       
   323         for line in self.opener('journal').read().splitlines():
       
   324             if line.startswith('# User '):
       
   325                 user = line[7:]
       
   326             elif line.startswith('# Date '):
       
   327                 date = line[7:]
       
   328             elif line.startswith('# Node ID '):
       
   329                 node = revlog.bin(line[10:])
       
   330             elif line.startswith('# Parent '):
       
   331                 parents.append(revlog.bin(line[9:]))
       
   332             else:
       
   333                 message.append(line)
       
   334         return (node, user, date, '\n'.join(message), parents)
       
   335 
   358 
   336     def unlog(self):
   359     def unlog(self):
   337         '''remove changelog journal'''
   360         '''remove changelog journal'''
   338         absdst = os.path.join(self.path, 'journal')
   361         absdst = os.path.join(self.path, 'journal')
   339         if os.path.exists(absdst):
   362         if os.path.exists(absdst):