public WalkFetchConnection(IWalkTransport t, WalkRemoteObjectDatabase w)
        {
            var wt = (Transport)t;

            _local    = wt.Local;
            _objCheck = wt.CheckFetchedObjects ? new ObjectChecker() : null;

            _remotes = new List <WalkRemoteObjectDatabase> {
                w
            };

            _unfetchedPacks  = new LinkedList <RemotePack>();
            _packsConsidered = new List <string>();

            _noPacksYet = new LinkedList <WalkRemoteObjectDatabase>();
            _noPacksYet.AddLast(w);

            _noAlternatesYet = new LinkedList <WalkRemoteObjectDatabase>();
            _noAlternatesYet.AddLast(w);

            _fetchErrors = new Dictionary <ObjectId, List <Exception> >();
            _packLocks   = new List <PackLock>(4);

            _revWalk = new RevWalk.RevWalk(_local);
            _revWalk.setRetainBody(false);
            _treeWalk = new TreeWalk.TreeWalk(_local);

            COMPLETE      = _revWalk.newFlag("COMPLETE");
            IN_WORK_QUEUE = _revWalk.newFlag("IN_WORK_QUEUE");
            LOCALLY_SEEN  = _revWalk.newFlag("LOCALLY_SEEN");

            _localCommitQueue = new DateRevQueue();
            _workQueue        = new LinkedList <ObjectId>();
        }
示例#2
0
        ///	<summary>
        /// Recursively add an entire tree into this builder.
        /// <para />
        /// If pathPrefix is "a/b" and the tree contains file "c" then the resulting
        /// DirCacheEntry will have the path "a/b/c".
        /// <para />
        /// All entries are inserted at stage 0, therefore assuming that the
        /// application will not insert any other paths with the same pathPrefix.
        /// </summary>
        /// <param name="pathPrefix">
        /// UTF-8 encoded prefix to mount the tree's entries at. If the
        /// path does not end with '/' one will be automatically inserted
        /// as necessary.
        /// </param>
        /// <param name="stage">Stage of the entries when adding them.</param>
        /// <param name="db">
        /// Repository the tree(s) will be read from during recursive
        /// traversal. This must be the same repository that the resulting
        /// <see cref="DirCache"/> would be written out to (or used in) otherwise
        /// the caller is simply asking for deferred MissingObjectExceptions.
        /// </param>
        /// <param name="tree">
        /// The tree to recursively add. This tree's contents will appear
        /// under <paramref name="pathPrefix"/>. The ObjectId must be that of a
        /// tree; the caller is responsible for dereferencing a tag or
        /// commit (if necessary).
        /// </param>
        /// <exception cref="IOException">
        /// A tree cannot be read to iterate through its entries.
        /// </exception>
        public void addTree(byte[] pathPrefix, int stage, Repository db, AnyObjectId tree)
        {
            var tw = new TreeWalk.TreeWalk(db);

            tw.reset();
            var curs = new WindowCursor();

            try
            {
                tw.addTree(new CanonicalTreeParser(pathPrefix, db, tree.ToObjectId(), curs));
            }
            finally
            {
                curs.Release();
            }
            tw.Recursive = true;

            if (!tw.next())
            {
                return;
            }

            DirCacheEntry newEntry = ToEntry(stage, tw);

            BeforeAdd(newEntry);
            FastAdd(newEntry);
            while (tw.next())
            {
                FastAdd(ToEntry(stage, tw));
            }
        }
示例#3
0
        private static DirCacheEntry ToEntry(int stage, TreeWalk.TreeWalk tw)
        {
            var e        = new DirCacheEntry(tw.getRawPath(), stage);
            var iterator = tw.getTree <AbstractTreeIterator>(0, typeof(AbstractTreeIterator));

            e.setFileMode(tw.getFileMode(0));
            e.setObjectIdFromRaw(iterator.idBuffer(), iterator.idOffset());
            return(e);
        }
