Exemple #1
0
    def last_change_num_for_branches(ctx, branch_ids, must_exist_local=False):
        """Return highest changelist number for all branches which exists in p4.

        Searches //P4GF_DEPOT/objects/... for commits and returns ObjectType
        for commit with highest change_num, or None if no matching commit.

        If must_exist_local is True, only commits which also exist in the
        repo are considered in the search.
        """
        # pylint: disable=too-many-branches
        # if only one branch_id given, don't fetch them all
        if len(branch_ids) == 1:
            branch_id = branch_ids[0]
            if branch_id not in ObjectType.last_commits_cache:
                        # Using get_all() instead of get() to avoid annoying
                        # default value "0" for unset keys.
                key = p4gf_const.P4GF_P4KEY_INDEX_LCN_ON_BRANCH\
                      .format( repo_name = ctx.config.repo_name
                             , branch_id = branch_id)
                d = P4Key.get_all(ctx.p4gf, key)
                if d and d.get(key):
                    ObjectType.last_commits_cache[branch_id] = d[key]
            if branch_id not in ObjectType.last_commits_cache:
                return None
            change_num, sha1 = ObjectType.last_commits_cache[branch_id].split(',')
            if must_exist_local and not p4gf_util.sha1_exists(sha1):
                return None
            return ObjectType.create_commit( sha1       = sha1
                                           , repo_name  = ctx.config.repo_name
                                           , change_num = int(change_num)
                                           , branch_id  = branch_id )

        # if more than one branch, load up all branches into the cache
        ObjectType._load_last_commits_cache(ctx)
        highest = {}
        k = None
        for branch_id, v in ObjectType.last_commits_cache.items():
            if branch_id not in branch_ids:
                continue
            change_num, sha1 = v.split(',')
            if branch_id in highest:
                if int(change_num) > highest[branch_id][0]:
                    if must_exist_local and not p4gf_util.sha1_exists(sha1):
                        continue
                    highest[branch_id] = (int(change_num), sha1)
            elif not branch_ids or branch_id in branch_ids:
                if must_exist_local and not p4gf_util.sha1_exists(sha1):
                    continue
                highest[branch_id] = (int(change_num), sha1)
            else:
                continue
            if not k or int(change_num) > highest[k][0]:
                k = branch_id
        if not k:
            return None
        return ObjectType.create_commit( sha1       = highest[k][1]
                                       , repo_name  = ctx.config.repo_name
                                       , change_num = highest[k][0]
                                       , branch_id  = k )
