hgext/convert/cvsps.py
changeset 8756 6019e6517f95
parent 8661 883f14fcd1df
child 8890 c487719cccef
equal deleted inserted replaced
8755:a2b4ddee3785 8756:6019e6517f95
    34         .revision  - revision number as tuple
    34         .revision  - revision number as tuple
    35         .tags      - list of tags on the file
    35         .tags      - list of tags on the file
    36         .synthetic - is this a synthetic "file ... added on ..." revision?
    36         .synthetic - is this a synthetic "file ... added on ..." revision?
    37         .mergepoint- the branch that has been merged from
    37         .mergepoint- the branch that has been merged from
    38                      (if present in rlog output)
    38                      (if present in rlog output)
       
    39         .branchpoints- the branches that start at the current entry
    39     '''
    40     '''
    40     def __init__(self, **entries):
    41     def __init__(self, **entries):
    41         self.__dict__.update(entries)
    42         self.__dict__.update(entries)
    42 
    43 
    43     def __repr__(self):
    44     def __repr__(self):
   398             if revn > 3 and (revn % 2) == 0:
   399             if revn > 3 and (revn % 2) == 0:
   399                 e.branch = tags.get(e.revision[:-1], [None])[0]
   400                 e.branch = tags.get(e.revision[:-1], [None])[0]
   400             else:
   401             else:
   401                 e.branch = None
   402                 e.branch = None
   402 
   403 
       
   404             # find the branches starting from this revision
       
   405             branchpoints = set()
       
   406             for branch, revision in branchmap.iteritems():
       
   407                 revparts = tuple([int(i) for i in revision.split('.')])
       
   408                 if revparts[-2] == 0 and revparts[-1] % 2 == 0:
       
   409                     # normal branch
       
   410                     if revparts[:-2] == e.revision:
       
   411                         branchpoints.add(branch)
       
   412                 elif revparts == (1,1,1): # vendor branch
       
   413                     if revparts in e.branches:
       
   414                         branchpoints.add(branch)
       
   415             e.branchpoints = branchpoints
       
   416 
   403             log.append(e)
   417             log.append(e)
   404 
   418 
   405             if len(log) % 100 == 0:
   419             if len(log) % 100 == 0:
   406                 ui.status(util.ellipsis('%d %s' % (len(log), e.file), 80)+'\n')
   420                 ui.status(util.ellipsis('%d %s' % (len(log), e.file), 80)+'\n')
   407 
   421 
   451         .parents   - list of one or two parent changesets
   465         .parents   - list of one or two parent changesets
   452         .tags      - list of tags on this changeset
   466         .tags      - list of tags on this changeset
   453         .synthetic - from synthetic revision "file ... added on branch ..."
   467         .synthetic - from synthetic revision "file ... added on branch ..."
   454         .mergepoint- the branch that has been merged from
   468         .mergepoint- the branch that has been merged from
   455                      (if present in rlog output)
   469                      (if present in rlog output)
       
   470         .branchpoints- the branches that start at the current entry
   456     '''
   471     '''
   457     def __init__(self, **entries):
   472     def __init__(self, **entries):
   458         self.__dict__.update(entries)
   473         self.__dict__.update(entries)
   459 
   474 
   460     def __repr__(self):
   475     def __repr__(self):
   475     files = set()
   490     files = set()
   476     c = None
   491     c = None
   477     for i, e in enumerate(log):
   492     for i, e in enumerate(log):
   478 
   493 
   479         # Check if log entry belongs to the current changeset or not.
   494         # Check if log entry belongs to the current changeset or not.
       
   495 
       
   496         # Since CVS is file centric, two different file revisions with
       
   497         # different branchpoints should be treated as belonging to two
       
   498         # different changesets (and the ordering is important and not
       
   499         # honoured by cvsps at this point).
       
   500         #
       
   501         # Consider the following case:
       
   502         # foo 1.1 branchpoints: [MYBRANCH]
       
   503         # bar 1.1 branchpoints: [MYBRANCH, MYBRANCH2]
       
   504         #
       
   505         # Here foo is part only of MYBRANCH, but not MYBRANCH2, e.g. a
       
   506         # later version of foo may be in MYBRANCH2, so foo should be the
       
   507         # first changeset and bar the next and MYBRANCH and MYBRANCH2
       
   508         # should both start off of the bar changeset. No provisions are
       
   509         # made to ensure that this is, in fact, what happens.
   480         if not (c and
   510         if not (c and
   481                   e.comment == c.comment and
   511                   e.comment == c.comment and
   482                   e.author == c.author and
   512                   e.author == c.author and
   483                   e.branch == c.branch and
   513                   e.branch == c.branch and
       
   514                   e.branchpoints == c.branchpoints and
   484                   ((c.date[0] + c.date[1]) <=
   515                   ((c.date[0] + c.date[1]) <=
   485                    (e.date[0] + e.date[1]) <=
   516                    (e.date[0] + e.date[1]) <=
   486                    (c.date[0] + c.date[1]) + fuzz) and
   517                    (c.date[0] + c.date[1]) + fuzz) and
   487                   e.file not in files):
   518                   e.file not in files):
   488             c = changeset(comment=e.comment, author=e.author,
   519             c = changeset(comment=e.comment, author=e.author,
   489                           branch=e.branch, date=e.date, entries=[],
   520                           branch=e.branch, date=e.date, entries=[],
   490                           mergepoint=getattr(e, 'mergepoint', None))
   521                           mergepoint=getattr(e, 'mergepoint', None),
       
   522                           branchpoints=getattr(e, 'branchpoints', set()))
   491             changesets.append(c)
   523             changesets.append(c)
   492             files = set()
   524             files = set()
   493             if len(changesets) % 100 == 0:
   525             if len(changesets) % 100 == 0:
   494                 t = '%d %s' % (len(changesets), repr(e.comment)[1:-1])
   526                 t = '%d %s' % (len(changesets), repr(e.comment)[1:-1])
   495                 ui.status(util.ellipsis(t, 80) + '\n')
   527                 ui.status(util.ellipsis(t, 80) + '\n')
   611 
   643 
   612         p = None
   644         p = None
   613         if c.branch in branches:
   645         if c.branch in branches:
   614             p = branches[c.branch]
   646             p = branches[c.branch]
   615         else:
   647         else:
   616             for f in c.entries:
   648             # first changeset on a new branch
   617                 p = max(p, versions.get((f.rcs, f.parent), None))
   649             # the parent is a changeset with the branch in its
       
   650             # branchpoints such that it is the latest possible
       
   651             # commit without any intervening, unrelated commits.
       
   652 
       
   653             for candidate in xrange(i):
       
   654                 if c.branch not in changesets[candidate].branchpoints:
       
   655                     if p is not None:
       
   656                         break
       
   657                     continue
       
   658                 p = candidate
   618 
   659 
   619         c.parents = []
   660         c.parents = []
   620         if p is not None:
   661         if p is not None:
   621             p = changesets[p]
   662             p = changesets[p]
   622 
   663 
   751                                                  '%Y/%m/%d %H:%M:%S %1%2'))
   792                                                  '%Y/%m/%d %H:%M:%S %1%2'))
   752             ui.write('Author: %s\n' % cs.author)
   793             ui.write('Author: %s\n' % cs.author)
   753             ui.write('Branch: %s\n' % (cs.branch or 'HEAD'))
   794             ui.write('Branch: %s\n' % (cs.branch or 'HEAD'))
   754             ui.write('Tag%s: %s \n' % (['', 's'][len(cs.tags)>1],
   795             ui.write('Tag%s: %s \n' % (['', 's'][len(cs.tags)>1],
   755                                   ','.join(cs.tags) or '(none)'))
   796                                   ','.join(cs.tags) or '(none)'))
       
   797             branchpoints = getattr(cs, 'branchpoints', None)
       
   798             if branchpoints:
       
   799                 ui.write('Branchpoints: %s \n' % ', '.join(branchpoints))
   756             if opts["parents"] and cs.parents:
   800             if opts["parents"] and cs.parents:
   757                 if len(cs.parents)>1:
   801                 if len(cs.parents)>1:
   758                     ui.write('Parents: %s\n' % (','.join([str(p.id) for p in cs.parents])))
   802                     ui.write('Parents: %s\n' % (','.join([str(p.id) for p in cs.parents])))
   759                 else:
   803                 else:
   760                     ui.write('Parent: %d\n' % cs.parents[0].id)
   804                     ui.write('Parent: %d\n' % cs.parents[0].id)