/// <exception cref="System.IO.IOException"></exception>
        private void BreakModifies(ContentSource.Pair reader, ProgressMonitor pm)
        {
            AList <DiffEntry> newEntries = new AList <DiffEntry>(entries.Count);

            pm.BeginTask(JGitText.Get().renamesBreakingModifies, entries.Count);
            for (int i = 0; i < entries.Count; i++)
            {
                DiffEntry e = entries[i];
                if (e.GetChangeType() == DiffEntry.ChangeType.MODIFY)
                {
                    int score = CalculateModifyScore(reader, e);
                    if (score < breakScore)
                    {
                        IList <DiffEntry> tmp = DiffEntry.BreakModify(e);
                        DiffEntry         del = tmp[0];
                        del.score = score;
                        deleted.AddItem(del);
                        added.AddItem(tmp[1]);
                    }
                    else
                    {
                        newEntries.AddItem(e);
                    }
                }
                else
                {
                    newEntries.AddItem(e);
                }
                pm.Update(1);
            }
            entries = newEntries;
        }
 /// <summary>Detect renames in the current file set.</summary>
 /// <remarks>Detect renames in the current file set.</remarks>
 /// <param name="reader">reader to obtain objects from the repository with.</param>
 /// <param name="pm">report progress during the detection phases.</param>
 /// <returns>
 /// an unmodifiable list of
 /// <see cref="DiffEntry">DiffEntry</see>
 /// s representing all files
 /// that have been changed.
 /// </returns>
 /// <exception cref="System.IO.IOException">file contents cannot be read from the repository.
 ///     </exception>
 public virtual IList <DiffEntry> Compute(ContentSource.Pair reader, ProgressMonitor
                                          pm)
 {
     if (!done)
     {
         done = true;
         if (pm == null)
         {
             pm = NullProgressMonitor.INSTANCE;
         }
         if (0 < breakScore)
         {
             BreakModifies(reader, pm);
         }
         if (!added.IsEmpty() && !deleted.IsEmpty())
         {
             FindExactRenames(pm);
         }
         if (!added.IsEmpty() && !deleted.IsEmpty())
         {
             FindContentRenames(reader, pm);
         }
         if (0 < breakScore && !added.IsEmpty() && !deleted.IsEmpty())
         {
             RejoinModifies(pm);
         }
         Sharpen.Collections.AddAll(entries, added);
         added = null;
         Sharpen.Collections.AddAll(entries, deleted);
         deleted = null;
         entries.Sort(DIFF_COMPARATOR);
     }
     return(Sharpen.Collections.UnmodifiableList(entries));
 }
 internal SimilarityRenameDetector(ContentSource.Pair reader, IList <DiffEntry> srcs
                                   , IList <DiffEntry> dsts)
 {
     this.reader = reader;
     this.srcs   = srcs;
     this.dsts   = dsts;
 }
