Пример #1
0
        private void UpdateRepository()
        {
            _repository?.Dispose();
            _repository = new Repository(_repositoryPath);

            var compareOptions = new CompareOptions();

            compareOptions.ContextLines = _fullFileDiff ? int.MaxValue : _contextLines;

            var tipTree = _repository.Head.Tip?.Tree;
            var changes = _viewStage
                ? _repository.Diff.Compare <TreeChanges>(tipTree, DiffTargets.Index)
                : _repository.Diff.Compare <TreeChanges>(null, true);
            var paths = changes.Select(c => c.Path).ToArray();
            var patch = paths.Any()
                ? _viewStage
                    ? _repository.Diff.Compare <Patch>(tipTree, DiffTargets.Index, paths, null, compareOptions)
                    : _repository.Diff.Compare <Patch>(paths, true, null, compareOptions)
                : null;

            _document      = PatchDocument.Parse(patch);
            _view.Document = _document;

            UpdateHeader();
            UpdateFooter();
        }
Пример #2
0
        public static int FindEndOfChangeBlock(this PatchDocument document, int lineIndex)
        {
            var end = lineIndex;

            while (end < document.Lines.Count - 1 && document.Lines[end + 1].Kind.IsAdditionOrRemoval())
            {
                end++;
            }

            return(end);
        }
Пример #3
0
        public static int FindStartOfChangeBlock(this PatchDocument document, int lineIndex)
        {
            var start = lineIndex;

            while (start > 0 && document.Lines[start - 1].Kind.IsAdditionOrRemoval())
            {
                start--;
            }

            return(start);
        }
Пример #4
0
        public static int FindNextChangeBlock(this PatchDocument document, int lineIndex)
        {
            var end = lineIndex;

            // Skip current block
            while (end < document.Lines.Count - 1 && document.Lines[end].Kind.IsAdditionOrRemoval())
            {
                end++;
            }

            // Find next block
            while (end < document.Lines.Count - 1 && !document.Lines[end].Kind.IsAdditionOrRemoval())
            {
                end++;
            }

            if (end >= document.Lines.Count || !document.Lines[end].Kind.IsAdditionOrRemoval())
            {
                return(lineIndex);
            }

            return(end);
        }
Пример #5
0
        public static int FindPreviousChangeBlock(this PatchDocument document, int lineIndex)
        {
            var start = lineIndex;

            // Skip current block
            while (start > 0 && document.Lines[start].Kind.IsAdditionOrRemoval())
            {
                start--;
            }

            // Find next block
            while (start > 0 && !document.Lines[start].Kind.IsAdditionOrRemoval())
            {
                start--;
            }

            if (start < 0 || !document.Lines[start].Kind.IsAdditionOrRemoval())
            {
                return(lineIndex);
            }

            return(start);
        }
Пример #6
0
        private void UpdateRepository()
        {
            _repository?.Dispose();
            _repository = new Repository(_repositoryPath);

            var compareOptions = new CompareOptions();
            compareOptions.ContextLines = _fullFileDiff ? int.MaxValue : _contextLines;

            var tipTree = _repository.Head.Tip?.Tree;
            var changes = _viewStage
                ? _repository.Diff.Compare<TreeChanges>(tipTree, DiffTargets.Index)
                : _repository.Diff.Compare<TreeChanges>(null, true);
            var paths = changes.Select(c => c.Path).ToArray();
            var patch = paths.Any()
                ? _viewStage
                    ? _repository.Diff.Compare<Patch>(tipTree, DiffTargets.Index, paths, null, compareOptions)
                    : _repository.Diff.Compare<Patch>(paths, true, null, compareOptions)
                : null;

            _document = PatchDocument.Parse(patch);
            _view.Document = _document;

            UpdateHeader();
            UpdateFooter();
        }
