Exemple #1
0
def is_same_line_of_development(rev1, rev2):
  """Return True if rev1 and rev2 are on the same line of
  development (i.e., both on trunk, or both on the same branch);
  return False otherwise.  Either rev1 or rev2 can be None, in
  which case automatically return False."""

  if rev1 is None or rev2 is None:
    return False
  if is_trunk_revision(rev1) and is_trunk_revision(rev2):
    # Trunk revisions have to be handled specially because the main
    # trunk version number can be changed; e.g., from 1 to 2.
    return True
  if rev1[0:rev1.rfind('.')] == rev2[0:rev2.rfind('.')]:
    return True
  return False
Exemple #2
0
def is_same_line_of_development(rev1, rev2):
    """Return True if rev1 and rev2 are on the same line of
  development (i.e., both on trunk, or both on the same branch);
  return False otherwise.  Either rev1 or rev2 can be None, in
  which case automatically return False."""

    if rev1 is None or rev2 is None:
        return False
    if is_trunk_revision(rev1) and is_trunk_revision(rev2):
        # Trunk revisions have to be handled specially because the main
        # trunk version number can be changed; e.g., from 1 to 2.
        return True
    if rev1[0:rev1.rfind('.')] == rev2[0:rev2.rfind('.')]:
        return True
    return False
Exemple #3
0
    def set_revision_info(self, revision, log, text):
        if revision in self.revisions_seen:
            # One common form of CVS repository corruption is that the
            # Deltatext block for revision 1.1 appears twice.  CollectData
            # has already warned about this problem; here we can just ignore
            # it.
            return
        else:
            self.revisions_seen.add(revision)

        cvs_rev_id = self.cvs_file_items.original_ids[revision]
        if is_trunk_revision(revision):
            # On trunk, revisions are encountered in reverse order (1.<N>
            # ... 1.1) and deltas are inverted.  The first text that we see
            # is the fulltext for the HEAD revision.  After that, the text
            # corresponding to revision 1.N is the delta (1.<N+1> ->
            # 1.<N>)).  We have to invert the deltas here so that we can
            # read the revisions out in dependency order; that is, for
            # revision 1.1 we want the fulltext, and for revision 1.<N> we
            # want the delta (1.<N-1> -> 1.<N>).  This means that we can't
            # compute the delta for a revision until we see its logical
            # parent.  When we finally see revision 1.1 (which is recognized
            # because it doesn't have a parent), we can record the diff (1.1
            # -> 1.2) for revision 1.2, and also the fulltext for 1.1.

            if revision == self.head_revision:
                # This is HEAD, as fulltext.  Initialize the RCSStream so
                # that we can compute deltas backwards in time.
                self._rcs_stream = RCSStream(text)
                self._rcs_stream_revision = revision
            else:
                # Any other trunk revision is a backward delta.  Apply the
                # delta to the RCSStream to mutate it to the contents of this
                # revision, and also to get the reverse delta, which we store
                # as the forward delta of our child revision.
                try:
                    text = self._rcs_stream.invert_diff(text)
                except MalformedDeltaException, e:
                    logger.error(
                        'Malformed RCS delta in %s, revision %s: %s' %
                        (self.cvs_file_items.cvs_file.rcs_path, revision, e))
                    raise RuntimeError()
                text_record = DeltaTextRecord(
                    self.cvs_file_items.original_ids[
                        self._rcs_stream_revision], cvs_rev_id)
                self.revision_collector._writeout(text_record, text)
                self._rcs_stream_revision = revision

            if revision == self.revision_1_1:
                # This is revision 1.1.  Write its fulltext:
                text_record = FullTextRecord(cvs_rev_id)
                self.revision_collector._writeout(text_record,
                                                  self._rcs_stream.get_text())

                # There will be no more trunk revisions delivered, so free the
                # RCSStream.
                del self._rcs_stream
                del self._rcs_stream_revision
