public IEnumerable<HunkRangeInfo> GetGitDiffFor(ITextDocument textDocument, ITextSnapshot snapshot) { var content = GetCompleteContent(textDocument, snapshot); if (content == null) yield break; var filename = textDocument.FilePath; var discoveredPath = Repository.Discover(Path.GetFullPath(filename)); if (!Repository.IsValid(discoveredPath)) yield break; using (var repo = new Repository(discoveredPath)) { var retrieveStatus = repo.Index.RetrieveStatus(filename); if (retrieveStatus == FileStatus.Untracked || retrieveStatus == FileStatus.Added) yield break; content = AdaptCrlf(repo, content, textDocument); using (var currentContent = new MemoryStream(content)) { var newBlob = repo.ObjectDatabase.CreateBlob(currentContent); var directoryInfo = new DirectoryInfo(discoveredPath).Parent; if (directoryInfo == null) yield break; var relativeFilepath = filename.Replace(directoryInfo.FullName + "\\", string.Empty); // Determine 'from' and 'to' trees. var currentBranch = repo.Head.Name; var baseCommitEntry = repo.Config.Get<string>(string.Format("branch.{0}.diffmarginbase", currentBranch)); Tree tree = null; if (baseCommitEntry != null) { var baseCommit = repo.Lookup<Commit>(baseCommitEntry.Value); if (baseCommit != null) { // Found a merge base to diff from. tree = baseCommit.Tree; } } tree = tree ?? repo.Head.Tip.Tree; var from = TreeDefinition.From(tree); var treeDefinition = from.Add(relativeFilepath, newBlob, Mode.NonExecutableFile); var to = repo.ObjectDatabase.CreateTree(treeDefinition); var treeChanges = repo.Diff.Compare(tree, to, compareOptions: new CompareOptions { ContextLines = ContextLines, InterhunkLines = 0 }); var gitDiffParser = new GitDiffParser(treeChanges.Patch, ContextLines); var hunkRangeInfos = gitDiffParser.Parse(); foreach (var hunkRangeInfo in hunkRangeInfos) { yield return hunkRangeInfo; } } } }
public IEnumerable<HunkRangeInfo> GetGitDiffFor(ITextDocument textDocument, ITextSnapshot snapshot) { var filename = textDocument.FilePath; var discoveredPath = Repository.Discover(Path.GetFullPath(filename)); if (!Repository.IsValid(discoveredPath)) yield break; using (var repo = new Repository(discoveredPath)) { var retrieveStatus = repo.Index.RetrieveStatus(filename); if (retrieveStatus == FileStatus.Untracked || retrieveStatus == FileStatus.Added) yield break; var content = GetCompleteContent(textDocument, snapshot); if (content == null) yield break; content = AdaptCrlf(repo, content, textDocument); using (var currentContent = new MemoryStream(content)) { var newBlob = repo.ObjectDatabase.CreateBlob(currentContent); var directoryInfo = new DirectoryInfo(discoveredPath).Parent; if (directoryInfo == null) yield break; var relativeFilepath = filename.Replace(directoryInfo.FullName + "\\", string.Empty); var from = TreeDefinition.From(repo.Head.Tip.Tree); if (!repo.ObjectDatabase.Contains(@from[relativeFilepath].TargetId)) yield break; var blob = repo.Lookup<Blob>(@from[relativeFilepath].TargetId); var treeChanges = repo.Diff.Compare(blob, newBlob, new CompareOptions { ContextLines = ContextLines, InterhunkLines = 0 }); var gitDiffParser = new GitDiffParser(treeChanges.Patch, ContextLines); var hunkRangeInfos = gitDiffParser.Parse(); foreach (var hunkRangeInfo in hunkRangeInfos) { yield return hunkRangeInfo; } } } }
public IEnumerable<HunkRangeInfo> GetGitDiffFor(string filename) { var p = GetProcess(filename); p.StartInfo.Arguments = String.Format(@" diff --unified=0 {0}", filename); ActivityLog.LogInformation("GitDiffMargin", "Command:" + p.StartInfo.Arguments); p.Start(); // Do not wait for the child process to exit before // reading to the end of its redirected stream. // p.WaitForExit(); // Read the output stream first and then wait. var output = p.StandardOutput.ReadToEnd(); p.WaitForExit(); ActivityLog.LogInformation("GitDiffMargin", "Git Diff output:" + output); var gitDiffParser = new GitDiffParser(output); return gitDiffParser.Parse(); }
public void Parse_WithThreeHunk_ExpectHunkRanges() { //Arrange var gitDiffParser = new GitDiffParser(SecondGitDiff, 0); //Act var hunkRanges = gitDiffParser.Parse().ToList(); //Assert hunkRanges[0].OriginalHunkRange.StartingLineNumber.ShouldBe(67); hunkRanges[0].OriginalHunkRange.NumberOfLines.ShouldBe(2); hunkRanges[0].NewHunkRange.StartingLineNumber.ShouldBe(66); hunkRanges[0].NewHunkRange.NumberOfLines.ShouldBe(0); hunkRanges[1].OriginalHunkRange.StartingLineNumber.ShouldBe(169); hunkRanges[1].OriginalHunkRange.NumberOfLines.ShouldBe(0); hunkRanges[1].NewHunkRange.StartingLineNumber.ShouldBe(168); hunkRanges[1].NewHunkRange.NumberOfLines.ShouldBe(27); hunkRanges[2].OriginalHunkRange.StartingLineNumber.ShouldBe(184); hunkRanges[2].OriginalHunkRange.NumberOfLines.ShouldBe(2); hunkRanges[2].NewHunkRange.StartingLineNumber.ShouldBe(208); hunkRanges[2].NewHunkRange.NumberOfLines.ShouldBe(0); }
public void Parse_WithOneHunk_ExpectHunkRanges() { //Arrange var gitDiffParser = new GitDiffParser(FirstGitDiff, 0); //Act var hunkRanges = gitDiffParser.Parse().ToList(); //Assert hunkRanges[0].OriginalHunkRange.StartingLineNumber.ShouldBe(40); hunkRanges[0].OriginalHunkRange.NumberOfLines.ShouldBe(0); hunkRanges[0].NewHunkRange.StartingLineNumber.ShouldBe(41); hunkRanges[0].NewHunkRange.NumberOfLines.ShouldBe(20); }
public void Parse_EmptyGitDiff_Expect0HunkRangeInfos() { //Arrange var gitDiffParser = new GitDiffParser(EmptyGitDiff, 0); //Act var hunkRangeInfos = gitDiffParser.Parse().ToList(); //Assert hunkRangeInfos.Count.ShouldBe(0); }
public void Parse_DiffFromLibGit_ExpectThirdHunkRangeToBeAddition() { //Arrange var gitDiffParser = new GitDiffParser(DiffFromLibGit, 0); //Act var hunkRangeInfos = gitDiffParser.Parse().ToList(); //Assert hunkRangeInfos[2].IsDeletion.ShouldBe(false); hunkRangeInfos[2].IsAddition.ShouldBe(true); hunkRangeInfos[2].IsModification.ShouldBe(false); }
public void Parse_DiffFromLibGit_ExpectSecondHunkRangeOriginalText() { //Arrange var gitDiffParser = new GitDiffParser(DiffFromLibGit, 0); //Act var hunkRangeInfos = gitDiffParser.Parse().ToList(); //Assert hunkRangeInfos[1].OriginalText.ShouldBe(new List<string> {" class Class1"}); }
public void Parse_DiffFromLibGit_Expect5HunkRangeInfos() { //Arrange var gitDiffParser = new GitDiffParser(DiffFromLibGit, 0); //Act var hunkRangeInfos = gitDiffParser.Parse().ToList(); //Assert hunkRangeInfos.Count.ShouldBe(5); }
public IEnumerable <HunkRangeInfo> GetGitDiffFor(ITextDocument textDocument, ITextSnapshot snapshot) { var filename = textDocument.FilePath; var repositoryPath = GetGitRepository(Path.GetFullPath(filename)); if (repositoryPath == null) { yield break; } using (var repo = new Repository(repositoryPath)) { var workingDirectory = repo.Info.WorkingDirectory; if (workingDirectory == null) { yield break; } var retrieveStatus = repo.Index.RetrieveStatus(filename); if (retrieveStatus == FileStatus.Nonexistent) { // this occurs if a file within the repository itself (not the working copy) is opened. yield break; } if ((retrieveStatus & FileStatus.Ignored) != 0) { // pointless to show diffs for ignored files yield break; } if (retrieveStatus == FileStatus.Unaltered && !textDocument.IsDirty) { // truly unaltered yield break; } var content = GetCompleteContent(textDocument, snapshot); if (content == null) { yield break; } using (var currentContent = new MemoryStream(content)) { var relativeFilepath = filename; if (relativeFilepath.StartsWith(workingDirectory, StringComparison.OrdinalIgnoreCase)) { relativeFilepath = relativeFilepath.Substring(workingDirectory.Length); } var newBlob = repo.ObjectDatabase.CreateBlob(currentContent, relativeFilepath); bool suppressRollback; Blob blob; if ((retrieveStatus & FileStatus.Untracked) != 0 || (retrieveStatus & FileStatus.Added) != 0) { suppressRollback = true; // special handling for added files (would need updating to compare against index) using (var emptyContent = new MemoryStream()) { blob = repo.ObjectDatabase.CreateBlob(emptyContent, relativeFilepath); } } else { suppressRollback = false; Commit from = repo.Head.Tip; TreeEntry fromEntry = from[relativeFilepath]; if (fromEntry == null) { // try again using case-insensitive comparison Tree tree = from.Tree; foreach (string segment in relativeFilepath.Split(Path.DirectorySeparatorChar)) { if (tree == null) { yield break; } fromEntry = tree.FirstOrDefault(i => string.Equals(segment, i.Name, StringComparison.OrdinalIgnoreCase)); if (fromEntry == null) { yield break; } tree = fromEntry.Target as Tree; } } blob = fromEntry.Target as Blob; if (blob == null) { yield break; } } var treeChanges = repo.Diff.Compare(blob, newBlob, new CompareOptions { ContextLines = ContextLines, InterhunkLines = 0 }); var gitDiffParser = new GitDiffParser(treeChanges.Patch, ContextLines, suppressRollback); var hunkRangeInfos = gitDiffParser.Parse(); foreach (var hunkRangeInfo in hunkRangeInfos) { yield return(hunkRangeInfo); } } } }
public IEnumerable<HunkRangeInfo> GetGitDiffFor(ITextDocument textDocument, ITextSnapshot snapshot) { var filename = textDocument.FilePath; var repositoryPath = GetGitRepository(Path.GetFullPath(filename)); if (repositoryPath == null) yield break; using (var repo = new Repository(repositoryPath)) { var workingDirectory = repo.Info.WorkingDirectory; if (workingDirectory == null) yield break; var retrieveStatus = repo.Index.RetrieveStatus(filename); if (retrieveStatus == FileStatus.Nonexistent) { // this occurs if a file within the repository itself (not the working copy) is opened. yield break; } if ((retrieveStatus & FileStatus.Ignored) != 0) { // pointless to show diffs for ignored files yield break; } if (retrieveStatus == FileStatus.Unaltered && !textDocument.IsDirty) { // truly unaltered yield break; } var content = GetCompleteContent(textDocument, snapshot); if (content == null) yield break; using (var currentContent = new MemoryStream(content)) { var relativeFilepath = filename; if (relativeFilepath.StartsWith(workingDirectory, StringComparison.OrdinalIgnoreCase)) relativeFilepath = relativeFilepath.Substring(workingDirectory.Length); var newBlob = repo.ObjectDatabase.CreateBlob(currentContent, relativeFilepath); bool suppressRollback; Blob blob; if ((retrieveStatus & FileStatus.Untracked) != 0 || (retrieveStatus & FileStatus.Added) != 0) { suppressRollback = true; // special handling for added files (would need updating to compare against index) using (var emptyContent = new MemoryStream()) { blob = repo.ObjectDatabase.CreateBlob(emptyContent, relativeFilepath); } } else { suppressRollback = false; Commit from = repo.Head.Tip; TreeEntry fromEntry = from[relativeFilepath]; if (fromEntry == null) { // try again using case-insensitive comparison Tree tree = from.Tree; foreach (string segment in relativeFilepath.Split(Path.DirectorySeparatorChar)) { if (tree == null) yield break; fromEntry = tree.FirstOrDefault(i => string.Equals(segment, i.Name, StringComparison.OrdinalIgnoreCase)); if (fromEntry == null) yield break; tree = fromEntry.Target as Tree; } } blob = fromEntry.Target as Blob; if (blob == null) yield break; } var treeChanges = repo.Diff.Compare(blob, newBlob, new CompareOptions { ContextLines = ContextLines, InterhunkLines = 0 }); var gitDiffParser = new GitDiffParser(treeChanges.Patch, ContextLines, suppressRollback); var hunkRangeInfos = gitDiffParser.Parse(); foreach (var hunkRangeInfo in hunkRangeInfos) { yield return hunkRangeInfo; } } } }
public void Parse_WithOneHunkWithoutLineCount_ExpectHunkRanges() { //Arrange var gitDiffParser = new GitDiffParser(ThirdGitDiff); //Act var hunkRanges = gitDiffParser.Parse().ToList(); //Assert hunkRanges[0].OriginaleHunkRange.StartingLineNumber.ShouldBe(0); hunkRanges[0].OriginaleHunkRange.NumberOfLines.ShouldBe(1); hunkRanges[0].NewHunkRange.StartingLineNumber.ShouldBe(0); hunkRanges[0].NewHunkRange.NumberOfLines.ShouldBe(1); }
public IEnumerable <HunkRangeInfo> GetGitDiffFor(ITextDocument textDocument, ITextSnapshot snapshot) { var filename = textDocument.FilePath; var discoveredPath = Repository.Discover(Path.GetFullPath(filename)); if (!Repository.IsValid(discoveredPath)) { yield break; } using (var repo = new Repository(discoveredPath)) { var retrieveStatus = repo.Index.RetrieveStatus(filename); if (retrieveStatus == FileStatus.Untracked || retrieveStatus == FileStatus.Added) { yield break; } var content = GetCompleteContent(textDocument, snapshot); if (content == null) { yield break; } content = AdaptCrlf(repo, content, textDocument); using (var currentContent = new MemoryStream(content)) { var newBlob = repo.ObjectDatabase.CreateBlob(currentContent); var directoryInfo = new DirectoryInfo(discoveredPath).Parent; if (directoryInfo == null) { yield break; } var relativeFilepath = filename.Replace(directoryInfo.FullName + "\\", string.Empty); var from = TreeDefinition.From(repo.Head.Tip.Tree); if (!repo.ObjectDatabase.Contains(@from[relativeFilepath].TargetId)) { yield break; } var blob = repo.Lookup <Blob>(@from[relativeFilepath].TargetId); var treeChanges = repo.Diff.Compare(blob, newBlob, new CompareOptions { ContextLines = ContextLines, InterhunkLines = 0 }); var gitDiffParser = new GitDiffParser(treeChanges.Patch, ContextLines); var hunkRangeInfos = gitDiffParser.Parse(); foreach (var hunkRangeInfo in hunkRangeInfos) { yield return(hunkRangeInfo); } } } }
public IEnumerable <HunkRangeInfo> GetGitDiffFor(ITextDocument textDocument, string originalPath, ITextSnapshot snapshot) { var filename = textDocument.FilePath; var repositoryPath = GetGitRepository(Path.GetFullPath(filename), ref originalPath); if (repositoryPath == null) { yield break; } using (var repo = new Repository(repositoryPath)) { var workingDirectory = repo.Info.WorkingDirectory; if (workingDirectory == null) { yield break; } var retrieveStatus = repo.RetrieveStatus(originalPath); if (retrieveStatus == FileStatus.Nonexistent) { // this occurs if a file within the repository itself (not the working copy) is opened. yield break; } if ((retrieveStatus & FileStatus.Ignored) != 0) { // pointless to show diffs for ignored files yield break; } // Determine 'from' tree. var currentBranch = repo.Head.FriendlyName; var baseCommitEntry = repo.Config.Get <string>(string.Format("branch.{0}.diffmarginbase", currentBranch)); Commit from = null; if (baseCommitEntry != null) { var baseCommit = repo.Lookup <Commit>(baseCommitEntry.Value); if (baseCommit != null) { // Found a merge base to diff from. from = baseCommit; } } if (from == null && retrieveStatus == FileStatus.Unaltered && !textDocument.IsDirty && Path.GetFullPath(filename) == originalPath) { // Truly unaltered. The `IsDirty` check isn't valid for cases where the textDocument is a view of a // temporary copy of the file, since the temporary copy could have been made using unsaved changes // and still appear "not dirty". yield break; } var content = GetCompleteContent(textDocument, snapshot); if (content == null) { yield break; } using (var currentContent = new MemoryStream(content)) { var relativeFilepath = originalPath; if (relativeFilepath.StartsWith(workingDirectory, StringComparison.OrdinalIgnoreCase)) { relativeFilepath = relativeFilepath.Substring(workingDirectory.Length); } relativeFilepath = relativeFilepath.Replace('\\', '/'); var newBlob = repo.ObjectDatabase.CreateBlob(currentContent, relativeFilepath); bool suppressRollback; Blob blob; if ((retrieveStatus & FileStatus.NewInWorkdir) != 0 || (retrieveStatus & FileStatus.NewInIndex) != 0) { suppressRollback = true; // special handling for added files (would need updating to compare against index) using (var emptyContent = new MemoryStream()) { blob = repo.ObjectDatabase.CreateBlob(emptyContent, relativeFilepath); } } else { suppressRollback = false; from = from ?? repo.Head.Tip; TreeEntry fromEntry = from[relativeFilepath]; if (fromEntry == null) { // try again using case-insensitive comparison Tree tree = from.Tree; foreach (string segment in relativeFilepath.Split('/')) { if (tree == null) { yield break; } fromEntry = tree.FirstOrDefault(i => string.Equals(segment, i.Name, StringComparison.OrdinalIgnoreCase)); if (fromEntry == null) { yield break; } tree = fromEntry.Target as Tree; } } blob = fromEntry.Target as Blob; if (blob == null) { yield break; } } var treeChanges = repo.Diff.Compare(blob, newBlob, new CompareOptions { ContextLines = ContextLines, InterhunkLines = 0 }); var gitDiffParser = new GitDiffParser(treeChanges.Patch, ContextLines, suppressRollback); var hunkRangeInfos = gitDiffParser.Parse(); foreach (var hunkRangeInfo in hunkRangeInfos) { yield return(hunkRangeInfo); } } } }