예제 #1
0
 /// <summary>Enable or disable rename detection.</summary>
 /// <remarks>
 /// Enable or disable rename detection.
 /// Before enabling rename detection the repository must be set with
 /// <see cref="SetRepository(NGit.Repository)">SetRepository(NGit.Repository)</see>
 /// . Once enabled the detector can be
 /// configured away from its defaults by obtaining the instance directly from
 /// <see cref="GetRenameDetector()">GetRenameDetector()</see>
 /// and invoking configuration.
 /// </remarks>
 /// <param name="on">if rename detection should be enabled.</param>
 public virtual void SetDetectRenames(bool on)
 {
     if (on && renameDetector == null)
     {
         AssertHaveRepository();
         renameDetector = new RenameDetector(db);
     }
     else
     {
         if (!on)
         {
             renameDetector = null;
         }
     }
 }
예제 #2
0
파일: DiffEntry.cs 프로젝트: shoff/ngit
        // reduce the visibility of the default constructor
        /// <summary>Convert the TreeWalk into DiffEntry headers.</summary>
        /// <remarks>Convert the TreeWalk into DiffEntry headers.</remarks>
        /// <param name="walk">the TreeWalk to walk through. Must have exactly two trees.</param>
        /// <returns>headers describing the changed files.</returns>
        /// <exception cref="System.IO.IOException">the repository cannot be accessed.</exception>
        public static IList <NGit.Diff.DiffEntry> Scan(TreeWalk walk)
        {
            IList <NGit.Diff.DiffEntry> r     = new AList <NGit.Diff.DiffEntry>();
            MutableObjectId             idBuf = new MutableObjectId();

            while (walk.Next())
            {
                NGit.Diff.DiffEntry entry = new NGit.Diff.DiffEntry();
                walk.GetObjectId(idBuf, 0);
                entry.oldId = AbbreviatedObjectId.FromObjectId(idBuf);
                walk.GetObjectId(idBuf, 1);
                entry.newId   = AbbreviatedObjectId.FromObjectId(idBuf);
                entry.oldMode = walk.GetFileMode(0);
                entry.newMode = walk.GetFileMode(1);
                entry.newPath = entry.oldPath = walk.PathString;
                if (entry.oldMode == FileMode.MISSING)
                {
                    entry.oldPath    = NGit.Diff.DiffEntry.DEV_NULL;
                    entry.changeType = DiffEntry.ChangeType.ADD;
                    r.AddItem(entry);
                }
                else
                {
                    if (entry.newMode == FileMode.MISSING)
                    {
                        entry.newPath    = NGit.Diff.DiffEntry.DEV_NULL;
                        entry.changeType = DiffEntry.ChangeType.DELETE;
                        r.AddItem(entry);
                    }
                    else
                    {
                        entry.changeType = DiffEntry.ChangeType.MODIFY;
                        if (RenameDetector.SameType(entry.oldMode, entry.newMode))
                        {
                            r.AddItem(entry);
                        }
                        else
                        {
                            Sharpen.Collections.AddAll(r, BreakModify(entry));
                        }
                    }
                }
            }
            return(r);
        }
        /// <summary>
        /// Convert the TreeWalk into DiffEntry headers, depending on
        /// <code>includeTrees</code>
        /// it will add tree objects into result or not.
        /// </summary>
        /// <param name="walk">
        /// the TreeWalk to walk through. Must have exactly two trees and
        /// when
        /// <code>includeTrees</code>
        /// parameter is
        /// <code>true</code>
        /// it can't
        /// be recursive.
        /// </param>
        /// <param name="includeTrees">include tree object's.</param>
        /// <returns>headers describing the changed files.</returns>
        /// <exception cref="System.IO.IOException">the repository cannot be accessed.</exception>
        /// <exception cref="System.ArgumentException">
        /// when
        /// <code>includeTrees</code>
        /// is true and given TreeWalk is
        /// recursive. Or when given TreeWalk doesn't have exactly two
        /// trees
        /// </exception>
        public static IList <NGit.Diff.DiffEntry> Scan(TreeWalk walk, bool includeTrees)
        {
            if (walk.TreeCount != 2)
            {
                throw new ArgumentException(JGitText.Get().treeWalkMustHaveExactlyTwoTrees);
            }
            if (includeTrees && walk.Recursive)
            {
                throw new ArgumentException(JGitText.Get().cannotBeRecursiveWhenTreesAreIncluded);
            }
            IList <NGit.Diff.DiffEntry> r     = new AList <NGit.Diff.DiffEntry>();
            MutableObjectId             idBuf = new MutableObjectId();

            while (walk.Next())
            {
                NGit.Diff.DiffEntry entry = new NGit.Diff.DiffEntry();
                walk.GetObjectId(idBuf, 0);
                entry.oldId = AbbreviatedObjectId.FromObjectId(idBuf);
                walk.GetObjectId(idBuf, 1);
                entry.newId   = AbbreviatedObjectId.FromObjectId(idBuf);
                entry.oldMode = walk.GetFileMode(0);
                entry.newMode = walk.GetFileMode(1);
                entry.newPath = entry.oldPath = walk.PathString;
                if (entry.oldMode == FileMode.MISSING)
                {
                    entry.oldPath    = NGit.Diff.DiffEntry.DEV_NULL;
                    entry.changeType = DiffEntry.ChangeType.ADD;
                    r.AddItem(entry);
                }
                else
                {
                    if (entry.newMode == FileMode.MISSING)
                    {
                        entry.newPath    = NGit.Diff.DiffEntry.DEV_NULL;
                        entry.changeType = DiffEntry.ChangeType.DELETE;
                        r.AddItem(entry);
                    }
                    else
                    {
                        if (!entry.oldId.Equals(entry.newId))
                        {
                            entry.changeType = DiffEntry.ChangeType.MODIFY;
                            if (RenameDetector.SameType(entry.oldMode, entry.newMode))
                            {
                                r.AddItem(entry);
                            }
                            else
                            {
                                Sharpen.Collections.AddAll(r, BreakModify(entry));
                            }
                        }
                        else
                        {
                            if (entry.oldMode != entry.newMode)
                            {
                                entry.changeType = DiffEntry.ChangeType.MODIFY;
                                r.AddItem(entry);
                            }
                        }
                    }
                }
                if (includeTrees && walk.IsSubtree)
                {
                    walk.EnterSubtree();
                }
            }
            return(r);
        }
        /// <exception cref="System.IO.IOException"></exception>
        private int BuildMatrix(ProgressMonitor pm)
        {
            // Allocate for the worst-case scenario where every pair has a
            // score that we need to consider. We might not need that many.
            //
            matrix = new long[srcs.Count * dsts.Count];
            long[] srcSizes    = new long[srcs.Count];
            long[] dstSizes    = new long[dsts.Count];
            BitSet dstTooLarge = null;
            // Consider each pair of files, if the score is above the minimum
            // threshold we need record that scoring in the matrix so we can
            // later find the best matches.
            //
            int mNext = 0;

            for (int srcIdx = 0; srcIdx < srcs.Count; srcIdx++)
            {
                DiffEntry srcEnt = srcs[srcIdx];
                if (!IsFile(srcEnt.oldMode))
                {
                    pm.Update(dsts.Count);
                    continue;
                }
                SimilarityIndex s = null;
                for (int dstIdx = 0; dstIdx < dsts.Count; dstIdx++)
                {
                    DiffEntry dstEnt = dsts[dstIdx];
                    if (!IsFile(dstEnt.newMode))
                    {
                        pm.Update(1);
                        continue;
                    }
                    if (!RenameDetector.SameType(srcEnt.oldMode, dstEnt.newMode))
                    {
                        pm.Update(1);
                        continue;
                    }
                    if (dstTooLarge != null && dstTooLarge.Get(dstIdx))
                    {
                        pm.Update(1);
                        continue;
                    }
                    long srcSize = srcSizes[srcIdx];
                    if (srcSize == 0)
                    {
                        srcSize          = Size(DiffEntry.Side.OLD, srcEnt) + 1;
                        srcSizes[srcIdx] = srcSize;
                    }
                    long dstSize = dstSizes[dstIdx];
                    if (dstSize == 0)
                    {
                        dstSize          = Size(DiffEntry.Side.NEW, dstEnt) + 1;
                        dstSizes[dstIdx] = dstSize;
                    }
                    long max = Math.Max(srcSize, dstSize);
                    long min = Math.Min(srcSize, dstSize);
                    if (min * 100 / max < renameScore)
                    {
                        // Cannot possibly match, as the file sizes are so different
                        pm.Update(1);
                        continue;
                    }
                    if (s == null)
                    {
                        try
                        {
                            s = Hash(DiffEntry.Side.OLD, srcEnt);
                        }
                        catch (SimilarityIndex.TableFullException)
                        {
                            tableOverflow = true;
                            goto SRC_continue;
                        }
                    }
                    SimilarityIndex d;
                    try
                    {
                        d = Hash(DiffEntry.Side.NEW, dstEnt);
                    }
                    catch (SimilarityIndex.TableFullException)
                    {
                        if (dstTooLarge == null)
                        {
                            dstTooLarge = new BitSet(dsts.Count);
                        }
                        dstTooLarge.Set(dstIdx);
                        tableOverflow = true;
                        pm.Update(1);
                        continue;
                    }
                    int contentScore = s.Score(d, 10000);
                    // nameScore returns a value between 0 and 100, but we want it
                    // to be in the same range as the content score. This allows it
                    // to be dropped into the pretty formula for the final score.
                    int nameScore = NameScore(srcEnt.oldPath, dstEnt.newPath) * 100;
                    int score     = (contentScore * 99 + nameScore * 1) / 10000;
                    if (score < renameScore)
                    {
                        pm.Update(1);
                        continue;
                    }
                    matrix[mNext++] = Encode(score, srcIdx, dstIdx);
                    pm.Update(1);
                }
                SRC_continue :;
            }
            SRC_break :;
            // Sort everything in the range we populated, which might be the
            // entire matrix, or just a smaller slice if we had some bad low
            // scoring pairs.
            //
            Arrays.Sort(matrix, 0, mNext);
            return(mNext);
        }
 public override void SetUp()
 {
     base.SetUp();
     testDb = new TestRepository <FileRepository>(db);
     rd     = new RenameDetector(db);
 }