Exemple #4
0
    def define_revision(self, revision, timestamp, author, state, branches,
                        next):
        """This is a callback method declared in Sink."""

        for branch in branches:
            try:
                branch_data = self.sdc.rev_to_branch_data(branch)
            except KeyError:
                # Normally we learn about the branches from the branch names
                # and numbers parsed from the symbolic name header.  But this
                # must have been an unlabeled branch that slipped through the
                # net.  Generate a name for it and create a _BranchData record
                # for it now.
                branch_data = self.sdc._add_unlabeled_branch(
                    self.sdc.rev_to_branch_number(branch))

            assert branch_data.child is None
            branch_data.child = branch

        if revision in self._rev_data:
            # This revision has already been seen.
            logger.error(
                'File %r contains duplicate definitions of revision %s.' % (
                    self.cvs_file.rcs_path,
                    revision,
                ))
            raise RuntimeError()

        # Record basic information about the revision:
        rev_data = _RevisionData(self.collect_data.item_key_generator.gen_id(),
                                 revision, int(timestamp), author, state)
        self._rev_data[revision] = rev_data

        # When on trunk, the RCS 'next' revision number points to what
        # humans might consider to be the 'previous' revision number.  For
        # example, 1.3's RCS 'next' is 1.2.
        #
        # However, on a branch, the RCS 'next' revision number really does
        # point to what humans would consider to be the 'next' revision
        # number.  For example, 1.1.2.1's RCS 'next' would be 1.1.2.2.
        #
        # In other words, in RCS, 'next' always means "where to find the next
        # deltatext that you need this revision to retrieve.
        #
        # That said, we don't *want* RCS's behavior here, so we determine
        # whether we're on trunk or a branch and set the dependencies
        # accordingly.
        if next:
            if is_trunk_revision(revision):
                self._primary_dependencies.append((
                    next,
                    revision,
                ))
            else:
                self._primary_dependencies.append((
                    revision,
                    next,
                ))
Exemple #5
0
    def define_revision(self, revision, timestamp, author, state, branches,
                        next):
        if next:
            self.base_revisions[next] = revision
        else:
            if is_trunk_revision(revision):
                self.revision_1_1 = revision

        for branch in branches:
            self.base_revisions[branch] = revision
Exemple #6
0
  def rev_to_lod(self, revision):
    """Return the line of development on which REVISION lies.

    REVISION must be a revision number with an even number of
    components.  Raise KeyError iff REVISION is unknown."""

    if is_trunk_revision(revision):
      return self.pdc.trunk
    else:
      return self.rev_to_branch_data(revision).symbol
Exemple #7
0
  def rev_to_branch_data(self, revision):
    """Return the branch_data of the branch on which REVISION lies.

    REVISION must be a branch revision number with an even number of
    components; for example '1.7.2.1' (never '1.7.2' nor '1.7.0.2').
    Raise KeyError iff REVISION is unknown."""

    assert not is_trunk_revision(revision)

    return self.branches_data[self.rev_to_branch_number(revision)]
Exemple #8
0
    def rev_to_lod(self, revision):
        """Return the line of development on which REVISION lies.

    REVISION must be a revision number with an even number of
    components.  Raise KeyError iff REVISION is unknown."""

        if is_trunk_revision(revision):
            return self.pdc.trunk
        else:
            return self.rev_to_branch_data(revision).symbol
Exemple #9
0
    def rev_to_branch_data(self, revision):
        """Return the branch_data of the branch on which REVISION lies.

    REVISION must be a branch revision number with an even number of
    components; for example '1.7.2.1' (never '1.7.2' nor '1.7.0.2').
    Raise KeyError iff REVISION is unknown."""

        assert not is_trunk_revision(revision)

        return self.branches_data[self.rev_to_branch_number(revision)]
Exemple #10
0
  def rev_to_branch_number(revision):
    """Return the branch_number of the branch on which REVISION lies.

    REVISION is a branch revision number with an even number of
    components; for example '1.7.2.1' (never '1.7.2' nor '1.7.0.2').
    The return value is the branch number (for example, '1.7.2').
    Return none iff REVISION is a trunk revision such as '1.2'."""

    if is_trunk_revision(revision):
      return None
    return revision[:revision.rindex(".")]
