Beispiel #1
0
        public virtual void TestCreateFileHeader_Modify()
        {
            ObjectId   adId       = Blob("a\nd\n");
            ObjectId   abcdId     = Blob("a\nb\nc\nd\n");
            string     diffHeader = MakeDiffHeader(PATH_A, PATH_A, adId, abcdId);
            DiffEntry  ad         = DiffEntry.Delete(PATH_A, adId);
            DiffEntry  abcd       = DiffEntry.Add(PATH_A, abcdId);
            DiffEntry  mod        = DiffEntry.Pair(DiffEntry.ChangeType.MODIFY, ad, abcd, 0);
            FileHeader fh         = df.ToFileHeader(mod);

            NUnit.Framework.Assert.AreEqual(diffHeader, RawParseUtils.Decode(fh.GetBuffer()));
            NUnit.Framework.Assert.AreEqual(0, fh.GetStartOffset());
            NUnit.Framework.Assert.AreEqual(fh.GetBuffer().Length, fh.GetEndOffset());
            NUnit.Framework.Assert.AreEqual(FileHeader.PatchType.UNIFIED, fh.GetPatchType());
            NUnit.Framework.Assert.AreEqual(1, fh.GetHunks().Count);
            HunkHeader hh = fh.GetHunks()[0];

            NUnit.Framework.Assert.AreEqual(1, hh.ToEditList().Count);
            EditList el = hh.ToEditList();

            NUnit.Framework.Assert.AreEqual(1, el.Count);
            Edit e = el[0];

            NUnit.Framework.Assert.AreEqual(1, e.GetBeginA());
            NUnit.Framework.Assert.AreEqual(1, e.GetEndA());
            NUnit.Framework.Assert.AreEqual(1, e.GetBeginB());
            NUnit.Framework.Assert.AreEqual(3, e.GetEndB());
            NUnit.Framework.Assert.AreEqual(Edit.Type.INSERT, e.GetType());
        }
        /// <exception cref="System.IO.IOException"></exception>
        internal virtual void Compute(ProgressMonitor pm)
        {
            if (pm == null)
            {
                pm = NullProgressMonitor.INSTANCE;
            }
            pm.BeginTask(JGitText.Get().renamesFindingByContent, 2 * srcs.Count * dsts.Count);
            //
            int mNext = BuildMatrix(pm);

            @out = new AList <DiffEntry>(Math.Min(mNext, dsts.Count));
            // Match rename pairs on a first come, first serve basis until
            // we have looked at everything that is above our minimum score.
            //
            for (--mNext; mNext >= 0; mNext--)
            {
                long      ent  = matrix[mNext];
                int       sIdx = SrcFile(ent);
                int       dIdx = DstFile(ent);
                DiffEntry s    = srcs[sIdx];
                DiffEntry d    = dsts[dIdx];
                if (d == null)
                {
                    pm.Update(1);
                    continue;
                }
                // was already matched earlier
                DiffEntry.ChangeType type;
                if (s.changeType == DiffEntry.ChangeType.DELETE)
                {
                    // First use of this source file. Tag it as a rename so we
                    // later know it is already been used as a rename, other
                    // matches (if any) will claim themselves as copies instead.
                    //
                    s.changeType = DiffEntry.ChangeType.RENAME;
                    type         = DiffEntry.ChangeType.RENAME;
                }
                else
                {
                    type = DiffEntry.ChangeType.COPY;
                }
                @out.AddItem(DiffEntry.Pair(type, s, d, Score(ent)));
                dsts.Set(dIdx, null);
                // Claim the destination was matched.
                pm.Update(1);
            }
            srcs = CompactSrcList(srcs);
            dsts = CompactDstList(dsts);
            pm.EndTask();
        }
Beispiel #3
0
        public virtual void TestCreateFileHeader_Binary()
        {
            ObjectId   adId       = Blob("a\nd\n");
            ObjectId   binId      = Blob("a\nb\nc\n\x0\x0\x0\x0d\n");
            string     diffHeader = MakeDiffHeader(PATH_A, PATH_B, adId, binId) + "Binary files differ\n";
            DiffEntry  ad         = DiffEntry.Delete(PATH_A, adId);
            DiffEntry  abcd       = DiffEntry.Add(PATH_B, binId);
            DiffEntry  mod        = DiffEntry.Pair(DiffEntry.ChangeType.MODIFY, ad, abcd, 0);
            FileHeader fh         = df.ToFileHeader(mod);

            NUnit.Framework.Assert.AreEqual(diffHeader, RawParseUtils.Decode(fh.GetBuffer()));
            NUnit.Framework.Assert.AreEqual(FileHeader.PatchType.BINARY, fh.GetPatchType());
            NUnit.Framework.Assert.AreEqual(1, fh.GetHunks().Count);
            HunkHeader hh = fh.GetHunks()[0];

            NUnit.Framework.Assert.AreEqual(0, hh.ToEditList().Count);
        }