Пример #7
0
        public static string ComputePatch(PatchDocument document, IEnumerable <int> lineIndexes, PatchDirection direction)
        {
            var isUndo = direction == PatchDirection.Reset ||
                         direction == PatchDirection.Unstage;

            var newPatch = new StringBuilder();

            var entryLines = lineIndexes.Select(i => new { i, e = document.FindEntry(i) }).GroupBy(t => t.e, t => t.i);

            foreach (var entryLine in entryLines)
            {
                var entry     = entryLine.Key;
                var hunkLines = entryLine.Select(i => new { i, h = entry.FindHunk(i) }).GroupBy(t => t.h, t => t.i);

                foreach (var hunkLine in hunkLines)
                {
                    var hunk    = hunkLine.Key;
                    var lineSet = new HashSet <int>(hunkLine);

                    // Get current hunk information

                    var oldStart = hunk.OldStart;
                    var newStart = hunk.NewStart;

                    // Compute the new hunk size

                    var oldLength = 0;

                    for (var i = hunk.Offset; i < hunk.Offset + hunk.Length; i++)
                    {
                        var line = document.Lines[i];
                        var kind = line.Kind;

                        var wasPresent = kind == PatchLineKind.Context ||
                                         kind == PatchLineKind.Removal && (!isUndo || lineSet.Contains(i)) ||
                                         kind == PatchLineKind.Addition && (isUndo && !lineSet.Contains(i));

                        if (wasPresent)
                        {
                            oldLength++;
                        }
                    }

                    var delta = lineSet.Select(i => document.Lines[i])
                                .Select(l => l.Kind)
                                .Where(k => k.IsAdditionOrRemoval())
                                .Select(k => k == PatchLineKind.Addition ? 1 : -1)
                                .Sum();

                    var newLength = oldLength + delta;

                    // Add header

                    var changes   = entry.Changes;
                    var oldPath   = changes.OldPath.Replace(@"\", "/");
                    var oldExists = oldLength != 0 || changes.OldMode != Mode.Nonexistent;
                    var path      = changes.Path.Replace(@"\", "/");

                    if (oldExists)
                    {
                        newPatch.AppendFormat("--- {0}\n", oldPath);
                    }
                    else
                    {
                        newPatch.AppendFormat("new file mode {0}\n", changes.Mode);
                        newPatch.Append("--- /dev/null\n");
                    }
                    newPatch.AppendFormat("+++ b/{0}\n", path);

                    // Write hunk header

                    newPatch.Append("@@ -");
                    newPatch.Append(oldStart);
                    if (oldLength != 1)
                    {
                        newPatch.Append(",");
                        newPatch.Append(oldLength);
                    }
                    newPatch.Append(" +");
                    newPatch.Append(newStart);
                    if (newLength != 1)
                    {
                        newPatch.Append(",");
                        newPatch.Append(newLength);
                    }
                    newPatch.Append(" @@");
                    newPatch.Append("\n");

                    // Write hunk

                    var previousIncluded = false;

                    for (var i = hunk.Offset; i < hunk.Offset + hunk.Length; i++)
                    {
                        var line = document.Lines[i];
                        var kind = line.Kind;
                        if (lineSet.Contains(i) ||
                            kind == PatchLineKind.Context ||
                            previousIncluded && kind == PatchLineKind.NoEndOfLine)
                        {
                            newPatch.Append(line.Text);
                            newPatch.Append("\n");
                            previousIncluded = true;
                        }
                        else if (!isUndo && kind == PatchLineKind.Removal ||
                                 isUndo && kind == PatchLineKind.Addition)
                        {
                            newPatch.Append(" ");
                            newPatch.Append(line.Text, 1, line.Text.Length - 1);
                            newPatch.Append("\n");
                            previousIncluded = true;
                        }
                        else
                        {
                            previousIncluded = false;
                        }
                    }
                }
            }

            return(newPatch.ToString());
        }
Пример #8
0
        public static string ComputePatch(PatchDocument document, IEnumerable<int> lineIndexes, PatchDirection direction)
        {
            var isUndo = direction == PatchDirection.Reset ||
                         direction == PatchDirection.Unstage;

            var newPatch = new StringBuilder();

            var entryLines = lineIndexes.Select(i => new {i, e = document.FindEntry(i)}).GroupBy(t => t.e, t => t.i);

            foreach (var entryLine in entryLines)
            {
                var entry = entryLine.Key;
                var hunkLines = entryLine.Select(i => new {i, h = entry.FindHunk(i)}).GroupBy(t => t.h, t => t.i);

                foreach (var hunkLine in hunkLines)
                {
                    var hunk = hunkLine.Key;
                    var lineSet = new HashSet<int>(hunkLine);

                    // Get current hunk information

                    var oldStart = hunk.OldStart;
                    var newStart = hunk.NewStart;

                    // Compute the new hunk size

                    var oldLength = 0;

                    for (var i = hunk.Offset; i < hunk.Offset + hunk.Length; i++)
                    {
                        var line = document.Lines[i];
                        var kind = line.Kind;

                        var wasPresent = kind == PatchLineKind.Context ||
                                         kind == PatchLineKind.Removal && (!isUndo || lineSet.Contains(i)) ||
                                         kind == PatchLineKind.Addition && (isUndo && !lineSet.Contains(i));

                        if (wasPresent)
                            oldLength++;
                    }

                    var delta = lineSet.Select(i => document.Lines[i])
                                       .Select(l => l.Kind)
                                       .Where(k => k.IsAdditionOrRemoval())
                                       .Select(k => k == PatchLineKind.Addition ? 1 : -1)
                                       .Sum();

                    var newLength = oldLength + delta;

                    // Add header

                    var changes = entry.Changes;
                    var oldPath = changes.OldPath.Replace(@"\", "/");
                    var oldExists = oldLength != 0 || changes.OldMode != Mode.Nonexistent;
                    var path = changes.Path.Replace(@"\", "/");

                    if (oldExists)
                    {
                        newPatch.AppendFormat("--- {0}\n", oldPath);
                    }
                    else
                    {
                        newPatch.AppendFormat("new file mode {0}\n", changes.Mode);
                        newPatch.Append("--- /dev/null\n");
                    }
                    newPatch.AppendFormat("+++ b/{0}\n", path);

                    // Write hunk header

                    newPatch.Append("@@ -");
                    newPatch.Append(oldStart);
                    if (oldLength != 1)
                    {
                        newPatch.Append(",");
                        newPatch.Append(oldLength);
                    }
                    newPatch.Append(" +");
                    newPatch.Append(newStart);
                    if (newLength != 1)
                    {
                        newPatch.Append(",");
                        newPatch.Append(newLength);
                    }
                    newPatch.Append(" @@");
                    newPatch.Append("\n");

                    // Write hunk

                    var previousIncluded = false;

                    for (var i = hunk.Offset; i < hunk.Offset + hunk.Length; i++)
                    {
                        var line = document.Lines[i];
                        var kind = line.Kind;
                        if (lineSet.Contains(i) ||
                            kind == PatchLineKind.Context ||
                            previousIncluded && kind == PatchLineKind.NoEndOfLine)
                        {
                            newPatch.Append(line.Text);
                            newPatch.Append("\n");
                            previousIncluded = true;
                        }
                        else if (!isUndo && kind == PatchLineKind.Removal ||
                                 isUndo && kind == PatchLineKind.Addition)
                        {
                            newPatch.Append(" ");
                            newPatch.Append(line.Text, 1, line.Text.Length - 1);
                            newPatch.Append("\n");
                            previousIncluded = true;
                        }
                        else
                        {
                            previousIncluded = false;
                        }
                    }
                }
            }

            return newPatch.ToString();
        }
Пример #9
0
        public static int FindNextEntryIndex(this PatchDocument document, int lineIndex)
        {
            var entryIndex = document.FindEntryIndex(lineIndex);

            return(Math.Min(entryIndex + 1, document.Entries.Count - 1));
        }
Пример #10
0
        public static int FindPreviousEntryIndex(this PatchDocument document, int lineIndex)
        {
            var entryIndex = document.FindEntryIndex(lineIndex);

            return(Math.Max(entryIndex - 1, 0));
        }