예제 #1
0
    query_merges(VersionControlServer vcs,
                 string srcPath, VersionSpec srcVer,
                 string targetPath, VersionSpec targetVer,
                 VersionSpec fromVer, VersionSpec toVer,
                 RecursionType recurType)
    {
        RBDictTree <int, SortedDictionary <int, ChangesetMerge> > merges =
            new RBDictTree <int, SortedDictionary <int, ChangesetMerge> >();

        ++_queries;
        logger.DebugFormat("query_merges {0}, {1}, {2}, {3}, {4}, {5}",
                           (srcPath == null ? "(null)": srcPath),
                           (srcVer == null ? "(null)" : srcVer.DisplayString),
                           targetPath, targetVer.DisplayString,
                           (fromVer == null ? "(null)" : fromVer.DisplayString),
                           (toVer == null ? "(null)" : toVer.DisplayString));

        _queryTimer.start();
        try
        {
            ChangesetMerge[] mergesrc = vcs.QueryMerges(srcPath, srcVer, targetPath, targetVer,
                                                        fromVer, toVer, recurType);
            /* group by merged changesets. */
            for (int i = 0; i < mergesrc.Length; ++i)
            {
                RBDictTree <int, SortedDictionary <int, ChangesetMerge> > .iterator it =
                    merges.find(mergesrc[i].TargetVersion);

                if (merges.end() == it)
                {
                    /* create the list... */
                    SortedDictionary <int, ChangesetMerge> group = new SortedDictionary <int, ChangesetMerge>();
                    group.Add(mergesrc[i].SourceVersion, mergesrc[i]);
                    merges.insert(mergesrc[i].TargetVersion, group);
                }
                else
                {
                    it.value().second.Add(mergesrc[i].SourceVersion, mergesrc[i]);
                }
            }
        }
        catch (Exception e)
        {
            Console.Error.WriteLine("Error querying: {0},{1}", targetPath, targetVer);
            Console.Error.WriteLine(e.ToString());
        }
        _queryTimer.stop();

        return(merges);
    }
예제 #2
0
    /** visit an explicit list of changesets.
     */
    private bool _visit(int parentID,
                        List <string> targetBranches,
                        string srcPath, VersionSpec srcVer,
                        string target, VersionSpec targetVer,
                        VersionSpec fromVer, VersionSpec toVer,
                        RecursionType recursionType)
    {
        logger.DebugFormat("{{_visit: parent={0}", parentID);

        /* so, here we might have a few top-level merge changesets.
         * the red-black binary tree sorts the changesets in decending order
         */
        RBDictTree <int, SortedDictionary <int, ChangesetMerge> > merges =
            query_merges(_vcs, srcPath, srcVer, target, targetVer, fromVer, toVer, recursionType);

        RBDictTree <int, SortedDictionary <int, ChangesetMerge> > .iterator it = merges.begin();

        /* walk through the merge changesets
         * - this should return only one merge changeset for the recursive calls.
         */
        for (; it != merges.end(); ++it)
        {
            int csID = it.value().first;
            try
            {
                /* visit the 'target' merge changeset here.
                 * it's parent is the one passed in.
                 */
                Changeset            cs          = _vcs.GetChangeset(csID);
                string               path_part   = _get_path_part(target);
                ChangesetVersionSpec cstargetVer = targetVer as ChangesetVersionSpec;

                /* pass in the known set of branches in this changeset, or let it figure that out. */
                if (cstargetVer.ChangesetId == csID)
                {
                    _visitor.visit(parentID, cs, targetBranches);
                }
                else
                {
                    _visitor.visit(parentID, cs);
                }

                {
                    Visitor.PatchInfo p = _visitor[csID];

                    /* if the user chose to heed our warnings,
                     *   and there are no branches to visit for this changeset?
                     *   move on to the next result, ignoring all the 'composites' of this 'fake' changeset.
                     */
                    if (!_options.ForceDecomposition &&
                        (p != null && (p.treeBranches == null || p.treeBranches.Count == 0)))
                    {
                        continue;
                    }
                }

                foreach (KeyValuePair <int, ChangesetMerge> cng in it.value().second)
                {
                    ChangesetMerge csm = cng.Value;

                    /* now visit each of the children.
                     * we've already expanded cs.ChangesetId (hopefully...)
                     */
                    try
                    {
                        Changeset     child    = _vcs.GetChangeset(csm.SourceVersion);
                        List <string> branches = null;

                        {
                            /* speed-up. if we already have the branches, don't do it again.
                             * looking through 40K+ records takes some time...
                             */
                            Visitor.PatchInfo p = _visitor[child.ChangesetId];
                            if (p != null)
                            {
                                branches = p.treeBranches;
                            }
                            else
                            {
                                branches = FindChangesetBranches(child);
                            }
                        }

                        /* - this is for the recursive query -
                         * you have to have specific branches here.
                         * a query of the entire project will probably not return.
                         *
                         * eg:
                         * query target $/IGT_0803/main/EGS,78029 = 41s
                         * query target $/IGT_0803,78029 = DNF (waited 6+m)
                         */

                        if (_options.NoRecurse)
                        {
                            /* they just want the top-level query. */
                            _visitor.visit(cs.ChangesetId, child, branches);
                        }
                        else
                        {
                            if (!_visitor.visited(child.ChangesetId))
                            {
                                /* we just wanted to see the initial list, not a full tree of changes. */
                                ChangesetVersionSpec tv = new ChangesetVersionSpec(child.ChangesetId);
                                bool results            = false;

                                /* this is going to execute a number of queries to get
                                 * all of the source changesets for this merge.
                                 * since using a branch is an(several hundred) order(s) of magnitude faster,
                                 * we're doing this by branch(path)
                                 */
                                for (int i = 0; i < branches.Count; ++i)
                                {
                                    if (_options.AllowBranchRevisiting || !_visitor.visited(branches[i]))
                                    {
                                        logger.DebugFormat("visiting ({0}) {1}{2}",
                                                           child.ChangesetId, branches[i], path_part);

                                        /* this recurisve call needs to then
                                         * handle visiting the results of this query.
                                         */
                                        bool branchResult = _visit(cs.ChangesetId, branches,
                                                                   null, null,
                                                                   branches[i] + path_part, tv,
                                                                   tv, tv, RecursionType.Full);

                                        if (branchResult)
                                        {
                                            results = true;
                                        }
                                    }
                                }

                                if (!results)
                                {
                                    /* we got no results from our query, so display the changeset
                                     * (it won't be displayed otherwise)
                                     */
                                    _visitor.visit(cs.ChangesetId, child, branches);                                                                                             //, branches);
                                }
                            }
                            else
                            {
                                /* do we want to see it again? */
                                _visitor.visit(cs.ChangesetId, child, branches);                                                                                //, branches);
                            }
                        }
                    }
                    catch (Exception e) { _visitor.visit(cs.ChangesetId, csm.SourceVersion, e); }
                }
            }
            catch (Exception e) { _visitor.visit(parentID, csID, e); }
        }

        logger.DebugFormat("}}_visit:{0}", parentID);

        return(false == merges.empty());
    }