Beispiel #4
0
        public virtual void TestCreateFileHeader_GitLink()
        {
            ObjectId aId        = Blob("a\n");
            ObjectId bId        = Blob("b\n");
            string   diffHeader = MakeDiffHeaderModeChange(PATH_A, PATH_A, aId, bId, GITLINK, REGULAR_FILE
                                                           ) + "-Subproject commit " + aId.Name + "\n";
            DiffEntry ad = DiffEntry.Delete(PATH_A, aId);

            ad.oldMode = FileMode.GITLINK;
            DiffEntry  abcd = DiffEntry.Add(PATH_A, bId);
            DiffEntry  mod  = DiffEntry.Pair(DiffEntry.ChangeType.MODIFY, ad, abcd, 0);
            FileHeader fh   = df.ToFileHeader(mod);

            NUnit.Framework.Assert.AreEqual(diffHeader, RawParseUtils.Decode(fh.GetBuffer()));
            NUnit.Framework.Assert.AreEqual(1, fh.GetHunks().Count);
            HunkHeader hh = fh.GetHunks()[0];

            NUnit.Framework.Assert.AreEqual(0, hh.ToEditList().Count);
        }
        private void RejoinModifies(ProgressMonitor pm)
        {
            Dictionary <string, DiffEntry> nameMap = new Dictionary <string, DiffEntry>();
            AList <DiffEntry> newAdded             = new AList <DiffEntry>(added.Count);

            pm.BeginTask(JGitText.Get().renamesRejoiningModifies, added.Count + deleted.Count
                         );
            foreach (DiffEntry src in deleted)
            {
                nameMap.Put(src.oldPath, src);
                pm.Update(1);
            }
            foreach (DiffEntry dst in added)
            {
                DiffEntry src_1 = Sharpen.Collections.Remove(nameMap, dst.newPath);
                if (src_1 != null)
                {
                    if (SameType(src_1.oldMode, dst.newMode))
                    {
                        entries.AddItem(DiffEntry.Pair(DiffEntry.ChangeType.MODIFY, src_1, dst, src_1.score
                                                       ));
                    }
                    else
                    {
                        nameMap.Put(src_1.oldPath, src_1);
                        newAdded.AddItem(dst);
                    }
                }
                else
                {
                    newAdded.AddItem(dst);
                }
                pm.Update(1);
            }
            added   = newAdded;
            deleted = new AList <DiffEntry>(nameMap.Values);
        }
 private static DiffEntry ExactCopy(DiffEntry src, DiffEntry dst)
 {
     return(DiffEntry.Pair(DiffEntry.ChangeType.COPY, src, dst, EXACT_RENAME_SCORE));
 }
 private static DiffEntry ExactRename(DiffEntry src, DiffEntry dst)
 {
     return(DiffEntry.Pair(DiffEntry.ChangeType.RENAME, src, dst, EXACT_RENAME_SCORE));
 }
        private void FindExactRenames(ProgressMonitor pm)
        {
            pm.BeginTask(JGitText.Get().renamesFindingExact, added.Count + added.Count + deleted
                         .Count + added.Count * deleted.Count);
            //
            Dictionary <AbbreviatedObjectId, object> deletedMap = PopulateMap(deleted, pm);
            Dictionary <AbbreviatedObjectId, object> addedMap   = PopulateMap(added, pm);
            AList <DiffEntry>          uniqueAdds    = new AList <DiffEntry>(added.Count);
            AList <IList <DiffEntry> > nonUniqueAdds = new AList <IList <DiffEntry> >();

            foreach (object o in addedMap.Values)
            {
                if (o is DiffEntry)
                {
                    uniqueAdds.AddItem((DiffEntry)o);
                }
                else
                {
                    nonUniqueAdds.AddItem((IList <DiffEntry>)o);
                }
            }
            AList <DiffEntry> left = new AList <DiffEntry>(added.Count);

            foreach (DiffEntry a in uniqueAdds)
            {
                object del = deletedMap.Get(a.newId);
                if (del is DiffEntry)
                {
                    // We have one add to one delete: pair them if they are the same
                    // type
                    DiffEntry e = (DiffEntry)del;
                    if (SameType(e.oldMode, a.newMode))
                    {
                        e.changeType = DiffEntry.ChangeType.RENAME;
                        entries.AddItem(ExactRename(e, a));
                    }
                    else
                    {
                        left.AddItem(a);
                    }
                }
                else
                {
                    if (del != null)
                    {
                        // We have one add to many deletes: find the delete with the
                        // same type and closest name to the add, then pair them
                        IList <DiffEntry> list = (IList <DiffEntry>)del;
                        DiffEntry         best = BestPathMatch(a, list);
                        if (best != null)
                        {
                            best.changeType = DiffEntry.ChangeType.RENAME;
                            entries.AddItem(ExactRename(best, a));
                        }
                        else
                        {
                            left.AddItem(a);
                        }
                    }
                    else
                    {
                        left.AddItem(a);
                    }
                }
                pm.Update(1);
            }
            foreach (IList <DiffEntry> adds in nonUniqueAdds)
            {
                object o_1 = deletedMap.Get(adds[0].newId);
                if (o_1 is DiffEntry)
                {
                    // We have many adds to one delete: find the add with the same
                    // type and closest name to the delete, then pair them. Mark the
                    // rest as copies of the delete.
                    DiffEntry d    = (DiffEntry)o_1;
                    DiffEntry best = BestPathMatch(d, adds);
                    if (best != null)
                    {
                        d.changeType = DiffEntry.ChangeType.RENAME;
                        entries.AddItem(ExactRename(d, best));
                        foreach (DiffEntry a_1 in adds)
                        {
                            if (a_1 != best)
                            {
                                if (SameType(d.oldMode, a_1.newMode))
                                {
                                    entries.AddItem(ExactCopy(d, a_1));
                                }
                                else
                                {
                                    left.AddItem(a_1);
                                }
                            }
                        }
                    }
                    else
                    {
                        Sharpen.Collections.AddAll(left, adds);
                    }
                }
                else
                {
                    if (o_1 != null)
                    {
                        // We have many adds to many deletes: score all the adds against
                        // all the deletes by path name, take the best matches, pair
                        // them as renames, then call the rest copies
                        IList <DiffEntry> dels   = (IList <DiffEntry>)o_1;
                        long[]            matrix = new long[dels.Count * adds.Count];
                        int mNext = 0;
                        for (int delIdx = 0; delIdx < dels.Count; delIdx++)
                        {
                            string deletedName = dels[delIdx].oldPath;
                            for (int addIdx = 0; addIdx < adds.Count; addIdx++)
                            {
                                string addedName = adds[addIdx].newPath;
                                int    score     = SimilarityRenameDetector.NameScore(addedName, deletedName);
                                matrix[mNext] = SimilarityRenameDetector.Encode(score, delIdx, addIdx);
                                mNext++;
                            }
                        }
                        Arrays.Sort(matrix);
                        for (--mNext; mNext >= 0; mNext--)
                        {
                            long      ent      = matrix[mNext];
                            int       delIdx_1 = SimilarityRenameDetector.SrcFile(ent);
                            int       addIdx   = SimilarityRenameDetector.DstFile(ent);
                            DiffEntry d        = dels[delIdx_1];
                            DiffEntry a_1      = adds[addIdx];
                            if (a_1 == null)
                            {
                                pm.Update(1);
                                continue;
                            }
                            // was already matched earlier
                            DiffEntry.ChangeType type;
                            if (d.changeType == DiffEntry.ChangeType.DELETE)
                            {
                                // First use of this source file. Tag it as a rename so we
                                // later know it is already been used as a rename, other
                                // matches (if any) will claim themselves as copies instead.
                                //
                                d.changeType = DiffEntry.ChangeType.RENAME;
                                type         = DiffEntry.ChangeType.RENAME;
                            }
                            else
                            {
                                type = DiffEntry.ChangeType.COPY;
                            }
                            entries.AddItem(DiffEntry.Pair(type, d, a_1, 100));
                            adds.Set(addIdx, null);
                            // Claim the destination was matched.
                            pm.Update(1);
                        }
                    }
                    else
                    {
                        Sharpen.Collections.AddAll(left, adds);
                    }
                }
            }
            added   = left;
            deleted = new AList <DiffEntry>(deletedMap.Count);
            foreach (object o_2 in deletedMap.Values)
            {
                if (o_2 is DiffEntry)
                {
                    DiffEntry e = (DiffEntry)o_2;
                    if (e.changeType == DiffEntry.ChangeType.DELETE)
                    {
                        deleted.AddItem(e);
                    }
                }
                else
                {
                    IList <DiffEntry> list = (IList <DiffEntry>)o_2;
                    foreach (DiffEntry e in list)
                    {
                        if (e.changeType == DiffEntry.ChangeType.DELETE)
                        {
                            deleted.AddItem(e);
                        }
                    }
                }
            }
            pm.EndTask();
        }