Split Patch and TreeChanges generation

Remove Patch from TreeChanges
Make repo.Diff.Compare() generic
This commit is contained in:
yorah 2013-09-16 13:55:18 +02:00
Родитель c5419f7be3
Коммит 11f4cb81f0
13 изменённых файлов: 494 добавлений и 289 удалений

Просмотреть файл

@ -43,9 +43,12 @@ namespace LibGit2Sharp.Tests
{
SetUpSimpleDiffContext(repo);
TreeChanges changes = repo.Diff.Compare(repo.Head.Tip.Tree,
var changes = repo.Diff.Compare<TreeChanges>(repo.Head.Tip.Tree,
DiffTargets.WorkingDirectory);
Assert.Equal(1, changes.Modified.Count());
var patch = repo.Diff.Compare<Patch>(repo.Head.Tip.Tree,
DiffTargets.WorkingDirectory);
var expected = new StringBuilder()
.Append("diff --git a/file.txt b/file.txt\n")
.Append("index ce01362..4f125e3 100644\n")
@ -56,7 +59,7 @@ namespace LibGit2Sharp.Tests
.Append("+world\n")
.Append("+!!!\n");
Assert.Equal(expected.ToString(), changes.Patch);
Assert.Equal(expected.ToString(), patch);
}
}
@ -67,7 +70,7 @@ namespace LibGit2Sharp.Tests
{
Tree tree = repo.Head.Tip.Tree;
TreeChanges changes = repo.Diff.Compare(tree, DiffTargets.WorkingDirectory);
var changes = repo.Diff.Compare<TreeChanges>(tree, DiffTargets.WorkingDirectory);
Assert.NotNull(changes);
Assert.Equal(6, changes.Count());
@ -103,9 +106,12 @@ namespace LibGit2Sharp.Tests
{
SetUpSimpleDiffContext(repo);
TreeChanges changes = repo.Diff.Compare(repo.Head.Tip.Tree,
var changes = repo.Diff.Compare<TreeChanges>(repo.Head.Tip.Tree,
DiffTargets.Index | DiffTargets.WorkingDirectory);
Assert.Equal(1, changes.Modified.Count());
var patch = repo.Diff.Compare<Patch>(repo.Head.Tip.Tree,
DiffTargets.Index | DiffTargets.WorkingDirectory);
var expected = new StringBuilder()
.Append("diff --git a/file.txt b/file.txt\n")
.Append("index ce01362..4f125e3 100644\n")
@ -116,7 +122,7 @@ namespace LibGit2Sharp.Tests
.Append("+world\n")
.Append("+!!!\n");
Assert.Equal(expected.ToString(), changes.Patch);
Assert.Equal(expected.ToString(), patch);
}
}
@ -158,8 +164,13 @@ namespace LibGit2Sharp.Tests
FileStatus state = repo.Index.RetrieveStatus("file.txt");
Assert.Equal(FileStatus.Removed | FileStatus.Untracked, state);
var wrkDirToIdxToTree = repo.Diff.Compare<TreeChanges>(repo.Head.Tip.Tree,
DiffTargets.Index | DiffTargets.WorkingDirectory);
TreeChanges wrkDirToIdxToTree = repo.Diff.Compare(repo.Head.Tip.Tree,
Assert.Equal(1, wrkDirToIdxToTree.Deleted.Count());
Assert.Equal(0, wrkDirToIdxToTree.Modified.Count());
var patch = repo.Diff.Compare<Patch>(repo.Head.Tip.Tree,
DiffTargets.Index | DiffTargets.WorkingDirectory);
var expected = new StringBuilder()
.Append("diff --git a/file.txt b/file.txt\n")
@ -170,9 +181,15 @@ namespace LibGit2Sharp.Tests
.Append("@@ -1 +0,0 @@\n")
.Append("-hello\n");
Assert.Equal(expected.ToString(), wrkDirToIdxToTree.Patch);
Assert.Equal(expected.ToString(), patch);
TreeChanges wrkDirToTree = repo.Diff.Compare(repo.Head.Tip.Tree,
var wrkDirToTree = repo.Diff.Compare<TreeChanges>(repo.Head.Tip.Tree,
DiffTargets.WorkingDirectory);
Assert.Equal(0, wrkDirToTree.Deleted.Count());
Assert.Equal(1, wrkDirToTree.Modified.Count());
patch = repo.Diff.Compare<Patch>(repo.Head.Tip.Tree,
DiffTargets.WorkingDirectory);
expected = new StringBuilder()
.Append("diff --git a/file.txt b/file.txt\n")
@ -184,7 +201,7 @@ namespace LibGit2Sharp.Tests
.Append("+world\n")
.Append("+!!!\n");
Assert.Equal(expected.ToString(), wrkDirToTree.Patch);
Assert.Equal(expected.ToString(), patch);
}
}
@ -207,9 +224,12 @@ namespace LibGit2Sharp.Tests
{
SetUpSimpleDiffContext(repo);
TreeChanges changes = repo.Diff.Compare(repo.Head.Tip.Tree,
var changes = repo.Diff.Compare<TreeChanges>(repo.Head.Tip.Tree,
DiffTargets.Index);
Assert.Equal(1, changes.Modified.Count());
var patch = repo.Diff.Compare<Patch>(repo.Head.Tip.Tree,
DiffTargets.Index);
var expected = new StringBuilder()
.Append("diff --git a/file.txt b/file.txt\n")
.Append("index ce01362..94954ab 100644\n")
@ -219,7 +239,7 @@ namespace LibGit2Sharp.Tests
.Append(" hello\n")
.Append("+world\n");
Assert.Equal(expected.ToString(), changes.Patch);
Assert.Equal(expected.ToString(), patch);
}
}
@ -254,7 +274,7 @@ namespace LibGit2Sharp.Tests
{
Tree tree = repo.Head.Tip.Tree;
TreeChanges changes = repo.Diff.Compare(tree, DiffTargets.Index);
var changes = repo.Diff.Compare<TreeChanges>(tree, DiffTargets.Index);
Assert.NotNull(changes);
Assert.Equal(3, changes.Count());
@ -281,7 +301,7 @@ namespace LibGit2Sharp.Tests
{
Tree tree = repo.Head.Tip.Tree;
TreeChanges changes = repo.Diff.Compare(tree, DiffTargets.Index,
var changes = repo.Diff.Compare<TreeChanges>(tree, DiffTargets.Index,
new[] { "deleted_staged_file.txt", "1/branch_file.txt" });
Assert.NotNull(changes);
@ -305,11 +325,11 @@ namespace LibGit2Sharp.Tests
{
Tree tree = repo.Head.Tip.Tree;
TreeChanges changes = repo.Diff.Compare(tree, DiffTargets.Index,
var changes = repo.Diff.Compare<TreeChanges>(tree, DiffTargets.Index,
new[] { "deleted_staged_file.txt", "1/branch_file.txt", "I-do/not-exist" }, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false });
AssertCanCompareASubsetOfTheTreeAgainstTheIndex(changes);
changes = repo.Diff.Compare(tree, DiffTargets.Index,
changes = repo.Diff.Compare<TreeChanges>(tree, DiffTargets.Index,
new[] { "deleted_staged_file.txt", "1/branch_file.txt", "I-do/not-exist" });
AssertCanCompareASubsetOfTheTreeAgainstTheIndex(changes);
}
@ -322,7 +342,7 @@ namespace LibGit2Sharp.Tests
{
Tree tree = repo.Head.Tip.Tree;
Assert.Throws<UnmatchedPathException>(() => repo.Diff.Compare(tree, DiffTargets.Index,
Assert.Throws<UnmatchedPathException>(() => repo.Diff.Compare<TreeChanges>(tree, DiffTargets.Index,
new[] { "deleted_staged_file.txt", "1/branch_file.txt", "I-do/not-exist" }, new ExplicitPathsOptions()));
}
}
@ -359,11 +379,10 @@ namespace LibGit2Sharp.Tests
File.AppendAllText(fullpath, "\n");
repo.Index.Stage("file.txt");
TreeChanges changes = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.Index);
var changes = repo.Diff.Compare<TreeChanges>(repo.Head.Tip.Tree, DiffTargets.Index);
Assert.Equal(1, changes.Modified.Count());
Assert.Equal(1, changes.LinesAdded);
Assert.Equal(1, changes.LinesDeleted);
var patch = repo.Diff.Compare<Patch>(repo.Head.Tip.Tree, DiffTargets.Index);
var expected = new StringBuilder()
.Append("diff --git a/file.txt b/file.txt\n")
.Append("index 2e65efe..7898192 100644\n")
@ -374,7 +393,9 @@ namespace LibGit2Sharp.Tests
.Append("\\ No newline at end of file\n")
.Append("+a\n");
Assert.Equal(expected.ToString(), changes.Patch);
Assert.Equal(expected.ToString(), patch);
Assert.Equal(1, patch.LinesAdded);
Assert.Equal(1, patch.LinesDeleted);
}
}
@ -384,11 +405,11 @@ namespace LibGit2Sharp.Tests
using (var repo = new Repository(BareTestRepoPath))
{
Assert.Throws<BareRepositoryException>(
() => repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.WorkingDirectory));
() => repo.Diff.Compare<TreeChanges>(repo.Head.Tip.Tree, DiffTargets.WorkingDirectory));
Assert.Throws<BareRepositoryException>(
() => repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.Index));
() => repo.Diff.Compare<TreeChanges>(repo.Head.Tip.Tree, DiffTargets.Index));
Assert.Throws<BareRepositoryException>(
() => repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.WorkingDirectory | DiffTargets.Index));
() => repo.Diff.Compare<TreeChanges>(repo.Head.Tip.Tree, DiffTargets.WorkingDirectory | DiffTargets.Index));
}
}
@ -401,14 +422,13 @@ namespace LibGit2Sharp.Tests
{
SetUpSimpleDiffContext(repo);
TreeChanges changes = repo.Diff.Compare(null,
var changes = repo.Diff.Compare<TreeChanges>(null,
DiffTargets.Index);
Assert.Equal(1, changes.Count());
Assert.Equal(1, changes.Added.Count());
Assert.Equal("file.txt", changes.Added.Single().Path);
Assert.Equal(2, changes.Added.Single().LinesAdded);
}
}
@ -421,14 +441,13 @@ namespace LibGit2Sharp.Tests
{
SetUpSimpleDiffContext(repo);
TreeChanges changes = repo.Diff.Compare(null,
var changes = repo.Diff.Compare<TreeChanges>(null,
DiffTargets.WorkingDirectory);
Assert.Equal(1, changes.Count());
Assert.Equal(1, changes.Added.Count());
Assert.Equal("file.txt", changes.Added.Single().Path);
Assert.Equal(3, changes.Added.Single().LinesAdded);
}
}
@ -441,14 +460,13 @@ namespace LibGit2Sharp.Tests
{
SetUpSimpleDiffContext(repo);
TreeChanges changes = repo.Diff.Compare(null,
var changes = repo.Diff.Compare<TreeChanges>(null,
DiffTargets.WorkingDirectory | DiffTargets.Index);
Assert.Equal(1, changes.Count());
Assert.Equal(1, changes.Added.Count());
Assert.Equal("file.txt", changes.Added.Single().Path);
Assert.Equal(3, changes.Added.Single().LinesAdded);
}
}
}