示例#4
0
        public override bool include(RevWalk walker, RevCommit c)
        {
            // Reset the tree filter to scan this commit and parents.
            //
            RevCommit[] pList    = c.Parents;
            int         nParents = pList.Length;

            TreeWalk.TreeWalk tw = _pathFilter;
            var trees            = new ObjectId[nParents + 1];

            for (int i = 0; i < nParents; i++)
            {
                RevCommit p = c.Parents[i];
                if ((p.Flags & Parsed) == 0)
                {
                    p.parseHeaders(walker);
                }
                trees[i] = p.Tree;
            }

            trees[nParents] = c.Tree;
            tw.reset(trees);

            if (nParents == 1)
            {
                // We have exactly one parent. This is a very common case.
                //
                int chgs = 0, adds = 0;
                while (tw.next())
                {
                    chgs++;
                    if (tw.getRawMode(0) == 0 && tw.getRawMode(1) != 0)
                    {
                        adds++;
                    }
                    else
                    {
                        break; // no point in looking at this further.
                    }
                }

                if (chgs == 0)
                {
                    // No changes, so our tree is effectively the same as
                    // our parent tree. We pass the buck to our parent.
                    //
                    c.Flags |= Rewrite;
                    return(false);
                }

                // We have interesting items, but neither of the special
                // cases denoted above.
                //
                return(true);
            }

            if (nParents == 0)
            {
                // We have no parents to compare against. Consider us to be
                // Rewrite only if we have no paths matching our filter.
                //
                if (tw.next())
                {
                    return(true);
                }

                c.Flags |= Rewrite;
                return(false);
            }

            // We are a merge commit. We can only be Rewrite if we are same
            // to _all_ parents. We may also be able to eliminate a parent if
            // it does not contribute changes to us. Such a parent may be an
            // uninteresting side branch.
            //
            var chgs_ = new int[nParents];
            var adds_ = new int[nParents];

            while (tw.next())
            {
                int myMode = tw.getRawMode(nParents);
                for (int i = 0; i < nParents; i++)
                {
                    int pMode = tw.getRawMode(i);
                    if (myMode == pMode && tw.idEqual(i, nParents))
                    {
                        continue;
                    }

                    chgs_[i]++;
                    if (pMode == 0 && myMode != 0)
                    {
                        adds_[i]++;
                    }
                }
            }

            bool same = false;
            bool diff = false;

            for (int i = 0; i < nParents; i++)
            {
                if (chgs_[i] == 0)
                {
                    // No changes, so our tree is effectively the same as
                    // this parent tree. We pass the buck to only this one
                    // parent commit.
                    //

                    RevCommit p = pList[i];
                    if ((p.Flags & Uninteresting) != 0)
                    {
                        // This parent was marked as not interesting by the
                        // application. We should look for another parent
                        // that is interesting.
                        //
                        same = true;
                        continue;
                    }

                    c.Flags  |= Rewrite;
                    c.Parents = new[] { p };
                    return(false);
                }

                if (chgs_[i] == adds_[i])
                {
                    // All of the differences from this parent were because we
                    // added files that they did not have. This parent is our
                    // "empty tree root" and thus their history is not relevant.
                    // Cut our grandparents to be an empty list.
                    //
                    pList[i].Parents = RevCommit.NoParents;
                }

                // We have an interesting difference relative to this parent.
                //
                diff = true;
            }

            if (diff && !same)
            {
                // We did not abort above, so we are different in at least one
                // way from all of our parents. We have to take the blame for
                // that difference.
                //
                return(true);
            }

            // We are the same as all of our parents. We must keep them
            // as they are and allow those parents to flow into pending
            // for further scanning.
            //
            c.Flags |= Rewrite;
            return(false);
        }
示例#5
0
 public RewriteTreeFilter(RevWalk walker, TreeFilter t)
 {
     _pathFilter = new TreeWalk.TreeWalk(walker.Repository);
     _pathFilter.setFilter(t);
     _pathFilter.Recursive = t.shouldBeRecursive();
 }