Exemple #11
0
    def rev_to_branch_number(revision):
        """Return the branch_number of the branch on which REVISION lies.

    REVISION is a branch revision number with an even number of
    components; for example '1.7.2.1' (never '1.7.2' nor '1.7.0.2').
    The return value is the branch number (for example, '1.7.2').
    Return none iff REVISION is a trunk revision such as '1.2'."""

        if is_trunk_revision(revision):
            return None
        return revision[:revision.rindex(".")]
  def define_revision(
        self, revision, timestamp, author, state, branches, next
        ):
    if next:
      self.base_revisions[next] = revision
    else:
      if is_trunk_revision(revision):
        self.revision_1_1 = revision

    for branch in branches:
      self.base_revisions[branch] = revision
Exemple #13
0
  def define_revision(self, revision, timestamp, author, state,
                      branches, next):
    """This is a callback method declared in Sink."""

    for branch in branches:
      try:
        branch_data = self.sdc.rev_to_branch_data(branch)
      except KeyError:
        # Normally we learn about the branches from the branch names
        # and numbers parsed from the symbolic name header.  But this
        # must have been an unlabeled branch that slipped through the
        # net.  Generate a name for it and create a _BranchData record
        # for it now.
        branch_data = self.sdc._add_unlabeled_branch(
            self.sdc.rev_to_branch_number(branch))

      assert branch_data.child is None
      branch_data.child = branch

    if revision in self._rev_data:
      # This revision has already been seen.
      logger.error('File %r contains duplicate definitions of revision %s.'
                  % (self.cvs_file.rcs_path, revision,))
      raise RuntimeError()

    # Record basic information about the revision:
    rev_data = _RevisionData(
        self.collect_data.item_key_generator.gen_id(),
        revision, int(timestamp), author, state)
    self._rev_data[revision] = rev_data

    # When on trunk, the RCS 'next' revision number points to what
    # humans might consider to be the 'previous' revision number.  For
    # example, 1.3's RCS 'next' is 1.2.
    #
    # However, on a branch, the RCS 'next' revision number really does
    # point to what humans would consider to be the 'next' revision
    # number.  For example, 1.1.2.1's RCS 'next' would be 1.1.2.2.
    #
    # In other words, in RCS, 'next' always means "where to find the next
    # deltatext that you need this revision to retrieve.
    #
    # That said, we don't *want* RCS's behavior here, so we determine
    # whether we're on trunk or a branch and set the dependencies
    # accordingly.
    if next:
      if is_trunk_revision(revision):
        self._primary_dependencies.append( (next, revision,) )
      else:
        self._primary_dependencies.append( (revision, next,) )
Exemple #14
0
  def set_revision_info(self, revision, log, text):
    """This is a callback method declared in Sink."""

    rev_data = self._rev_data[revision]
    cvs_rev = self._cvs_file_items[rev_data.cvs_rev_id]

    if cvs_rev.metadata_id is not None:
      # Users have reported problems with repositories in which the
      # deltatext block for revision 1.1 appears twice.  It is not
      # known whether this results from a CVS/RCS bug, or from botched
      # hand-editing of the repository.  In any case, empirically, cvs
      # and rcs both use the first version when checking out data, so
      # that's what we will do.  (For the record: "cvs log" fails on
      # such a file; "rlog" prints the log message from the first
      # block and ignores the second one.)
      logger.warn(
          "%s: in '%s':\n"
          "   Deltatext block for revision %s appeared twice;\n"
          "   ignoring the second occurrence.\n"
          % (warning_prefix, self.cvs_file.rcs_path, revision,)
          )
      return

    if is_trunk_revision(revision):
      branch_name = None
    else:
      branch_name = self.sdc.rev_to_branch_data(revision).symbol.name

    cvs_rev.metadata_id = self.collect_data.metadata_logger.store(
        self.project, branch_name, rev_data.author, log
        )
    cvs_rev.deltatext_exists = bool(text)

    # If this is revision 1.1, determine whether the file appears to
    # have been created via 'cvs add' instead of 'cvs import'.  The
    # test is that the log message CVS uses for 1.1 in imports is
    # "Initial revision\n" with no period.  (This fact helps determine
    # whether this file might have had a default branch in the past.)
    if revision == '1.1':
      self._file_imported = (log == 'Initial revision\n')