Просмотреть файл

@ -19,10 +19,12 @@ namespace LibGit2Sharp.Tests
{
Tree tree = repo.Head.Tip.Tree;
TreeChanges changes = repo.Diff.Compare(tree, tree);
var changes = repo.Diff.Compare<TreeChanges>(tree, tree);
var patch = repo.Diff.Compare<Patch>(tree, tree);
Assert.Empty(changes);
Assert.Equal(string.Empty, changes.Patch);
Assert.Empty(patch);
Assert.Equal(String.Empty, patch);
}
}
@ -33,7 +35,7 @@ namespace LibGit2Sharp.Tests
{
Tree tree = repo.Head.Tip.Tree;
TreeChanges changes = repo.Diff.Compare(tree, tree);
var changes = repo.Diff.Compare<TreeChanges>(tree, tree);
Assert.Null(changes["batman"]);
}
@ -52,19 +54,20 @@ namespace LibGit2Sharp.Tests
Tree commitTree = repo.Head.Tip.Tree;
Tree parentCommitTree = repo.Head.Tip.Parents.Single().Tree;
TreeChanges changes = repo.Diff.Compare(parentCommitTree, commitTree);
var changes = repo.Diff.Compare<TreeChanges>(parentCommitTree, commitTree);
Assert.Equal(1, changes.Count());
Assert.Equal(1, changes.Added.Count());
TreeEntryChanges treeEntryChanges = changes["1.txt"];
Assert.False(treeEntryChanges.IsBinaryComparison);
var patch = repo.Diff.Compare<Patch>(parentCommitTree, commitTree);
Assert.False(patch["1.txt"].IsBinaryComparison);
Assert.Equal("1.txt", treeEntryChanges.Path);
Assert.Equal(ChangeKind.Added, treeEntryChanges.Status);
Assert.Equal(treeEntryChanges, changes.Added.Single());
Assert.Equal(1, treeEntryChanges.LinesAdded);
Assert.Equal(Mode.Nonexistent, treeEntryChanges.OldMode);
}
@ -88,7 +91,7 @@ namespace LibGit2Sharp.Tests
Tree tree = repo.Head.Tip.Tree;
Tree ancestor = repo.Lookup<Commit>("9fd738e").Tree;
TreeChanges changes = repo.Diff.Compare(ancestor, tree, new[]{ "1" });
var changes = repo.Diff.Compare<TreeChanges>(ancestor, tree, new[] { "1" });
Assert.NotNull(changes);
Assert.Equal(1, changes.Count());
@ -118,7 +121,7 @@ namespace LibGit2Sharp.Tests
Tree commitTree = repo.Head.Tip.Tree;
Tree commitTreeWithDifferentAncestor = repo.Branches["refs/remotes/origin/test"].Tip.Tree;
TreeChanges changes = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree);
var changes = repo.Diff.Compare<TreeChanges>(commitTreeWithDifferentAncestor, commitTree);
Assert.Equal(10, changes.Count());
Assert.Equal(9, changes.Added.Count());
@ -128,9 +131,10 @@ namespace LibGit2Sharp.Tests
Assert.Equal(new[] { "1.txt", subBranchFilePath, "README", "branch_file.txt", "deleted_staged_file.txt", "deleted_unstaged_file.txt", "modified_staged_file.txt", "modified_unstaged_file.txt", "new.txt" },
changes.Added.Select(x => x.Path).OrderBy(p => p, StringComparer.Ordinal).ToArray());
Assert.Equal(9, changes.LinesAdded);
Assert.Equal(2, changes.LinesDeleted);
Assert.Equal(2, changes["readme.txt"].LinesDeleted);
var patch = repo.Diff.Compare<Patch>(commitTreeWithDifferentAncestor, commitTree);
Assert.Equal(9, patch.LinesAdded);
Assert.Equal(2, patch.LinesDeleted);
Assert.Equal(2, patch["readme.txt"].LinesDeleted);
}
}
@ -142,11 +146,11 @@ namespace LibGit2Sharp.Tests
Tree commitTree = repo.Head.Tip.Tree;
Tree commitTreeWithDifferentAncestor = repo.Branches["refs/remotes/origin/test"].Tip.Tree;
TreeChanges changes = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree,
var changes = repo.Diff.Compare<TreeChanges>(commitTreeWithDifferentAncestor, commitTree,
new[] { "if-I-exist-this-test-is-really-unlucky.txt" }, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false });
Assert.Equal(0, changes.Count());
changes = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree,
changes = repo.Diff.Compare<TreeChanges>(commitTreeWithDifferentAncestor, commitTree,
new[] { "if-I-exist-this-test-is-really-unlucky.txt" });
Assert.Equal(0, changes.Count());
}
@ -161,7 +165,7 @@ namespace LibGit2Sharp.Tests
Tree commitTreeWithDifferentAncestor = repo.Branches["refs/remotes/origin/test"].Tip.Tree;
Assert.Throws<UnmatchedPathException>(() =>
repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree,
repo.Diff.Compare<TreeChanges>(commitTreeWithDifferentAncestor, commitTree,
new[] { "if-I-exist-this-test-is-really-unlucky.txt" }, new ExplicitPathsOptions()));
}
}
@ -192,7 +196,7 @@ namespace LibGit2Sharp.Tests
Tree rootCommitTree = repo.Lookup<Commit>("f8d44d7").Tree;
Tree commitTreeWithRenamedFile = repo.Lookup<Commit>("4be51d6").Tree;
TreeChanges changes = repo.Diff.Compare(rootCommitTree, commitTreeWithRenamedFile);
var changes = repo.Diff.Compare<TreeChanges>(rootCommitTree, commitTreeWithRenamedFile);
Assert.Equal(1, changes.Count());
Assert.Equal("super-file.txt", changes["super-file.txt"].Path);
@ -236,18 +240,21 @@ namespace LibGit2Sharp.Tests
Tree rootCommitTree = repo.Lookup<Commit>("f8d44d7").Tree;
Tree commitTreeWithUpdatedFile = repo.Lookup<Commit>("ec9e401").Tree;
TreeChanges changes = repo.Diff.Compare(rootCommitTree, commitTreeWithUpdatedFile,
compareOptions: new CompareOptions { ContextLines = contextLines });
var changes = repo.Diff.Compare<TreeChanges>(rootCommitTree, commitTreeWithUpdatedFile);
Assert.Equal(1, changes.Count());
Assert.Equal(1, changes.Modified.Count());
Assert.Equal(expectedPatchLength, changes.Patch.Length);
TreeEntryChanges treeEntryChanges = changes.Modified.Single();
var patch = repo.Diff.Compare<Patch>(rootCommitTree, commitTreeWithUpdatedFile,
compareOptions: new CompareOptions { ContextLines = contextLines });
Assert.Equal(2, treeEntryChanges.LinesAdded);
Assert.Equal(1, treeEntryChanges.LinesDeleted);
Assert.Equal(expectedPatchLength, treeEntryChanges.Patch.Length);
Assert.Equal(expectedPatchLength, patch.Content.Length);
ContentChanges contentChanges = patch["numbers.txt"];
Assert.Equal(2, contentChanges.LinesAdded);
Assert.Equal(1, contentChanges.LinesDeleted);
Assert.Equal(expectedPatchLength, contentChanges.Patch.Length);
}
}
@ -326,23 +333,25 @@ namespace LibGit2Sharp.Tests
Tree rootCommitTree = repo.Lookup<Commit>("f8d44d7").Tree;
Tree mergedCommitTree = repo.Lookup<Commit>("7252fe2").Tree;
TreeChanges changes = repo.Diff.Compare(rootCommitTree, mergedCommitTree, compareOptions: compareOptions);
var changes = repo.Diff.Compare<TreeChanges>(rootCommitTree, mergedCommitTree);
Assert.Equal(3, changes.Count());
Assert.Equal(1, changes.Modified.Count());
Assert.Equal(1, changes.Deleted.Count());
Assert.Equal(1, changes.Added.Count());
TreeEntryChanges treeEntryChanges = changes["numbers.txt"];
Assert.Equal(3, treeEntryChanges.LinesAdded);
Assert.Equal(1, treeEntryChanges.LinesDeleted);
Assert.Equal(Mode.Nonexistent, changes["my-name-does-not-feel-right.txt"].Mode);
var patch = repo.Diff.Compare<Patch>(rootCommitTree, mergedCommitTree, compareOptions: compareOptions);
ContentChanges contentChanges = patch["numbers.txt"];
Assert.Equal(3, contentChanges.LinesAdded);
Assert.Equal(1, contentChanges.LinesDeleted);
Assert.Equal(Expected("f8d44d7...7252fe2/numbers.txt-{0}-{1}.diff", contextLines, interhunkLines),
treeEntryChanges.Patch);
contentChanges.Patch);
Assert.Equal(Expected("f8d44d7...7252fe2/full-{0}-{1}.diff", contextLines, interhunkLines),
changes.Patch);
patch);
}
}
@ -369,7 +378,7 @@ namespace LibGit2Sharp.Tests
Tree treeNew = repo.ObjectDatabase.CreateTree(tdNew);
TreeChanges changes = repo.Diff.Compare(treeOld, treeNew);
var changes = repo.Diff.Compare<TreeChanges>(treeOld, treeNew);
/*
* $ git diff-tree -p 5c87b67 d5278d0
@ -416,14 +425,14 @@ namespace LibGit2Sharp.Tests
{
Tree tree = repo.Branches["refs/remotes/origin/test"].Tip.Tree;
TreeChanges changes = repo.Diff.Compare(tree, null);
var changes = repo.Diff.Compare<TreeChanges>(tree, null);
Assert.Equal(1, changes.Count());
Assert.Equal(1, changes.Deleted.Count());
Assert.Equal("readme.txt", changes.Deleted.Single().Path);
changes = repo.Diff.Compare(null, tree);
changes = repo.Diff.Compare<TreeChanges>(null, tree);
Assert.Equal(1, changes.Count());
Assert.Equal(1, changes.Added.Count());
@ -437,7 +446,7 @@ namespace LibGit2Sharp.Tests
{
using (var repo = new Repository(StandardTestRepoPath))
{
TreeChanges changes = repo.Diff.Compare(default(Tree), default(Tree));
var changes = repo.Diff.Compare<TreeChanges>(default(Tree), default(Tree));
Assert.Equal(0, changes.Count());
}
@ -460,7 +469,7 @@ namespace LibGit2Sharp.Tests
File.WriteAllBytes(fullpath, ((Blob)(entry.Target)).Content);
// Unset the local core.filemode, if any.
repo.Config.Unset("core.filemode", ConfigurationLevel.Local);
repo.Config.Unset("core.filemode");
}
SelfCleaningDirectory scd = BuildSelfCleaningDirectory();
@ -469,7 +478,7 @@ namespace LibGit2Sharp.Tests
using (var repo = new Repository(path, options))
{
TreeChanges changes = repo.Diff.Compare(new []{ file });
var changes = repo.Diff.Compare<TreeChanges>(new[] { file });
Assert.Equal(1, changes.Count());
@ -482,7 +491,7 @@ namespace LibGit2Sharp.Tests
using (var repo = new Repository(path, options))
{
TreeChanges changes = repo.Diff.Compare(new[] { file });
var changes = repo.Diff.Compare<TreeChanges>(new[] { file });
Assert.Equal(0, changes.Count());
}
@ -535,11 +544,21 @@ namespace LibGit2Sharp.Tests
using (var repo = new Repository(repoPath))
{
var changes = repo.Diff.Compare(repo.Lookup<Tree>(treeOldOid), repo.Lookup<Tree>(treeNewOid));
var changes = repo.Diff.Compare<TreeChanges>(repo.Lookup<Tree>(treeOldOid), repo.Lookup<Tree>(treeNewOid));
Assert.Equal(ChangeKind.Modified, changes["a.txt"].Status);
Assert.Equal(ChangeKind.Modified, changes["A.TXT"].Status);
}
}
[Fact]
public void CallingCompareWithAnUnsupportedGenericParamThrows()
{
using (var repo = new Repository(StandardTestRepoPath))
{
Assert.Throws<LibGit2SharpException>(() => repo.Diff.Compare<string>(default(Tree), default(Tree)));
Assert.Throws<LibGit2SharpException>(() => repo.Diff.Compare<string>());
}
}
}
}

Просмотреть файл

@ -32,7 +32,7 @@ namespace LibGit2Sharp.Tests
{
using (var repo = new Repository(StandardTestRepoPath))
{
TreeChanges changes = repo.Diff.Compare();
var changes = repo.Diff.Compare<TreeChanges>();
Assert.Equal(2, changes.Count());
Assert.Equal("deleted_unstaged_file.txt", changes.Deleted.Single().Path);
@ -49,10 +49,10 @@ namespace LibGit2Sharp.Tests
{
Assert.Equal(currentStatus, repo.Index.RetrieveStatus(relativePath));
TreeChanges changes = repo.Diff.Compare(new[] { relativePath }, false, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false });
var changes = repo.Diff.Compare<TreeChanges>(new[] { relativePath }, false, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false });
Assert.Equal(0, changes.Count());
changes = repo.Diff.Compare(new[] { relativePath });
changes = repo.Diff.Compare<TreeChanges>(new[] { relativePath });
Assert.Equal(0, changes.Count());
}
}
@ -66,7 +66,7 @@ namespace LibGit2Sharp.Tests
{
Assert.Equal(currentStatus, repo.Index.RetrieveStatus(relativePath));
Assert.Throws<UnmatchedPathException>(() => repo.Diff.Compare(new[] { relativePath }, false, new ExplicitPathsOptions()));
Assert.Throws<UnmatchedPathException>(() => repo.Diff.Compare<TreeChanges>(new[] { relativePath }, false, new ExplicitPathsOptions()));
}
}
@ -81,7 +81,9 @@ namespace LibGit2Sharp.Tests
{
Assert.Equal(currentStatus, repo.Index.RetrieveStatus(relativePath));
repo.Diff.Compare(new[] { relativePath }, false, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false,
repo.Diff.Compare<TreeChanges>(new[] { relativePath }, false, new ExplicitPathsOptions
{
ShouldFailOnUnmatchedPath = false,
OnUnmatchedPath = callback.OnUnmatchedPath });
Assert.True(callback.WasCalled);
@ -124,7 +126,7 @@ namespace LibGit2Sharp.Tests
using (var repo = new Repository(path, options))
{
TreeChanges changes = repo.Diff.Compare(new[] { file });
var changes = repo.Diff.Compare<TreeChanges>(new[] { file });
Assert.Equal(1, changes.Count());
@ -137,7 +139,7 @@ namespace LibGit2Sharp.Tests
using (var repo = new Repository(path, options))
{
TreeChanges changes = repo.Diff.Compare(new[] { file });
var changes = repo.Diff.Compare<TreeChanges>(new[] { file });
Assert.Equal(0, changes.Count());
}
@ -168,7 +170,7 @@ namespace LibGit2Sharp.Tests
{
using (var repo = new Repository(StandardTestRepoPath))
{
TreeChanges changes = repo.Diff.Compare(null, true);
var changes = repo.Diff.Compare<TreeChanges>(null, true);
Assert.Equal(3, changes.Count());
Assert.Equal("deleted_unstaged_file.txt", changes.Deleted.Single().Path);

Просмотреть файл

@ -1,52 +0,0 @@
using System.Diagnostics;
using System.Globalization;
using System.Text;
namespace LibGit2Sharp
{
/// <summary>
/// Base class for changes.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public abstract class Changes
{
private readonly StringBuilder patchBuilder = new StringBuilder();
internal void AppendToPatch(string patch)
{
patchBuilder.Append(patch);
}
/// <summary>
/// The number of lines added.
/// </summary>
public virtual int LinesAdded { get; internal set; }
/// <summary>
/// The number of lines deleted.
/// </summary>
public virtual int LinesDeleted { get; internal set; }
/// <summary>
/// The patch corresponding to these changes.
/// </summary>
public virtual string Patch
{
get { return patchBuilder.ToString(); }
}
/// <summary>
/// Determines if at least one side of the comparison holds binary content.
/// </summary>
public virtual bool IsBinaryComparison { get; protected set; }
private string DebuggerDisplay
{
get
{
return string.Format(CultureInfo.InvariantCulture,
@"{{+{0}, -{1}}}", LinesAdded, LinesDeleted);
}
}
}
}

Просмотреть файл

@ -12,7 +12,6 @@ namespace LibGit2Sharp
{
ContextLines = 3;
InterhunkLines = 0;
SkipPatchBuilding = false;
}
/// <summary>
@ -26,11 +25,5 @@ namespace LibGit2Sharp
/// (Default = 0)
/// </summary>
public int InterhunkLines { get; set; }
/// <summary>
/// Flag to skip patch building. May be used if only file name and status required.
/// (Default = false)
/// </summary>
internal bool SkipPatchBuilding { get; set; }
}
}

Просмотреть файл

@ -1,4 +1,6 @@
using System;
using System.Diagnostics;
using System.Globalization;
using System.Text;
using LibGit2Sharp.Core;
@ -7,8 +9,12 @@ namespace LibGit2Sharp
/// <summary>
/// Holds the changes between two <see cref="Blob"/>s.
/// </summary>
public class ContentChanges : Changes
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class ContentChanges
{
private readonly StringBuilder patchBuilder = new StringBuilder();
private bool isBinaryComparison;
/// <summary>
/// Needed for mocking purposes.
/// </summary>
@ -23,6 +29,43 @@ namespace LibGit2Sharp
options, FileCallback, HunkCallback, LineCallback);
}
internal ContentChanges(bool isBinaryComparison)
{
this.isBinaryComparison = isBinaryComparison;
}
internal void AppendToPatch(string patch)
{
patchBuilder.Append(patch);
}
/// <summary>
/// The number of lines added.
/// </summary>
public virtual int LinesAdded { get; internal set; }
/// <summary>
/// The number of lines deleted.
/// </summary>
public virtual int LinesDeleted { get; internal set; }
/// <summary>
/// The patch corresponding to these changes.
/// </summary>
public virtual string Patch
{
get { return patchBuilder.ToString(); }
}
/// <summary>
/// Determines if at least one side of the comparison holds binary content.
/// </summary>
public virtual bool IsBinaryComparison
{
get { return isBinaryComparison; }
private set { isBinaryComparison = value; }
}
private int FileCallback(GitDiffDelta delta, float progress, IntPtr payload)
{
IsBinaryComparison = delta.IsBinary();
@ -76,5 +119,14 @@ namespace LibGit2Sharp
AppendToPatch(decodedContent);
return 0;
}
private string DebuggerDisplay
{
get
{
return string.Format(CultureInfo.InvariantCulture,
@"{{+{0}, -{1}}}", LinesAdded, LinesDeleted);
}
}
}
}

Просмотреть файл

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using LibGit2Sharp.Core;
@ -77,39 +78,24 @@ namespace LibGit2Sharp
this.repo = repo;
}
/// <summary>
/// Show changes between two <see cref="Tree"/>s.
/// </summary>
/// <param name="oldTree">The <see cref="Tree"/> you want to compare from.</param>
/// <param name="newTree">The <see cref="Tree"/> you want to compare to.</param>
/// <param name="paths">The list of paths (either files or directories) that should be compared.</param>
/// <param name="explicitPathsOptions">
/// If set, the passed <paramref name="paths"/> will be treated as explicit paths.
/// Use these options to determine how unmatched explicit paths should be handled.
/// </param>
/// <param name="compareOptions">Additional options to define comparison behavior.</param>
/// <returns>A <see cref="TreeChanges"/> containing the changes between the <paramref name="oldTree"/> and the <paramref name="newTree"/>.</returns>
public virtual TreeChanges Compare(Tree oldTree, Tree newTree, IEnumerable<string> paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null)
private static readonly IDictionary<DiffTargets, Func<Repository, TreeComparisonHandleRetriever>> HandleRetrieverDispatcher = BuildHandleRetrieverDispatcher();
private static IDictionary<DiffTargets, Func<Repository, TreeComparisonHandleRetriever>> BuildHandleRetrieverDispatcher()
{
var comparer = TreeToTree(repo);
ObjectId oldTreeId = oldTree != null ? oldTree.Id : null;
ObjectId newTreeId = newTree != null ? newTree.Id : null;
var diffOptions = DiffModifiers.None;
if (explicitPathsOptions != null)
{
diffOptions |= DiffModifiers.DisablePathspecMatch;
if (explicitPathsOptions.ShouldFailOnUnmatchedPath ||
explicitPathsOptions.OnUnmatchedPath != null)
{
diffOptions |= DiffModifiers.IncludeUnmodified;
}
}
return BuildTreeChangesFromComparer(oldTreeId, newTreeId, comparer, diffOptions, paths, explicitPathsOptions, compareOptions);
return new Dictionary<DiffTargets, Func<Repository, TreeComparisonHandleRetriever>>
{
{ DiffTargets.Index, IndexToTree },
{ DiffTargets.WorkingDirectory, WorkdirToTree },
{ DiffTargets.Index | DiffTargets.WorkingDirectory, WorkdirAndIndexToTree },
};
}
private static readonly IDictionary<Type, Func<DiffListSafeHandle, object>> ChangesBuilders = new Dictionary<Type, Func<DiffListSafeHandle, object>>
{
{ typeof(Patch), diff => new Patch(diff) },
{ typeof(TreeChanges), diff => new TreeChanges(diff) },
};
/// <summary>
/// Show changes between two <see cref="Blob"/>s.
/// </summary>
@ -125,37 +111,34 @@ namespace LibGit2Sharp
}
}
private readonly IDictionary<DiffTargets, Func<Repository, TreeComparisonHandleRetriever>> handleRetrieverDispatcher = BuildHandleRetrieverDispatcher();
private static IDictionary<DiffTargets, Func<Repository, TreeComparisonHandleRetriever>> BuildHandleRetrieverDispatcher()
{
return new Dictionary<DiffTargets, Func<Repository, TreeComparisonHandleRetriever>>
{
{ DiffTargets.Index, IndexToTree },
{ DiffTargets.WorkingDirectory, WorkdirToTree },
{ DiffTargets.Index | DiffTargets.WorkingDirectory, WorkdirAndIndexToTree },
};
}
/// <summary>
/// Show changes between a <see cref="Tree"/> and the Index, the Working Directory, or both.
/// Show changes between two <see cref="Tree"/>s.
/// </summary>
/// <param name="oldTree">The <see cref="Tree"/> to compare from.</param>
/// <param name="diffTargets">The targets to compare to.</param>
/// <param name="oldTree">The <see cref="Tree"/> you want to compare from.</param>
/// <param name="newTree">The <see cref="Tree"/> you want to compare to.</param>
/// <param name="paths">The list of paths (either files or directories) that should be compared.</param>
/// <param name="explicitPathsOptions">
/// If set, the passed <paramref name="paths"/> will be treated as explicit paths.
/// Use these options to determine how unmatched explicit paths should be handled.
/// </param>
/// <param name="compareOptions">Additional options to define comparison behavior.</param>
/// <returns>A <see cref="TreeChanges"/> containing the changes between the <see cref="Tree"/> and the selected target.</returns>
public virtual TreeChanges Compare(Tree oldTree, DiffTargets diffTargets, IEnumerable<string> paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null)
/// <param name="compareOptions">Additional options to define patch generation behavior.</param>
/// <returns>A <see cref="TreeChanges"/> containing the changes between the <paramref name="oldTree"/> and the <paramref name="newTree"/>.</returns>
public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> paths = null, ExplicitPathsOptions explicitPathsOptions = null,
CompareOptions compareOptions = null) where T : class
{
var comparer = handleRetrieverDispatcher[diffTargets](repo);
ObjectId oldTreeId = oldTree != null ? oldTree.Id : null;
Func<DiffListSafeHandle, object> builder;
DiffModifiers diffOptions = diffTargets.HasFlag(DiffTargets.WorkingDirectory) ?
DiffModifiers.IncludeUntracked : DiffModifiers.None;
if (!ChangesBuilders.TryGetValue(typeof (T), out builder))
{
throw new LibGit2SharpException(string.Format(CultureInfo.InvariantCulture,
"Unexpected type '{0}' passed to Compare. Supported values are either '{1}' or '{2}'.", typeof (T),
typeof (TreeChanges), typeof (Patch)));
}
var comparer = TreeToTree(repo);
ObjectId oldTreeId = oldTree != null ? oldTree.Id : null;
ObjectId newTreeId = newTree != null ? newTree.Id : null;
var diffOptions = DiffModifiers.None;
if (explicitPathsOptions != null)
{
@ -168,11 +151,74 @@ namespace LibGit2Sharp
}
}
return BuildTreeChangesFromComparer(oldTreeId, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions);
using (DiffListSafeHandle diffList = BuildDiffList(oldTreeId, newTreeId, comparer,
diffOptions, paths, explicitPathsOptions, compareOptions))
{
return (T)builder(diffList);
}
}
/// <summary>
/// Show changes between a <see cref="Tree"/> and the Index, the Working Directory, or both.
/// <para>
/// The level of diff performed can be specified by passing either a <see cref="TreeChanges"/>
/// or <see cref="Patch"/> type as the generic parameter.
/// </para>
/// </summary>
/// <param name="oldTree">The <see cref="Tree"/> to compare from.</param>
/// <param name="diffTargets">The targets to compare to.</param>
/// <param name="paths">The list of paths (either files or directories) that should be compared.</param>
/// <param name="explicitPathsOptions">
/// If set, the passed <paramref name="paths"/> will be treated as explicit paths.
/// Use these options to determine how unmatched explicit paths should be handled.
/// </param>
/// <param name="compareOptions">Additional options to define patch generation behavior.</param>
/// <typeparam name="T">Can be either a <see cref="TreeChanges"/> if you are only interested in the list of files modified, added, ..., or
/// a <see cref="Patch"/> if you want the actual patch content for the whole diff and for individual files.</typeparam>
/// <returns>A <typeparamref name="T"/> containing the changes between the <see cref="Tree"/> and the selected target.</returns>
public virtual T Compare<T>(Tree oldTree, DiffTargets diffTargets, IEnumerable<string> paths = null,
ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) where T : class
{
Func<DiffListSafeHandle, object> builder;
if (!ChangesBuilders.TryGetValue(typeof (T), out builder))
{
throw new LibGit2SharpException(string.Format(CultureInfo.InvariantCulture,
"Unexpected type '{0}' passed to Compare. Supported values are either '{1}' or '{2}'.", typeof (T),
typeof (TreeChanges), typeof (Patch)));
}
var comparer = HandleRetrieverDispatcher[diffTargets](repo);
ObjectId oldTreeId = oldTree != null ? oldTree.Id : null;
DiffModifiers diffOptions = diffTargets.HasFlag(DiffTargets.WorkingDirectory)
? DiffModifiers.IncludeUntracked
: DiffModifiers.None;
if (explicitPathsOptions != null)
{
diffOptions |= DiffModifiers.DisablePathspecMatch;
if (explicitPathsOptions.ShouldFailOnUnmatchedPath ||
explicitPathsOptions.OnUnmatchedPath != null)
{
diffOptions |= DiffModifiers.IncludeUnmodified;
}
}
using (DiffListSafeHandle diffList = BuildDiffList(oldTreeId, null, comparer,
diffOptions, paths, explicitPathsOptions, compareOptions))
{
return (T)builder(diffList);
}
}
/// <summary>
/// Show changes between the working directory and the index.
/// <para>
/// The level of diff performed can be specified by passing either a <see cref="TreeChanges"/>
/// or <see cref="Patch"/> type as the generic parameter.
/// </para>
/// </summary>
/// <param name="paths">The list of paths (either files or directories) that should be compared.</param>
/// <param name="includeUntracked">If true, include untracked files from the working dir as additions. Otherwise ignore them.</param>
@ -180,16 +226,28 @@ namespace LibGit2Sharp
/// If set, the passed <paramref name="paths"/> will be treated as explicit paths.
/// Use these options to determine how unmatched explicit paths should be handled.
/// </param>
/// <param name="compareOptions">Additional options to define comparison behavior.</param>
/// <returns>A <see cref="TreeChanges"/> containing the changes between the working directory and the index.</returns>
public virtual TreeChanges Compare(IEnumerable<string> paths = null, bool includeUntracked = false, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null)
/// <param name="compareOptions">Additional options to define patch generation behavior.</param>
/// <typeparam name="T">Can be either a <see cref="TreeChanges"/> if you are only interested in the list of files modified, added, ..., or
/// a <see cref="Patch"/> if you want the actual patch content for the whole diff and for individual files.</typeparam>
/// <returns>A <typeparamref name="T"/> containing the changes between the working directory and the index.</returns>
public virtual T Compare<T>(IEnumerable<string> paths = null, bool includeUntracked = false, ExplicitPathsOptions explicitPathsOptions = null,
CompareOptions compareOptions = null) where T : class
{
return Compare(includeUntracked ? DiffModifiers.IncludeUntracked : DiffModifiers.None, paths, explicitPathsOptions, compareOptions);
return Compare<T>(includeUntracked ? DiffModifiers.IncludeUntracked : DiffModifiers.None, paths, explicitPathsOptions);
}
internal virtual TreeChanges Compare(DiffModifiers diffOptions, IEnumerable<string> paths = null,
ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null)
internal virtual T Compare<T>(DiffModifiers diffOptions, IEnumerable<string> paths = null,
ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) where T : class
{
Func<DiffListSafeHandle, object> builder;
if (!ChangesBuilders.TryGetValue(typeof (T), out builder))
{
throw new LibGit2SharpException(string.Format(CultureInfo.InvariantCulture,
"Unexpected type '{0}' passed to Compare. Supported values are either '{1}' or '{2}'.", typeof (T),
typeof (TreeChanges), typeof (Patch)));
}
var comparer = WorkdirToIndex(repo);
if (explicitPathsOptions != null)
@ -203,10 +261,14 @@ namespace LibGit2Sharp
}
}
return BuildTreeChangesFromComparer(null, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions);
using (DiffListSafeHandle diffList = BuildDiffList(null, null, comparer,
diffOptions, paths, explicitPathsOptions, compareOptions))
{
return (T)builder(diffList);
}
}
private delegate DiffListSafeHandle TreeComparisonHandleRetriever(ObjectId oldTreeId, ObjectId newTreeId, GitDiffOptions options);
internal delegate DiffListSafeHandle TreeComparisonHandleRetriever(ObjectId oldTreeId, ObjectId newTreeId, GitDiffOptions options);
private static TreeComparisonHandleRetriever TreeToTree(Repository repo)
{
@ -256,23 +318,31 @@ namespace LibGit2Sharp
return (oh, nh, o) => Proxy.git_diff_tree_to_index(repo.Handle, repo.Index.Handle, oh, o);
}
private TreeChanges BuildTreeChangesFromComparer(
ObjectId oldTreeId, ObjectId newTreeId, TreeComparisonHandleRetriever comparisonHandleRetriever,
DiffModifiers diffOptions, IEnumerable<string> paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null)
private DiffListSafeHandle BuildDiffList(ObjectId oldTreeId, ObjectId newTreeId, TreeComparisonHandleRetriever comparisonHandleRetriever,
DiffModifiers diffOptions, IEnumerable<string> paths, ExplicitPathsOptions explicitPathsOptions,
CompareOptions compareOptions)
{
var matchedPaths = new MatchedPathsAggregator();
var filePaths = repo.ToFilePaths(paths);
using (GitDiffOptions options = BuildOptions(diffOptions, filePaths, matchedPaths, compareOptions))
using (DiffListSafeHandle diffList = comparisonHandleRetriever(oldTreeId, newTreeId, options))
{
if (explicitPathsOptions != null)
var diffList = comparisonHandleRetriever(oldTreeId, newTreeId, options);
try
{
DispatchUnmatchedPaths(explicitPathsOptions, filePaths, matchedPaths);
if (explicitPathsOptions != null)
{
DispatchUnmatchedPaths(explicitPathsOptions, filePaths, matchedPaths);
}
}
catch
{
diffList.Dispose();
throw;
}
bool skipPatchBuilding = (compareOptions != null) && compareOptions.SkipPatchBuilding;
return new TreeChanges(diffList, skipPatchBuilding);
return diffList;
}
}

Просмотреть файл

@ -156,8 +156,7 @@ namespace LibGit2Sharp
{
Ensure.ArgumentNotNull(paths, "paths");
var compareOptions = new CompareOptions { SkipPatchBuilding = true };
TreeChanges changes = repo.Diff.Compare(DiffModifiers.IncludeUntracked | DiffModifiers.IncludeIgnored, paths, explicitPathsOptions, compareOptions);
var changes = repo.Diff.Compare<TreeChanges>(DiffModifiers.IncludeUntracked | DiffModifiers.IncludeIgnored, paths, explicitPathsOptions);
foreach (var treeEntryChanges in changes)
{
@ -214,8 +213,7 @@ namespace LibGit2Sharp
if (repo.Info.IsHeadUnborn)
{
var compareOptions = new CompareOptions { SkipPatchBuilding = true };
TreeChanges changes = repo.Diff.Compare(null, DiffTargets.Index, paths, explicitPathsOptions, compareOptions);
var changes = repo.Diff.Compare<TreeChanges>(null, DiffTargets.Index, paths, explicitPathsOptions);
Reset(changes);
}
@ -350,8 +348,7 @@ namespace LibGit2Sharp
public virtual void Remove(IEnumerable<string> paths, bool removeFromWorkingDirectory = true, ExplicitPathsOptions explicitPathsOptions = null)
{
var pathsList = paths.ToList();
var compareOptions = new CompareOptions { SkipPatchBuilding = true };
TreeChanges changes = repo.Diff.Compare(DiffModifiers.IncludeUnmodified | DiffModifiers.IncludeUntracked, pathsList, explicitPathsOptions, compareOptions);
var changes = repo.Diff.Compare<TreeChanges>(DiffModifiers.IncludeUnmodified | DiffModifiers.IncludeUntracked, pathsList, explicitPathsOptions);
var pathsTodelete = pathsList.Where(p => Directory.Exists(Path.Combine(repo.Info.WorkingDirectory, p))).ToList();

Просмотреть файл

@ -64,7 +64,6 @@
<Compile Include="BranchCollectionExtensions.cs" />
<Compile Include="BranchTrackingDetails.cs" />
<Compile Include="BranchUpdater.cs" />
<Compile Include="Changes.cs" />
<Compile Include="CheckoutCallbacks.cs" />
<Compile Include="CheckoutModifiers.cs" />
<Compile Include="CheckoutNotificationOptions.cs" />
@ -83,6 +82,7 @@
<Compile Include="DiffModifiers.cs" />
<Compile Include="ObjectType.cs" />
<Compile Include="Core\UniqueIdentifier.cs" />
<Compile Include="Patch.cs" />
<Compile Include="ReferenceExtensions.cs" />
<Compile Include="Conflict.cs" />
<Compile Include="ConflictCollection.cs" />

176
LibGit2Sharp/Patch.cs Normal file
Просмотреть файл

@ -0,0 +1,176 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Text;
using LibGit2Sharp.Core;
using LibGit2Sharp.Core.Handles;
namespace LibGit2Sharp
{
/// <summary>
/// Holds the patch between two trees.
/// <para>The individual patches for each file can be accessed through the indexer of this class.</para>
/// <para>Building a patch is an expensive operation. If you only need to know which files have been added,
/// deleted, modified, ..., then consider using a simpler <see cref="TreeChanges"/>.</para>
/// </summary>
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class Patch : IEnumerable<ContentChanges>
{
private readonly StringBuilder fullPatchBuilder = new StringBuilder();
private readonly IDictionary<FilePath, ContentChanges> changes = new Dictionary<FilePath, ContentChanges>();
private int linesAdded;
private int linesDeleted;
/// <summary>
/// Needed for mocking purposes.
/// </summary>
protected Patch()
{ }
internal Patch(DiffListSafeHandle diff)
{
Proxy.git_diff_foreach(diff, FileCallback, null, DataCallback);
Proxy.git_diff_print_patch(diff, PrintCallBack);
}
private int FileCallback(GitDiffDelta delta, float progress, IntPtr payload)
{
AddFileChange(delta);
return 0;
}
private void AddFileChange(GitDiffDelta delta)
{
var newFilePath = FilePathMarshaler.FromNative(delta.NewFile.Path);
changes.Add(newFilePath, new ContentChanges(delta.IsBinary()));
}
private int DataCallback(GitDiffDelta delta, GitDiffRange range, GitDiffLineOrigin lineOrigin, IntPtr content,
UIntPtr contentLen, IntPtr payload)
{
var filePath = FilePathMarshaler.FromNative(delta.NewFile.Path);
AddLineChange(this[filePath], lineOrigin);
return 0;
}
private void AddLineChange(ContentChanges currentChange, GitDiffLineOrigin lineOrigin)
{
switch (lineOrigin)
{
case GitDiffLineOrigin.GIT_DIFF_LINE_ADDITION:
linesAdded++;
currentChange.LinesAdded++;
break;
case GitDiffLineOrigin.GIT_DIFF_LINE_DELETION:
linesDeleted++;
currentChange.LinesDeleted++;
break;
}
}
private int PrintCallBack(GitDiffDelta delta, GitDiffRange range, GitDiffLineOrigin lineorigin, IntPtr content, UIntPtr contentlen, IntPtr payload)
{
string formattedoutput = Utf8Marshaler.FromNative(content, (int)contentlen);
var filePath = FilePathMarshaler.FromNative(delta.NewFile.Path);
fullPatchBuilder.Append(formattedoutput);
this[filePath].AppendToPatch(formattedoutput);
return 0;
}
#region IEnumerable<ContentChanges> Members
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>An <see cref="IEnumerator{T}"/> object that can be used to iterate through the collection.</returns>
public virtual IEnumerator<ContentChanges> GetEnumerator()
{
return changes.Values.GetEnumerator();
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>An <see cref="IEnumerator"/> object that can be used to iterate through the collection.</returns>
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
/// <summary>
/// Gets the <see cref="ContentChanges"/> corresponding to the specified <paramref name="path"/>.
/// </summary>
public virtual ContentChanges this[string path]
{
get { return this[(FilePath)path]; }
}
private ContentChanges this[FilePath path]
{
get
{
ContentChanges contentChanges;
if (changes.TryGetValue(path, out contentChanges))
{
return contentChanges;
}
return null;
}
}
/// <summary>
/// The total number of lines added in this diff.
/// </summary>
public virtual int LinesAdded
{
get { return linesAdded; }
}
/// <summary>
/// The total number of lines added in this diff.
/// </summary>
public virtual int LinesDeleted
{
get { return linesDeleted; }
}
/// <summary>
/// The full patch file of this diff.
/// </summary>
public virtual string Content
{
get { return fullPatchBuilder.ToString(); }
}
/// <summary>
/// Implicit operator for string conversion.
/// </summary>
/// <param name="patch"><see cref="Patch"/>.</param>
/// <returns>The patch content as string.</returns>
public static implicit operator string(Patch patch)
{
return patch.fullPatchBuilder.ToString();
}
private string DebuggerDisplay
{
get
{
return string.Format(CultureInfo.InvariantCulture,
"+{0} -{1}", linesAdded, linesDeleted);
}
}
}
}

Просмотреть файл

@ -841,7 +841,7 @@ namespace LibGit2Sharp
Ensure.ArgumentNotNull(commit, "commit");
TreeChanges changes = Diff.Compare(commit.Tree, DiffTargets.Index, paths, explicitPathsOptions);
var changes = Diff.Compare<TreeChanges>(commit.Tree, DiffTargets.Index, paths, explicitPathsOptions);
Index.Reset(changes);
}

Просмотреть файл

@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
using LibGit2Sharp.Core;
using LibGit2Sharp.Core.Handles;
@ -13,6 +12,7 @@ namespace LibGit2Sharp
/// <summary>
/// Holds the result of a diff between two trees.
/// <para>Changes at the granularity of the file can be obtained through the different sub-collections <see cref="Added"/>, <see cref="Deleted"/> and <see cref="Modified"/>.</para>
/// <para>To obtain the actual patch of the diff, use the <see cref="Patch"/> class when calling Compare.</para>.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class TreeChanges : IEnumerable<TreeEntryChanges>
@ -23,13 +23,9 @@ namespace LibGit2Sharp
private readonly List<TreeEntryChanges> modified = new List<TreeEntryChanges>();
private readonly List<TreeEntryChanges> typeChanged = new List<TreeEntryChanges>();
private readonly List<TreeEntryChanges> unmodified = new List<TreeEntryChanges>();
private int linesAdded;
private int linesDeleted;
private readonly IDictionary<ChangeKind, Action<TreeChanges, TreeEntryChanges>> fileDispatcher = Build();
private readonly StringBuilder fullPatchBuilder = new StringBuilder();
private static IDictionary<ChangeKind, Action<TreeChanges, TreeEntryChanges>> Build()
{
return new Dictionary<ChangeKind, Action<TreeChanges, TreeEntryChanges>>
@ -48,23 +44,9 @@ namespace LibGit2Sharp
protected TreeChanges()
{ }
internal TreeChanges(DiffListSafeHandle diff, bool skipPatchBuilding = false)
internal TreeChanges(DiffListSafeHandle diff)
{
Proxy.git_diff_foreach(diff, FileCallback, null, DataCallback);
if (!skipPatchBuilding)
{
Proxy.git_diff_print_patch(diff, PrintCallBack);
}
}
private int DataCallback(GitDiffDelta delta, GitDiffRange range, GitDiffLineOrigin lineOrigin, IntPtr content, UIntPtr contentLen, IntPtr payload)
{
var filePath = FilePathMarshaler.FromNative(delta.NewFile.Path);
AddLineChange(this[filePath], lineOrigin);
return 0;
Proxy.git_diff_foreach(diff, FileCallback, null, null);
}
private int FileCallback(GitDiffDelta delta, float progress, IntPtr payload)
@ -73,33 +55,6 @@ namespace LibGit2Sharp
return 0;
}
private int PrintCallBack(GitDiffDelta delta, GitDiffRange range, GitDiffLineOrigin lineorigin, IntPtr content, UIntPtr contentlen, IntPtr payload)
{
string formattedoutput = Utf8Marshaler.FromNative(content, (int)contentlen);
var filePath = FilePathMarshaler.FromNative(delta.NewFile.Path);
fullPatchBuilder.Append(formattedoutput);
this[filePath].AppendToPatch(formattedoutput);
return 0;
}
private void AddLineChange(Changes currentChange, GitDiffLineOrigin lineOrigin)
{
switch (lineOrigin)
{
case GitDiffLineOrigin.GIT_DIFF_LINE_ADDITION:
linesAdded++;
currentChange.LinesAdded++;
break;
case GitDiffLineOrigin.GIT_DIFF_LINE_DELETION:
linesDeleted++;
currentChange.LinesDeleted++;
break;
}
}
private void AddFileChange(GitDiffDelta delta)
{
var newFilePath = FilePathMarshaler.FromNative(delta.NewFile.Path);
@ -115,13 +70,13 @@ namespace LibGit2Sharp
delta.Status = ChangeKind.Added;
}
var diffFile = new TreeEntryChanges(newFilePath, newMode, newOid, delta.Status, oldFilePath, oldMode, oldOid, delta.IsBinary());
var diffFile = new TreeEntryChanges(newFilePath, newMode, newOid, delta.Status, oldFilePath, oldMode, oldOid);
fileDispatcher[delta.Status](this, diffFile);
changes.Add(newFilePath, diffFile);
}
#region IEnumerable<Tag> Members
#region IEnumerable<TreeEntryChanges> Members
/// <summary>
/// Returns an enumerator that iterates through the collection.
@ -197,30 +152,6 @@ namespace LibGit2Sharp
get { return typeChanged; }
}
/// <summary>
/// The total number of lines added in this diff.
/// </summary>
public virtual int LinesAdded
{
get { return linesAdded; }
}
/// <summary>
/// The total number of lines added in this diff.
/// </summary>
public virtual int LinesDeleted
{
get { return linesDeleted; }
}
/// <summary>
/// The full patch file of this diff.
/// </summary>
public virtual string Patch
{
get { return fullPatchBuilder.ToString(); }
}
private string DebuggerDisplay
{
get

Просмотреть файл

@ -8,7 +8,7 @@ namespace LibGit2Sharp
/// Holds the changes between two versions of a tree entry.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class TreeEntryChanges : Changes
public class TreeEntryChanges
{
/// <summary>
/// Needed for mocking purposes.
@ -16,7 +16,7 @@ namespace LibGit2Sharp
protected TreeEntryChanges()
{ }
internal TreeEntryChanges(FilePath path, Mode mode, ObjectId oid, ChangeKind status, FilePath oldPath, Mode oldMode, ObjectId oldOid, bool isBinaryComparison)
internal TreeEntryChanges(FilePath path, Mode mode, ObjectId oid, ChangeKind status, FilePath oldPath, Mode oldMode, ObjectId oldOid)
{
Path = path.Native;
Mode = mode;
@ -25,7 +25,6 @@ namespace LibGit2Sharp
OldPath = oldPath.Native;
OldMode = oldMode;
OldOid = oldOid;
IsBinaryComparison = isBinaryComparison;
}
/// <summary>