Exemplo n.º 4
0
        /// <summary>Determine the differences between two trees.</summary>
        /// <remarks>
        /// Determine the differences between two trees.
        /// No output is created, instead only the file paths that are different are
        /// returned. Callers may choose to format these paths themselves, or convert
        /// them into
        /// <see cref="NGit.Patch.FileHeader">NGit.Patch.FileHeader</see>
        /// instances with a complete edit list by
        /// calling
        /// <see cref="ToFileHeader(DiffEntry)">ToFileHeader(DiffEntry)</see>
        /// .
        /// </remarks>
        /// <param name="a">the old (or previous) side.</param>
        /// <param name="b">the new (or updated) side.</param>
        /// <returns>the paths that are different.</returns>
        /// <exception cref="System.IO.IOException">trees cannot be read or file contents cannot be read.
        ///     </exception>
        public virtual IList <DiffEntry> Scan(AbstractTreeIterator a, AbstractTreeIterator
                                              b)
        {
            AssertHaveRepository();
            TreeWalk walk = new TreeWalk(reader);

            walk.AddTree(a);
            walk.AddTree(b);
            walk.Recursive = true;
            TreeFilter filter = GetDiffTreeFilterFor(a, b);

            if (pathFilter is FollowFilter)
            {
                walk.Filter = AndTreeFilter.Create(PathFilter.Create(((FollowFilter)pathFilter).GetPath
                                                                         ()), filter);
            }
            else
            {
                walk.Filter = AndTreeFilter.Create(pathFilter, filter);
            }
            source = new ContentSource.Pair(Source(a), Source(b));
            IList <DiffEntry> files = DiffEntry.Scan(walk);

            if (pathFilter is FollowFilter && IsAdd(files))
            {
                // The file we are following was added here, find where it
                // came from so we can properly show the rename or copy,
                // then continue digging backwards.
                //
                a.Reset();
                b.Reset();
                walk.Reset();
                walk.AddTree(a);
                walk.AddTree(b);
                walk.Filter = filter;
                if (renameDetector == null)
                {
                    SetDetectRenames(true);
                }
                files = UpdateFollowFilter(DetectRenames(DiffEntry.Scan(walk)));
            }
            else
            {
                if (renameDetector != null)
                {
                    files = DetectRenames(files);
                }
            }
            return(files);
        }
        /// <exception cref="System.IO.IOException"></exception>
        private void FindContentRenames(ContentSource.Pair reader, ProgressMonitor pm)
        {
            int cnt = Math.Max(added.Count, deleted.Count);

            if (GetRenameLimit() == 0 || cnt <= GetRenameLimit())
            {
                SimilarityRenameDetector d;
                d = new SimilarityRenameDetector(reader, deleted, added);
                d.SetRenameScore(GetRenameScore());
                d.Compute(pm);
                overRenameLimit |= d.IsTableOverflow();
                deleted          = d.GetLeftOverSources();
                added            = d.GetLeftOverDestinations();
                Sharpen.Collections.AddAll(entries, d.GetMatches());
            }
            else
            {
                overRenameLimit = true;
            }
        }
 /// <exception cref="System.IO.IOException"></exception>
 private int CalculateModifyScore(ContentSource.Pair reader, DiffEntry d)
 {
     try
     {
         SimilarityIndex src = new SimilarityIndex();
         src.Hash(reader.Open(DiffEntry.Side.OLD, d));
         src.Sort();
         SimilarityIndex dst = new SimilarityIndex();
         dst.Hash(reader.Open(DiffEntry.Side.NEW, d));
         dst.Sort();
         return(src.Score(dst, 100));
     }
     catch (SimilarityIndex.TableFullException)
     {
         // If either table overflowed while being constructed, don't allow
         // the pair to be broken. Returning 1 higher than breakScore will
         // ensure its not similar, but not quite dissimilar enough to break.
         //
         overRenameLimit = true;
         return(breakScore + 1);
     }
 }
Exemplo n.º 7
0
        /// <summary>Set the repository the formatter can load object contents from.</summary>
        /// <remarks>
        /// Set the repository the formatter can load object contents from.
        /// Once a repository has been set, the formatter must be released to ensure
        /// the internal ObjectReader is able to release its resources.
        /// </remarks>
        /// <param name="repository">source repository holding referenced objects.</param>
        public virtual void SetRepository(Repository repository)
        {
            if (reader != null)
            {
                reader.Release();
            }
            db     = repository;
            reader = db.NewObjectReader();
            ContentSource cs = ContentSource.Create(reader);

            source = new ContentSource.Pair(cs, cs);
            DiffConfig dc = db.GetConfig().Get(DiffConfig.KEY);

            if (dc.IsNoPrefix())
            {
                SetOldPrefix(string.Empty);
                SetNewPrefix(string.Empty);
            }
            SetDetectRenames(dc.IsRenameDetectionEnabled());
            diffAlgorithm = DiffAlgorithm.GetAlgorithm(db.GetConfig().GetEnum(ConfigConstants
                                                                              .CONFIG_DIFF_SECTION, null, ConfigConstants.CONFIG_KEY_ALGORITHM, DiffAlgorithm.SupportedAlgorithm
                                                                              .HISTOGRAM));
        }
		internal SimilarityRenameDetector(ContentSource.Pair reader, IList<DiffEntry> srcs
			, IList<DiffEntry> dsts)
		{
			this.reader = reader;
			this.srcs = srcs;
			this.dsts = dsts;
		}