예제 #1
0
CLogChangedPath::CLogChangedPath
    ( const CRevisionInfoContainer::CChangesIterator& iter
    , const CDictionaryBasedTempPath& logPath)
    : path (iter.GetPath())
    , copyFromPath (NULL, (index_t)NO_INDEX)
    , copyFromRev (0)
{
    flags.nodeKind = static_cast<svn_node_kind_t>(iter->GetPathType());
    flags.action = (DWORD)iter.GetAction() / 4;
    flags.textModifies = static_cast<svn_tristate_t>(iter->GetTextModifies());
    flags.propsModifies = static_cast<svn_tristate_t>(iter->GetPropsModifies());

    // check relevance for log path

    flags.relevantForStartPath = logPath.IsSameOrParentOf (path)
                              || logPath.IsSameOrChildOf (path);

    // set copy-from info, if available

    if (iter.HasFromPath() && (iter.GetFromRevision() != NO_REVISION))
    {
        copyFromPath = iter.GetFromPath();
        copyFromRev = iter.GetFromRevision();
    }
}
bool operator< ( const CDictionaryBasedTempPath& lhs
               , const CDictionaryBasedTempPath& rhs)
{
    // both elements should be from the same container
    // (otherwise, some shortcuts may not be justified)

    assert (lhs.GetDictionary() == rhs.GetDictionary());

    // quick compare: indices and counters

    ptrdiff_t diff = lhs.GetBasePath().GetIndex() - rhs.GetBasePath().GetIndex();
    if (diff < 0)
        return true;
    if (diff > 0)
        return false;

    diff = lhs.GetRelPathElements().size() - rhs.GetRelPathElements().size();
    if (diff < 0)
        return true;
    if (diff > 0)
        return false;

    // long and boring comparison

    return lhs.GetRelPathElements() < rhs.GetRelPathElements();
}
bool CDictionaryBasedTempPath::operator==(const CDictionaryBasedTempPath& rhs) const
{
    return (GetBasePath() == rhs.GetBasePath())
        && (relPathElements.size() == rhs.relPathElements.size())
        && (std::equal ( relPathElements.begin()
                       , relPathElements.end()
                       , rhs.relPathElements.begin()));
}
예제 #4
0
CLogIteratorBase::CLogIteratorBase ( const CCachedLogInfo* cachedLog
                                   , revision_t startRevision
                                   , const CDictionaryBasedTempPath& startPath)
    : revisionInfo (cachedLog->GetLogInfo())
    , revisionIndices (cachedLog->GetRevisions())
    , skipRevisionInfo (cachedLog->GetSkippedRevisions())
    , revision (startRevision)
    , addRevision ((revision_t)NO_REVISION)
    , path (startPath)
    , addPath (startPath.GetDictionary())
{
}
예제 #5
0
void CLogChangedPathArray::Add
    ( CRevisionInfoContainer::CChangesIterator& first
    , const CRevisionInfoContainer::CChangesIterator& last
    , CDictionaryBasedTempPath& logPath)
{
    reserve (last - first);
    for (; first != last; ++first)
        emplace_back(first, logPath);

    // update log path to the *last* copy source we found
    // because it will also be the closed one (parent may
    // have copied from somewhere else)

    for (size_t i = size(); i > 0; --i)
    {
        CLogChangedPath& change = at(i-1);

        // relevant for this path and
        // has the log path be renamed?

        if (   change.IsRelevantForStartPath()
            && (change.GetCopyFromRev() > 0)
            && logPath.IsSameOrChildOf (change.GetCachedPath()))
        {
            // note: this only works if the log is fetched top-to-bottom
            // but since we do that, it shouldn't be a problem

            logPath = logPath.ReplaceParent
                         ( change.GetCachedPath()
                         , change.GetCachedCopyFromPath());
            copiedSelf = true;

            return;
        }
    }

    actions = 0;
}
예제 #6
0
bool CLogIteratorBase::PathInRevision
    ( const CRevisionInfoContainer::CChangesIterator& first
    , const CRevisionInfoContainer::CChangesIterator& last
    , const CDictionaryBasedTempPath& path)
{
    // close examination of all changes

    for ( CRevisionInfoContainer::CChangesIterator iter = first
        ; iter != last
        ; ++iter)
    {
        // if (and only if) path is a cached path,
        // it may be a parent of the changedPath
        // (i.e. report a change of this or some sub-path)

        CDictionaryBasedPath changedPath = iter->GetPath();
        if (   path.IsFullyCachedPath()
            && path.GetBasePath().IsSameOrParentOf (changedPath))
            return true;

        // this change affects a true parent path or completely unrelated path
        // -> ignore mere modifications (e.g. properties on a folder)

        if (iter->GetAction() == CRevisionInfoContainer::ACTION_CHANGED)
            continue;

        // this is an add / delete / replace.
        // does it affect our path?

        if (changedPath.IsSameOrParentOf (path.GetBasePath()))
            return true;
    }

    // no paths that we were looking for

    return false;
}
CDictionaryBasedTempPath CDictionaryBasedTempPath::GetCommonRoot
    (const CDictionaryBasedTempPath& rhs) const
{
    // short-cut: different base directories anyway?

    if (rhs.GetIndex() != GetIndex())
        return CDictionaryBasedTempPath (inherited::GetCommonRoot (rhs));

    // match relative paths

    typedef std::vector<std::string>::const_iterator IT;
    IT begin = relPathElements.begin();
    IT end = relPathElements.end();
    IT iter = begin;

    IT rhsEnd = relPathElements.end();
    IT rhsIter = relPathElements.begin();

    while ((iter != end) && (rhsIter != rhsEnd) && (*iter == *rhsIter))
    {
        ++iter;
        ++rhsIter;
    }

    // construct the result

    CDictionaryBasedTempPath result (GetBasePath());
    result.relPathElements.insert (result.relPathElements.begin(), begin, iter);

    // update the debug-only _path member

#ifdef _DEBUG
    result._path = result.GetPath();
#endif

    return result;
}
예제 #8
0
void CFullGraphFinalizer::InitWCRevs()
{
    // collect revisions to show

    std::vector<revision_t> revisions;

    revisions.push_back (history.GetWCInfo().minCommit);
    revisions.push_back (history.GetWCInfo().maxCommit);
    revisions.push_back (history.GetWCInfo().minAtRev);
    revisions.push_back (history.GetWCInfo().maxAtRev);

    std::sort (revisions.begin(), revisions.end());
    revisions.erase ( std::unique_copy ( revisions.begin()
                                       , revisions.end()
                                       , revisions.begin())
                    , revisions.end());

    // assign paths

    CDictionaryBasedTempPath path = *history.GetWCPath();
    revision_t pathRevision = history.GetPegRevision();

    while (   !revisions.empty()
           && (revisions.back() >= pathRevision)
           && path.IsValid())
    {
        wcRevs.insert ( wcRevs.begin()
                      , std::make_pair (revisions.back(), path.GetBasePath()));
        revisions.pop_back();
    }

    while (!revisions.empty())
    {
        revision_t revision = revisions.back();
        revisions.pop_back();

        // efficiently follow path changes only

        const CCachedLogInfo* cache = history.GetCache();
        const CRevisionIndex& revisionIndices = cache->GetRevisions();
        const CRevisionInfoContainer& info = cache->GetLogInfo();

        while (revision < pathRevision)
        {
            index_t index = revisionIndices[pathRevision];
            if (   (index != NO_INDEX)
                && (info.GetSumChanges (index) & CRevisionInfoContainer::HAS_COPY_FROM)
                && (info.GetRootPath (index).IsSameOrParentOf (path.GetBasePath())))
            {
                CCopyFollowingLogIterator iterator (cache, pathRevision, path);
                iterator.Advance();

                pathRevision = iterator.GetRevision();
                path = iterator.GetPath();
            }
            else
            {
                --pathRevision;
            }
        }

        if (path.IsValid())
            wcRevs.insert ( wcRevs.begin()
                          , std::make_pair (revision, path.GetBasePath()));
    }
}