Exemple #15
0
    def set_revision_info(self, revision, log, text):
        """This is a callback method declared in Sink."""

        rev_data = self._rev_data[revision]
        cvs_rev = self._cvs_file_items[rev_data.cvs_rev_id]

        if cvs_rev.metadata_id is not None:
            # Users have reported problems with repositories in which the
            # deltatext block for revision 1.1 appears twice.  It is not
            # known whether this results from a CVS/RCS bug, or from botched
            # hand-editing of the repository.  In any case, empirically, cvs
            # and rcs both use the first version when checking out data, so
            # that's what we will do.  (For the record: "cvs log" fails on
            # such a file; "rlog" prints the log message from the first
            # block and ignores the second one.)
            logger.warn("%s: in '%s':\n"
                        "   Deltatext block for revision %s appeared twice;\n"
                        "   ignoring the second occurrence.\n" % (
                            warning_prefix,
                            self.cvs_file.rcs_path,
                            revision,
                        ))
            return

        if is_trunk_revision(revision):
            branch_name = None
        else:
            branch_name = self.sdc.rev_to_branch_data(revision).symbol.name

        cvs_rev.metadata_id = self.collect_data.metadata_logger.store(
            self.project, branch_name, rev_data.author, log)
        cvs_rev.deltatext_exists = bool(text)

        # If this is revision 1.1, determine whether the file appears to
        # have been created via 'cvs add' instead of 'cvs import'.  The
        # test is that the log message CVS uses for 1.1 in imports is
        # "Initial revision\n" with no period.  (This fact helps determine
        # whether this file might have had a default branch in the past.)
        if revision == '1.1':
            self._file_imported = (log == 'Initial revision\n')
  def set_revision_info(self, revision, log, text):
    if revision in self.revisions_seen:
      # One common form of CVS repository corruption is that the
      # Deltatext block for revision 1.1 appears twice.  CollectData
      # has already warned about this problem; here we can just ignore
      # it.
      return
    else:
      self.revisions_seen.add(revision)

    cvs_rev_id = self.cvs_file_items.original_ids[revision]
    if is_trunk_revision(revision):
      # On trunk, revisions are encountered in reverse order (1.<N>
      # ... 1.1) and deltas are inverted.  The first text that we see
      # is the fulltext for the HEAD revision.  After that, the text
      # corresponding to revision 1.N is the delta (1.<N+1> ->
      # 1.<N>)).  We have to invert the deltas here so that we can
      # read the revisions out in dependency order; that is, for
      # revision 1.1 we want the fulltext, and for revision 1.<N> we
      # want the delta (1.<N-1> -> 1.<N>).  This means that we can't
      # compute the delta for a revision until we see its logical
      # parent.  When we finally see revision 1.1 (which is recognized
      # because it doesn't have a parent), we can record the diff (1.1
      # -> 1.2) for revision 1.2, and also the fulltext for 1.1.

      if revision == self.head_revision:
        # This is HEAD, as fulltext.  Initialize the RCSStream so
        # that we can compute deltas backwards in time.
        self._rcs_stream = RCSStream(text)
        self._rcs_stream_revision = revision
      else:
        # Any other trunk revision is a backward delta.  Apply the
        # delta to the RCSStream to mutate it to the contents of this
        # revision, and also to get the reverse delta, which we store
        # as the forward delta of our child revision.
        try:
          text = self._rcs_stream.invert_diff(text)
        except MalformedDeltaException, e:
          logger.error(
              'Malformed RCS delta in %s, revision %s: %s'
              % (self.cvs_file_items.cvs_file.rcs_path, revision, e)
              )
          raise RuntimeError()
        text_record = DeltaTextRecord(
            self.cvs_file_items.original_ids[self._rcs_stream_revision],
            cvs_rev_id
            )
        self.revision_collector._writeout(text_record, text)
        self._rcs_stream_revision = revision

      if revision == self.revision_1_1:
        # This is revision 1.1.  Write its fulltext:
        text_record = FullTextRecord(cvs_rev_id)
        self.revision_collector._writeout(
            text_record, self._rcs_stream.get_text()
            )

        # There will be no more trunk revisions delivered, so free the
        # RCSStream.
        del self._rcs_stream
        del self._rcs_stream_revision