Ejemplo n.º 1
0
        public static Diff Compare(string fileOnePath, string fileOneContent, string fileTwoPath, string fileTwoContent, CompareOptions options)
        {
            if (fileOneContent == null && fileTwoContent == null)
                throw new InvalidOperationException("Both files were null");

            if (options.BomMode == BomMode.Ignore)
            {
                if (fileOneContent != null)
                    fileOneContent = RemoveBom(fileOneContent);
                if (fileTwoContent != null)
                    fileTwoContent = RemoveBom(fileTwoContent);
            }

            if (fileTwoContent == null)
                return DeletedFileDiff(fileOneContent, fileOnePath);
            if (fileOneContent == null)
                return NewFileDiff(fileTwoContent, fileTwoPath);
            if (IsBinary(fileOneContent))
                throw new BinaryFileException(fileOnePath);
            if (IsBinary(fileTwoContent))
                throw new BinaryFileException(fileTwoPath);

            var patchMaker = new PatchMaker();
            var patches = patchMaker.MakePatch(fileOneContent, fileTwoContent, options);
            var chunks = new List<Chunk>();

            foreach (var patch in patches)
            {
                var originalRange = new ChangeRange(patch.start1 + 1, patch.length1);
                var newRange = new ChangeRange(patch.start2 + 1, patch.length2);
                var range = new ChunkRange(originalRange, newRange);
                var snippets = new List<ISnippet>();

                var lines = new List<DiffMatchPatch.Diff>();
                Operation? previousOperation = null;
                var isModification = false;

                foreach (var diff in patch.diffs)
                {
                    if (previousOperation == null)
                        previousOperation = diff.operation;
                    if (previousOperation == Operation.DELETE && diff.operation == Operation.INSERT)
                        isModification = true;
                    else if (previousOperation != diff.operation)
                    {
                        // different operation
                        if (previousOperation == Operation.EQUAL)
                            snippets.Add(new ContextSnippet(lines.Select(x => new ContextLine(x.text)).Cast<ILine>()));
                        else if (isModification)
                            snippets.Add(new ModificationSnippet(
                                lines
                                    .Where(x => x.operation == Operation.DELETE)
                                    .Select(x => new SubtractionLine(x.text))
                                    .Cast<ILine>(),
                                lines
                                    .Where(x => x.operation == Operation.INSERT)
                                    .Select(x => new AdditionLine(x.text))
                                    .Cast<ILine>()
                            ));
                        else if (previousOperation == Operation.INSERT)
                            snippets.Add(new AdditionSnippet(lines.Select(x => new AdditionLine(x.text)).Cast<ILine>()));
                        else if (previousOperation == Operation.DELETE)
                            snippets.Add(new SubtractionSnippet(lines.Select(x => new SubtractionLine(x.text)).Cast<ILine>()));

                        lines.Clear();
                        isModification = false;
                    }

                    lines.Add(diff);
                    previousOperation = diff.operation;
                }

                if (lines.Count > 0)
                {
                    if (previousOperation == Operation.INSERT)
                        snippets.Add(new AdditionSnippet(lines.Select(x => new AdditionLine(x.text)).Cast<ILine>()));
                    else if (previousOperation == Operation.DELETE)
                        snippets.Add(new SubtractionSnippet(lines.Select(x => new SubtractionLine(x.text)).Cast<ILine>()));
                    else
                        snippets.Add(new ContextSnippet(lines.Select(x => new ContextLine(x.text)).Cast<ILine>()));
                }

                chunks.Add(new Chunk(range, snippets));
            }

            var fileOne = new File('a', fileOnePath);
            var fileTwo = new File('b', fileTwoPath);
            var header = new DiffHeader(new DiffFormatType("generated"), new[] { fileOne, fileTwo });

            return new Diff(header, new IHeader[0], new ChunksHeader(fileOne, fileTwo), chunks);
        }
Ejemplo n.º 2
0
        internal static Diff NewFileDiff(string content, string path)
        {
            var fileOne = new NullFile();
            var fileTwo = new File('b', path);
            var header = new DiffHeader(new DiffFormatType("generated"), new IFile[] { fileOne, fileTwo });

            var lines = content.SplitIntoLines()
                .Select(x => (ILine)new AdditionLine(x));
            var range = new ChunkRange(new ChangeRange(0, 0), new ChangeRange(1, lines.Count()));
            var snippet = new AdditionSnippet(lines);
            var chunk = new Chunk(range, new[] { snippet });

            return new Diff(header, new IHeader[0], new ChunksHeader(fileOne, fileTwo), new[] { chunk });
        }