hgext/convert/cvsps.py
changeset 7956 3e7611a83230
parent 7950 9bbcfa898cd3
child 7969 a969b1470987
equal deleted inserted replaced
7955:c3d4ff03ec72 7956:3e7611a83230
    32         .parent    - Previous revision of this entry
    32         .parent    - Previous revision of this entry
    33         .rcs       - name of file as returned from CVS
    33         .rcs       - name of file as returned from CVS
    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 (if present in rlog output)
    37     '''
    38     '''
    38     def __init__(self, **entries):
    39     def __init__(self, **entries):
    39         self.__dict__.update(entries)
    40         self.__dict__.update(entries)
    40 
    41 
    41 class logerror(Exception):
    42 class logerror(Exception):
   103     re_20 = re.compile('symbolic names:')
   104     re_20 = re.compile('symbolic names:')
   104     re_30 = re.compile('\t(.+): ([\\d.]+)$')
   105     re_30 = re.compile('\t(.+): ([\\d.]+)$')
   105     re_31 = re.compile('----------------------------$')
   106     re_31 = re.compile('----------------------------$')
   106     re_32 = re.compile('=============================================================================$')
   107     re_32 = re.compile('=============================================================================$')
   107     re_50 = re.compile('revision ([\\d.]+)(\s+locked by:\s+.+;)?$')
   108     re_50 = re.compile('revision ([\\d.]+)(\s+locked by:\s+.+;)?$')
   108     re_60 = re.compile(r'date:\s+(.+);\s+author:\s+(.+);\s+state:\s+(.+?);(\s+lines:\s+(\+\d+)?\s+(-\d+)?;)?')
   109     re_60 = re.compile(r'date:\s+(.+);\s+author:\s+(.+);\s+state:\s+(.+?);(\s+lines:\s+(\+\d+)?\s+(-\d+)?;)?(.*mergepoint:\s+([^;]+);)?')
   109     re_70 = re.compile('branches: (.+);$')
   110     re_70 = re.compile('branches: (.+);$')
   110 
   111 
   111     file_added_re = re.compile(r'file [^/]+ was (initially )?added on branch')
   112     file_added_re = re.compile(r'file [^/]+ was (initially )?added on branch')
   112 
   113 
   113     prefix = ''   # leading path to strip of what we get from CVS
   114     prefix = ''   # leading path to strip of what we get from CVS
   185         cmd.append('-d>%s' % date)
   186         cmd.append('-d>%s' % date)
   186     cmd.append(directory)
   187     cmd.append(directory)
   187 
   188 
   188     # state machine begins here
   189     # state machine begins here
   189     tags = {}     # dictionary of revisions on current file with their tags
   190     tags = {}     # dictionary of revisions on current file with their tags
       
   191     branchmap = {} # mapping between branch names and revision numbers
   190     state = 0
   192     state = 0
   191     store = False # set when a new record can be appended
   193     store = False # set when a new record can be appended
   192 
   194 
   193     cmd = [util.shellquote(arg) for arg in cmd]
   195     cmd = [util.shellquote(arg) for arg in cmd]
   194     ui.note(_("running %s\n") % (' '.join(cmd)))
   196     ui.note(_("running %s\n") % (' '.join(cmd)))
   242             state = 2
   244             state = 2
   243 
   245 
   244         elif state == 2:
   246         elif state == 2:
   245             # expect 'symbolic names'
   247             # expect 'symbolic names'
   246             if re_20.match(line):
   248             if re_20.match(line):
       
   249                 branchmap = {}
   247                 state = 3
   250                 state = 3
   248 
   251 
   249         elif state == 3:
   252         elif state == 3:
   250             # read the symbolic names and store as tags
   253             # read the symbolic names and store as tags
   251             match = re_30.match(line)
   254             match = re_30.match(line)
   259                 rev = tuple(rev)
   262                 rev = tuple(rev)
   260 
   263 
   261                 if rev not in tags:
   264                 if rev not in tags:
   262                     tags[rev] = []
   265                     tags[rev] = []
   263                 tags[rev].append(match.group(1))
   266                 tags[rev].append(match.group(1))
       
   267                 branchmap[match.group(1)] = match.group(2)
   264 
   268 
   265             elif re_31.match(line):
   269             elif re_31.match(line):
   266                 state = 5
   270                 state = 5
   267             elif re_32.match(line):
   271             elif re_32.match(line):
   268                 state = 0
   272                 state = 0
   309                     e.lines = (int(match.group(5)), 0)
   313                     e.lines = (int(match.group(5)), 0)
   310             elif match.group(6):
   314             elif match.group(6):
   311                 e.lines = (0, int(match.group(6)))
   315                 e.lines = (0, int(match.group(6)))
   312             else:
   316             else:
   313                 e.lines = None
   317                 e.lines = None
       
   318 
       
   319             if match.group(7): # cvsnt mergepoint
       
   320                 myrev = match.group(8).split('.')
       
   321                 if len(myrev) == 2: # head
       
   322                     e.mergepoint = 'HEAD'
       
   323                 else:
       
   324                     myrev = '.'.join(myrev[:-2] + ['0', myrev[-2]])
       
   325                     branches = [b for b in branchmap if branchmap[b] == myrev]
       
   326                     assert len(branches) == 1, 'unknown branch: %s' % e.mergepoint
       
   327                     e.mergepoint = branches[0]
       
   328             else:
       
   329                 e.mergepoint = None
   314             e.comment = []
   330             e.comment = []
   315             state = 7
   331             state = 7
   316 
   332 
   317         elif state == 7:
   333         elif state == 7:
   318             # read the revision numbers of branches that start at this revision
   334             # read the revision numbers of branches that start at this revision
   418         .date      - the commit date as a (time,tz) tuple
   434         .date      - the commit date as a (time,tz) tuple
   419         .entries   - list of logentry objects in this changeset
   435         .entries   - list of logentry objects in this changeset
   420         .parents   - list of one or two parent changesets
   436         .parents   - list of one or two parent changesets
   421         .tags      - list of tags on this changeset
   437         .tags      - list of tags on this changeset
   422         .synthetic - from synthetic revision "file ... added on branch ..."
   438         .synthetic - from synthetic revision "file ... added on branch ..."
       
   439         .mergepoint- the branch that has been merged from (if present in rlog output)
   423     '''
   440     '''
   424     def __init__(self, **entries):
   441     def __init__(self, **entries):
   425         self.__dict__.update(entries)
   442         self.__dict__.update(entries)
   426 
   443 
   427 def createchangeset(ui, log, fuzz=60, mergefrom=None, mergeto=None):
   444 def createchangeset(ui, log, fuzz=60, mergefrom=None, mergeto=None):
   446                   ((c.date[0] + c.date[1]) <=
   463                   ((c.date[0] + c.date[1]) <=
   447                    (e.date[0] + e.date[1]) <=
   464                    (e.date[0] + e.date[1]) <=
   448                    (c.date[0] + c.date[1]) + fuzz) and
   465                    (c.date[0] + c.date[1]) + fuzz) and
   449                   e.file not in files):
   466                   e.file not in files):
   450             c = changeset(comment=e.comment, author=e.author,
   467             c = changeset(comment=e.comment, author=e.author,
   451                           branch=e.branch, date=e.date, entries=[])
   468                           branch=e.branch, date=e.date, entries=[],
       
   469                           mergepoint=e.mergepoint)
   452             changesets.append(c)
   470             changesets.append(c)
   453             files = {}
   471             files = {}
   454             if len(changesets) % 100 == 0:
   472             if len(changesets) % 100 == 0:
   455                 t = '%d %s' % (len(changesets), repr(e.comment)[1:-1])
   473                 t = '%d %s' % (len(changesets), repr(e.comment)[1:-1])
   456                 ui.status(util.ellipsis(t, 80) + '\n')
   474                 ui.status(util.ellipsis(t, 80) + '\n')
   593                     break
   611                     break
   594 
   612 
   595             if p is not None:
   613             if p is not None:
   596                 c.parents.append(p)
   614                 c.parents.append(p)
   597 
   615 
       
   616         if c.mergepoint:
       
   617             if c.mergepoint == 'HEAD':
       
   618                 c.mergepoint = None
       
   619             c.parents.append(changesets[branches[c.mergepoint]])
       
   620 
   598         if mergefrom:
   621         if mergefrom:
   599             m = mergefrom.search(c.comment)
   622             m = mergefrom.search(c.comment)
   600             if m:
   623             if m:
   601                 m = m.group(1)
   624                 m = m.group(1)
   602                 if m == 'HEAD':
   625                 if m == 'HEAD':