public async Task TestDiffDeletedFiletAsync() { GitDiffParser diffParser = new GitDiffParser(); await git.InitRepoAsync(); io.WriteFile("file1.txt", "text1"); GitCommit commit1 = await git.CommitAllChangesAsync("Message1"); io.DeleteFile("file1.txt"); GitCommit commit2 = await git.CommitAllChangesAsync("Message2"); R <string> result1 = await cmd.GetFileDiffAsync(commit1.Sha.Sha, "file1.txt", ct); Assert.AreEqual(true, result1.IsOk); CommitDiff diff1 = await diffParser.ParseAsync(commit1.Sha, result1.Value, false, false); Assert.IsNullOrEmpty(File.ReadAllText(diff1.LeftPath)); Assert.AreEqual("text1\r\n", File.ReadAllText(diff1.RightPath)); R <string> result2 = await cmd.GetFileDiffAsync(commit2.Sha.Sha, "file1.txt", ct); Assert.AreEqual(true, result2.IsOk); CommitDiff diff2 = await diffParser.ParseAsync(commit2.Sha, result2.Value, false, false); Assert.AreEqual("text1\r", File.ReadAllText(diff2.LeftPath)); Assert.IsNullOrEmpty(File.ReadAllText(diff2.RightPath)); }
public Codegram GenerateCodegramFromDiffContent(string diffContent, int maxSize) { GitDiffParser parser = new GitDiffParser(); var diffInfo = parser.Parse(diffContent); return(GenerateCodegramFromDiffContent(diffInfo, maxSize)); }
public void GetHunkNewFile_WithOneHunk_ExpectHunkNewFile() { //Arrange var gitDiffParser = new GitDiffParser(FirstGitDiff, 0); //Act string hunkOriginalFile = gitDiffParser.GetHunkOriginalFile(gitDiffParser.GetUnifiedFormatHunkLines().First().Item1); //Assert hunkOriginalFile.ShouldBe("41,0"); }
public void GetUnifiedFormatHunkLine_DeleteDiff_ExpectedHunkLine() { //Arrange var gitDiffParser = new GitDiffParser(DiffOfADeleteOfThreeLines, 0); //Act var unifiedFormatHunk = gitDiffParser.GetUnifiedFormatHunkLines().ToList(); //Assert unifiedFormatHunk[0].Item1.ShouldBe("@@ -7,3 +6,0 @@ using GitDiffMargin.Git;"); }
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_Expect5HunkRangeInfos() { //Arrange var gitDiffParser = new GitDiffParser(DiffFromLibGit, 0); //Act var hunkRangeInfos = gitDiffParser.Parse().ToList(); //Assert hunkRangeInfos.Count.ShouldBe(5); }
public void GetHunkNewFile_DeleteDiff_ExpectHunkNewFile() { //Arrange var gitDiffParser = new GitDiffParser(DiffOfADeleteOfThreeLines, 0); //Act var hunkOriginalFile = gitDiffParser.GetHunkOriginalFile(gitDiffParser.GetUnifiedFormatHunkLines().First().Item1); //Assert hunkOriginalFile.ShouldBe("7,3"); }
public void GetUnifiedFormatHunkLine_WithOneHunk_ExpectHunkLine() { //Arrange var gitDiffParser = new GitDiffParser(FirstGitDiff, 0); //Act var unifiedFormatHunk = gitDiffParser.GetUnifiedFormatHunkLines().ToList(); //Assert unifiedFormatHunk[0].Item1.ShouldBe("@@ -41,0 +42,20 @@ namespace skyeEditor.Core.Model.Dependency"); }
public void GetUnifiedFormatHunkLine_WithTwoHunk_ExpectHunkLine() { //Arrange var gitDiffParser = new GitDiffParser(SecondGitDiff, 0); //Act List <Tuple <string, IEnumerable <string> > > unifiedFormatHunk = gitDiffParser.GetUnifiedFormatHunkLines().ToList(); //Assert unifiedFormatHunk[0].Item1.ShouldBe("@@ -68,2 +67,0 @@ namespace skyeEditor.Core.Model.Dependency"); unifiedFormatHunk[1].Item1.ShouldBe("@@ -170,0 +169,27 @@ namespace skyeEditor.Core.Model.Dependency"); unifiedFormatHunk[2].Item1.ShouldBe("@@ -185,2 +209,0 @@ namespace skyeEditor.Core.Model.Dependency"); }
public void Parse_DiffFromLibGit_ExpectFifthHunkRangeToBeAddition() { //Arrange var gitDiffParser = new GitDiffParser(DiffFromLibGit, 0); //Act var hunkRangeInfos = gitDiffParser.Parse().ToList(); //Assert hunkRangeInfos[4].IsDeletion.ShouldBe(false); hunkRangeInfos[4].IsAddition.ShouldBe(true); hunkRangeInfos[4].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_WithOneHunkWithoutLineCount_ExpectHunkRanges() { //Arrange var gitDiffParser = new GitDiffParser(ThirdGitDiff, 0); //Act var hunkRanges = gitDiffParser.Parse().ToList(); //Assert hunkRanges[0].OriginalHunkRange.StartingLineNumber.ShouldBe(0); hunkRanges[0].OriginalHunkRange.NumberOfLines.ShouldBe(1); hunkRanges[0].NewHunkRange.StartingLineNumber.ShouldBe(0); hunkRanges[0].NewHunkRange.NumberOfLines.ShouldBe(1); }
public async Task TestDiffUncommittedAsync() { GitDiffParser diffParser = new GitDiffParser(); await git.InitRepoAsync(); io.WriteFile("file1.txt", "line1\nline2\nline3\n"); io.WriteFile("file2.txt", "line1\nline2\nline3\n"); await git.CommitAllChangesAsync("Message1"); io.WriteFile("file1.txt", "line1\nline22\nline3\n"); io.DeleteFile("file2.txt"); io.WriteFile("file3.txt", "line1\nline2\nline3\n"); R <string> result = await cmd.GetUncommittedDiffAsync(ct); CommitDiff diff = await diffParser.ParseAsync(null, result.Value, true, false); string d1 = File.ReadAllText(diff.LeftPath); string d2 = File.ReadAllText(diff.RightPath); Assert.IsNotNullOrEmpty(result.Value); result = await cmd.GetUncommittedFileDiffAsync("file1.txt", ct); Assert.IsNotNullOrEmpty(result.Value); //io.WriteFile("file1.txt", "line1\nline22\nline3\n"); //io.DeleteFile("file2.txt"); //io.WriteFile("file3.txt", "line1\nline2\nline3\n"); //result = await cmd.GetUncommittedDiffAsync(ct); //Assert.IsNotNullOrEmpty(result.Value); result = await cmd.GetUncommittedFileDiffAsync("file1.txt", ct); Assert.IsNotNullOrEmpty(result.Value); result = await cmd.GetUncommittedFileDiffAsync("file2.txt", ct); Assert.IsNotNullOrEmpty(result.Value); result = await cmd.GetUncommittedFileDiffAsync("file3.txt", ct); Assert.IsNotNullOrEmpty(result.Value); }
private static void ParseUnifiedDiff(string path, GitDiffParser diffParser, GitCommit commit) { commit.Difflets = diffParser.Parse(commit.UnifiedDiff); foreach (var file in commit.Files) { if (file.Status != "A") { file.BeforeText = GitCommands.ShowFileBeforeCommit(path, commit.Sha, file.File); } if (file.Status != "D") { file.AfterText = GitCommands.ShowFileAfterCommit(path, commit.Sha, file.File); } } }
static void PrintDiff(string diffFile) { GitDiffParser parser = new GitDiffParser(); var chunks = parser.Parse(File.ReadAllText(diffFile)); foreach (var file in chunks.Files) { foreach (var hunk in file.Hunks) { Console.WriteLine(string.Format("{0} {1} #{2} {3}", hunk.FileName, hunk.NewHunkRange.StartingLineNumber, hunk.NewHunkRange.NumberOfLines, hunk.IsModification )); } } }
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 async Task TestConflictsResolveAsync() { GitDiffParser diffParser = new GitDiffParser(); await git.InitRepoAsync(); // Add some files as initial add on master io.WriteFile("file1.txt", "Text 1"); io.WriteFile("file2.txt", "Text 2"); io.WriteFile("file3.txt", "Text 3"); io.WriteFile("file4.txt", "Text 4"); io.WriteFile("file5.txt", "Text 5"); GitCommit masterCommit1 = await git.CommitAllChangesAsync("Initial add on master"); // Create branch1 await git.BranchAsync("branch1"); io.WriteFile("file1.txt", "Text 12 on branch\r\n\n"); io.DeleteFile("file2.txt"); // Deleted 2 on branch io.WriteFile("file3.txt", "Text 32 on branch"); io.WriteFile("file4.txt", "Text 42 on branch"); io.DeleteFile("file5.txt"); // Delete 5 on branch io.WriteFile("file6.txt", "Text 62 on branch"); // Added 6 on branch GitCommit branchCommit1 = await git.CommitAllChangesAsync("Message 1 on branch1"); // Switch to master and make some changes and commit await git.CheckoutAsync("master"); io.WriteFile("file1.txt", "Text 12 on master\n"); io.WriteFile("file2.txt", "Text 22 on master"); io.DeleteFile("file3.txt"); // Delete 3 on master // No change on file 4 io.DeleteFile("file5.txt"); // Delete 5 om master io.WriteFile("file6.txt", "Text 62 on master"); // added on master GitCommit masterCommit2 = await git.CommitAllChangesAsync("Message 2 on master"); // Merge branch to master, expecting 1CMM, 2CMD, 3CDM, 4M, (no 5), 6CAA R result = await cmd.MergeAsync("branch1", ct); status = await git.GetStatusAsync(); Assert.AreEqual(1, status.Modified); Assert.AreEqual(4, status.Conflicted); Assert.AreEqual(true, status.IsMerging); GitConflicts conflicts = await git.GetConflictsAsync(); Assert.AreEqual(true, conflicts.HasConflicts); Assert.AreEqual(4, conflicts.Count); io.WriteFile("file1.txt", "Text 13 merged"); status = await git.GetStatusAsync(); await git.Service <IGitStatusService>().Call(m => m.AddAsync("file1.txt", ct)); status = await git.GetStatusAsync(); Assert.AreEqual(2, status.Modified); Assert.AreEqual(3, status.Conflicted); io.DeleteFile("file2.txt"); await git.Service <IGitStatusService>().Call(m => m.RemoveAsync("file2.txt", ct)); status = await git.GetStatusAsync(); Assert.AreEqual(2, status.Modified); Assert.AreEqual(1, status.Deleted); Assert.AreEqual(2, status.Conflicted); string branchSide = await git.GetConflictFileAsync(conflicts.Files[2].RemoteId); io.WriteFile("file3.txt", branchSide); await git.Service <IGitStatusService>().Call(m => m.AddAsync("file3.txt", ct)); status = await git.GetStatusAsync(); Assert.AreEqual(3, status.Modified); Assert.AreEqual(1, status.Deleted); Assert.AreEqual(1, status.Conflicted); io.WriteFile("file6.txt", "Text 63 merged"); await git.Service <IGitStatusService>().Call(m => m.AddAsync("file6.txt", ct)); status = await git.GetStatusAsync(); Assert.AreEqual(4, status.Modified); Assert.AreEqual(1, status.Deleted); Assert.AreEqual(0, status.Conflicted); GitCommit mergeCommit = await git.CommitAllChangesAsync(status.MergeMessage); string mergePatch = await git.Service <IGitDiffService>().Call(m => m.GetCommitDiffAsync(mergeCommit.Sha.Sha, ct)); string mergePatch2 = await git.Service <IGitDiffService>().Call( m => m.GetCommitDiffAsync(mergeCommit.Sha.Sha, ct)); CommitDiff diff = await diffParser.ParseAsync(mergeCommit.Sha, mergePatch, true, false); CommitDiff diff2 = await diffParser.ParseAsync(mergeCommit.Sha, mergePatch2, true, false); string left = File.ReadAllText(diff.LeftPath); string right = File.ReadAllText(diff.RightPath); string left2 = File.ReadAllText(diff2.LeftPath); string right2 = File.ReadAllText(diff2.RightPath); }
static void Main(string[] args) { Console.OutputEncoding = System.Text.Encoding.UTF8; string path = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "autogit"); path = @"C:\DEV\github\automark\Source\Extensions\automark.VisualStudio\.HistoryData\LocalHistory"; //path = @"C:\dev\github\automark\Source\automark\.HistoryData\LocalHistory"; //fatal: bad default revision 'HEAD' //path = @"C:\Users\Chris\Downloads\HistoryData\.HistoryData\LocalHistory"; var reverse = false; var html = false; var fuzz = false; var export = false; if (args.Length > 0) { path = args[0]; } if (args.Any(a => a == "-r")) { reverse = true; } if (args.Any(a => a == "-html")) { html = true; } if (args.Any(a => a == "-fuzz")) { fuzz = true; } if (args.Any(a => a == "-export")) { export = true; } var output = GitCommands.ListShaWithFiles(path); if (output == "") { Console.Error.WriteLine("There are no commits to report yet."); } var parser = new ParseGitLog(); var diffParser = new GitDiffParser(); var commits = parser.Parse(output); // commit for files not yet in repository, skip. // in future can be smarter with this with tags, etc. commits = commits.Where(c => !c.Message.Contains("pre save")).ToList(); if (export) { ExportHistory(path, output, commits); return; } foreach (var commit in commits) { commit.UnifiedDiff = GitCommands.ShowSha(path, commit.Sha); // skip big files for arbiturary definition of big. if (commit.UnifiedDiff.Length > 500000) { continue; } ParseUnifiedDiff(path, diffParser, commit); //commit.Print(); } // Temporal fuzz if (fuzz) { var commitsToPrune = new List <GitCommit>(); // Do processing of commits in order, just easier on the brain... var inOrderCommits = commits.ToList(); inOrderCommits.Reverse(); var prevCommit = inOrderCommits.FirstOrDefault(); var accumalatedDifference = new TimeSpan(); var startOfFuzz = prevCommit; var endOfFuzz = prevCommit; foreach (var commit in inOrderCommits.Skip(1)) { var lastTime = ParseGitLog.GetDateFromGitFormat(prevCommit.Headers["Date"]); var commitTime = ParseGitLog.GetDateFromGitFormat(commit.Headers["Date"]); var span = (lastTime - commitTime).Duration(); accumalatedDifference += span; if (accumalatedDifference.TotalMinutes <= 3 && prevCommit.Files.All(f => commit.Files.Select(c => c.File).Contains(f.File)) && prevCommit.Files.Any(f => f.Status != "A" || f.Status != "D")) { commitsToPrune.Add(prevCommit); endOfFuzz = commit; } else { // endOfFuzz will be only surviving commit in range, others will be pruned. // Get a new unified diff, and then reparse. if (startOfFuzz != endOfFuzz) { try { endOfFuzz.UnifiedDiff = GitCommands.ShowDiffRange(path, startOfFuzz.Sha + "~1", endOfFuzz.Sha); ParseUnifiedDiff(path, diffParser, endOfFuzz); } catch (Exception ex) { Trace.WriteLine(ex.Message); } } accumalatedDifference = new TimeSpan(); startOfFuzz = commit; endOfFuzz = commit; } prevCommit = commit; } if (startOfFuzz != endOfFuzz) { try { endOfFuzz.UnifiedDiff = GitCommands.ShowDiffRange(path, startOfFuzz.Sha + "~1", endOfFuzz.Sha); ParseUnifiedDiff(path, diffParser, endOfFuzz); } catch (Exception ex) { Trace.WriteLine(ex.Message); } } foreach (var commitToRemove in commitsToPrune) { commits.Remove(commitToRemove); } } ////////////////// // CUSTOM FILTERS ////////////////// commits = commits.Where(c => c.Difflets.Count > 0 && !c.Difflets[0].FileName.EndsWith(".csproj")).ToList(); // Remove hunks that are only from newline. foreach (var commit in commits) { foreach (var fileDiff in commit.Difflets) { fileDiff.Hunks = fileDiff.Hunks.Where(hunk => !(hunk.DiffLines .Where(l => l.Trim().StartsWith("+")) .All(l => l.Trim() == "+") && hunk.IsAddition) && !(hunk.DiffLines .Where(l => l.Trim().StartsWith("-")) .All(l => l.Trim() == "-") && hunk.IsDeletion) ).ToList(); } } // Remove commits that now have 0 hunks. commits = commits.Where(c => c.Difflets.All(f => f.Hunks.Count > 0)).ToList(); //commits = FixOnFix(commits); CodeWebHistory(commits); if (reverse) { commits.Reverse(); } if (html) { var formatter = new AsMarkdownHtml(); Console.WriteLine(formatter.Export(commits)); } else { var formatter = new AsMarkdown(); Console.WriteLine(formatter.Export(commits, args.Length == 0)); } //var html = new AsMarkdownHtml(); //Console.WriteLine(html.Export(commits)); if (args.Length == 0) { Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("sv-SE"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("sv-SE"); Console.WriteLine(string.Format("## {0:dddd, MMMM dd, yyyy}\u00e5", DateTime.Now.AddDays(-2))); Console.ReadKey(); } }