示例#6
0
 /**
  * Recursively add an entire tree into this builder.
  * <p>
  * If pathPrefix is "a/b" and the tree contains file "c" then the resulting
  * DirCacheEntry will have the path "a/b/c".
  * <p>
  * All entries are inserted at stage 0, therefore assuming that the
  * application will not insert any other paths with the same pathPrefix.
  *
  * @param pathPrefix
  *            UTF-8 encoded prefix to mount the tree's entries at. If the
  *            path does not end with '/' one will be automatically inserted
  *            as necessary.
  * @param stage
  *            stage of the entries when adding them.
  * @param db
  *            repository the tree(s) will be read from during recursive
  *            traversal. This must be the same repository that the resulting
  *            DirCache would be written out to (or used in) otherwise the
  *            caller is simply asking for deferred MissingObjectExceptions.
  * @param tree
  *            the tree to recursively add. This tree's contents will appear
  *            under <code>pathPrefix</code>. The ObjectId must be that of a
  *            tree; the caller is responsible for dereferencing a tag or
  *            commit (if necessary).
  * @throws IOException
  *             a tree cannot be read to iterate through its entries.
  */
 public void addTree(byte[] pathPrefix, int stage, Repository db, AnyObjectId tree)
 {
     var tw = new TreeWalk.TreeWalk(db);
     tw.reset();
     var curs = new WindowCursor();
     try
     {
         tw.addTree(new CanonicalTreeParser(pathPrefix, db, tree.ToObjectId(), curs));
     }
     finally
     {
         curs.release();
     }
     tw.setRecursive(true);
     if (tw.next())
     {
         DirCacheEntry newEntry = toEntry(stage, tw);
         beforeAdd(newEntry);
         fastAdd(newEntry);
         while (tw.next())
             fastAdd(toEntry(stage, tw));
     }
 }
        public WalkFetchConnection(IWalkTransport t, WalkRemoteObjectDatabase w)
        {
            _idBuffer = new MutableObjectId();
            _objectDigest = Constants.newMessageDigest();

            var wt = (Transport)t;
            _local = wt.Local;
            _objCheck = wt.CheckFetchedObjects ? new ObjectChecker() : null;

            _remotes = new List<WalkRemoteObjectDatabase> { w };

            _unfetchedPacks = new LinkedList<RemotePack>();
            _packsConsidered = new List<string>();

            _noPacksYet = new LinkedList<WalkRemoteObjectDatabase>();
            _noPacksYet.AddFirst(w);

            _noAlternatesYet = new LinkedList<WalkRemoteObjectDatabase>();
            _noAlternatesYet.AddFirst(w);

            _fetchErrors = new Dictionary<ObjectId, List<Exception>>();
            _packLocks = new List<PackLock>(4);

            _revWalk = new RevWalk.RevWalk(_local);
            _treeWalk = new TreeWalk.TreeWalk(_local);

            COMPLETE = _revWalk.newFlag("COMPLETE");
            IN_WORK_QUEUE = _revWalk.newFlag("IN_WORK_QUEUE");
            LOCALLY_SEEN = _revWalk.newFlag("LOCALLY_SEEN");

            _localCommitQueue = new DateRevQueue();
            _workQueue = new LinkedList<ObjectId>();
        }
示例#8
0
 public RewriteTreeFilter(RevWalk walker, TreeFilter t)
 {
     _pathFilter = new TreeWalk.TreeWalk(walker.Repository);
     _pathFilter.setFilter(t);
     _pathFilter.Recursive = t.shouldBeRecursive();
 }
示例#9
0
 public RewriteTreeFilter(RevWalk walker, TreeFilter t)
 {
     pathFilter = new TreeWalk.TreeWalk(walker.db);
     pathFilter.setFilter(t);
     pathFilter.setRecursive(t.shouldBeRecursive());
 }