Exemple #2
0
    def last_change_for_branches(ctx, branch_ids, must_exist_local=False):
        '''
        Returns highest numbered change for all branches which exists in p4.

        Searches //P4GF_DEPOT/objects/... for commits and returns ObjectType
        for commit with highest change_number, or None if no matching commit.

        If must_exist_local is True, only commits which also exist in the
        repo are considered in the search.
        '''
        # if only one branch_id given, don't fetch them all
        if len(branch_ids) == 1:
            branch_id = branch_ids[0]
            if not branch_id in ObjectType.last_commits_cache:
                key = "git-fusion-index-last-{repo},{branch_id}".format(
                    repo=ctx.config.view_name, branch_id=branch_id)
                r = p4gf_util.p4run_logged(ctx.p4gf,
                                           ['counters', '-u', '-e', key])
                if r:
                    ObjectType.last_commits_cache[branch_id] = r[0]['value']
            if not branch_id in ObjectType.last_commits_cache:
                return None
            change, sha1 = ObjectType.last_commits_cache[branch_id].split(',')
            if must_exist_local and not p4gf_util.sha1_exists(sha1):
                return None
            return ObjectType.create_commit(sha1, ctx.config.view_name,
                                            int(change), branch_id)

        # if more than one branch, load up all branches into the cache
        ObjectType._load_last_commits_cache(ctx)
        highest = {}
        k = None
        for branch_id, v in ObjectType.last_commits_cache.items():
            if not branch_id in branch_ids:
                continue
            change, sha1 = v.split(',')
            if branch_id in highest:
                if int(change) > highest[branch_id][0]:
                    if must_exist_local and not p4gf_util.sha1_exists(sha1):
                        continue
                    highest[branch_id] = (int(change), sha1)
            elif not branch_ids or branch_id in branch_ids:
                if must_exist_local and not p4gf_util.sha1_exists(sha1):
                    continue
                highest[branch_id] = (int(change), sha1)
            else:
                continue
            if not k or int(change) > highest[k][0]:
                k = branch_id
        if not k:
            return None
        return ObjectType.create_commit(highest[k][1], ctx.config.view_name,
                                        highest[k][0], k)
 def _add_parent_changes(self):
     """If desc_info has parent-changes, add those to parent_commit_list.
     Return True if any parent added to self.parent_commit_list,
     False if nothing added.
     """
     if self.desc_info and self.desc_info.parent_changes:
         # orphan git commits with no parents
         if 'None' in self.desc_info.parent_changes:
             self.parent_commit_list = []
             self.is_git_orphan = True
             return True
         add_list = []
         for sha1 in self.desc_info.parents:
             changes = self.desc_info.parent_changes.get(sha1, None)
             if changes is None:
                 LOG.error(
                     'DescInfo missing parent changes for {}'.format(sha1))
                 return False
             for cl in changes:
                 ml = self.p2g.mark_list.cl_to_mark_list(str(cl))
                 if ml:
                     add_list.append(ml[0])
                     LOG.debug3(
                         '_add_parent_changes() @{} using mark {}'.format(
                             cl, ml[0]))
                     break
                 commit = ObjectType.change_num_to_commit(self.ctx, cl)
                 if commit and p4gf_util.sha1_exists(commit.sha1):
                     add_list.append(commit.sha1)
                     LOG.debug3(
                         '_add_parent_changes() @{} using SHA1 {}'.format(
                             cl, commit.sha1))
                     break
             else:
                 # Fell off the end of the "for cl" list without finding the
                 # parent in our repo.
                 #
                 # DescInfo lists a parent commit sha1/change_num that does
                 # not intersect this repo. This is okay: just means the
                 # changelist came from some other repo that can see some
                 # depot paths that this current repo cannot.
                 LOG.debug3('_add_parent_changes() skipping, could not find'
                            ' parent SHA1 {} cl {}'.format(sha1, changes))
                 self.omitted_di_parents = True
         if add_list:
             self.parent_commit_list.extend(add_list)
             return True
     return False
    def _can_use_as_parent(self, sha1):
        """If sha1 already copied to Git, return sha1.

        If sha1 not yet copied, but its corresponding Perforce changelist is in
        our MarkList of impending copies, return the mark for that changelist.

        If not, return None
        """
        # Already stored in Git from some previous push or pull?
        if p4gf_util.sha1_exists(sha1):
            return sha1

        # Any of this commit's corresponding changelists
        # about to be copied to Git in this pull?
        for commit in ObjectType.commits_for_sha1(self.ctx, sha1):
            ml = self.p2g.mark_list.cl_to_mark_list(commit.change_num)
            if ml:
                return ml[0]

        return None
    def _can_use_as_parent(self, sha1):
        '''
        If sha1 already copied to Git, return sha1.

        If sha1 not yet copied, but its corresponding Perforce changelist is in
        our MarkList of impending copies, return the mark for that changelist.

        If not, return None
        '''
        # Already stored in Git from some previous push or pull?
        if p4gf_util.sha1_exists(sha1):
            return sha1

        # Any of this commit's corresponding changelists
        # about to be copied to Git in this pull?
        for commit in ObjectType.commits_for_sha1(self.ctx, sha1):
            ml = self.p2g.mark_list.cl_to_mark_list(commit.details.changelist)
            if ml:
                return ml[0]

        return None
    def _calc_merge_parent_list(self):
        '''
        Return a list of marks/sha1s to use as parents for a Git merge commit.

        Returns a 2-tuple of ( [mark/commit parent], [parent branch id] ).
        '''
        parent_commit_id = []
        parent_branch_id = []
        for branch_id, cl in self.branch_id_to_changelist_num.items():
            # Changelists from before the start of history cannot be
            # parents. No merging from beyond the event horizon.
            if cl < self.p2g.rev_range.begin_change_num:
                continue

            # Each Perforce commit maps to zero or more Git commits, one per
            # branch that intersects the integ source files from that commit.

            # Do we have any pending commits for this changelist?
            ml = self.p2g.mark_list.cl_to_mark_list(str(cl))
            for mark in ml:
                ### Must only include mark if mark associated with branch.
                ### Must only include one mark here.
                ### But that requires adding more branch/mark tracking than we
                ### want to add until I have a test that proves we need it.
                if not mark in parent_commit_id:
                    parent_commit_id.append(mark)
                    parent_branch_id.append(branch_id)

            # Do we have any existing commits for this changelist?
            commit = ObjectType.commit_for_change(self.ctx, cl)

            # Does this Git commit occur in our Git repo at this
            # changelist number?
            if (commit and
                (not commit.sha1 in parent_commit_id) and
                p4gf_util.sha1_exists(commit.sha1) ):
                parent_commit_id.append(commit.sha1)
                parent_branch_id.append(branch_id)

        return (parent_commit_id, parent_branch_id)
Exemple #7
0
    def _calc_merge_parent_list(self):
        '''
        Return a list of marks/sha1s to use as parents for a Git merge commit.

        Returns a 2-tuple of ( [mark/commit parent], [parent branch id] ).
        '''
        parent_commit_id = []
        parent_branch_id = []
        for branch_id, cl in self.branch_id_to_changelist_num.items():
            # Changelists from before the start of history cannot be
            # parents. No merging from beyond the event horizon.
            if cl < self.p2g.rev_range.begin_change_num:
                continue

            # Each Perforce commit maps to zero or more Git commits, one per
            # branch that intersects the integ source files from that commit.

            # Do we have any pending commits for this changelist?
            ml = self.p2g.mark_list.cl_to_mark_list(str(cl))
            for mark in ml:
                ### Must only include mark if mark associated with branch.
                ### Must only include one mark here.
                ### But that requires adding more branch/mark tracking than we
                ### want to add until I have a test that proves we need it.
                if not mark in parent_commit_id:
                    parent_commit_id.append(mark)
                    parent_branch_id.append(branch_id)

            # Do we have any existing commits for this changelist?
            commit = ObjectType.commit_for_change(self.ctx, cl)

            # Does this Git commit occur in our Git repo at this
            # changelist number?
            if (commit and (not commit.sha1 in parent_commit_id)
                    and p4gf_util.sha1_exists(commit.sha1)):
                parent_commit_id.append(commit.sha1)
                parent_branch_id.append(branch_id)

        return (parent_commit_id, parent_branch_id)