public CommitDelta GetChanges(string commitHash) { Commit commit = this.repositoryReader.ReadCommit(commitHash); List <FileChange> added = new List <FileChange>(); List <FileChange> deleted = new List <FileChange>(); List <FileChange> modified = new List <FileChange>(); if ((commit.Parents.Count != 0) && (commit.Parents.Count <= 2)) { string str = commit.Parents[0]; Dictionary <string, PathHashMode> dictionary = Enumerable.ToDictionary <PathHashMode, string>(this.GetPathAndHashForFiles(str), x => x.Path); Dictionary <string, PathHashMode> dictionary2 = null; if (commit.Parents.Count > 1) { string str2 = commit.Parents[1]; dictionary2 = Enumerable.ToDictionary <PathHashMode, string>(this.GetPathAndHashForFiles(str2), x => x.Path); } Dictionary <string, PathHashMode> dictionary3 = Enumerable.ToDictionary <PathHashMode, string>(this.GetPathAndHashForFiles(commitHash), x => x.Path); HashSet <string> set = new HashSet <string>(Enumerable.Concat <string>((IEnumerable <string>)dictionary3.get_Keys(), (IEnumerable <string>)dictionary.get_Keys())); if (dictionary2 != null) { set.UnionWith((IEnumerable <string>)dictionary2.get_Keys()); } foreach (string str3 in set) { PathHashMode mode; PathHashMode mode2; PathHashMode mode3; bool flag = dictionary3.TryGetValue(str3, out mode); bool flag2 = dictionary.TryGetValue(str3, out mode2); if (dictionary2 == null) { if (!(flag2 & flag) || (mode2.Hash == mode.Hash)) { if (flag2 && !flag) { deleted.Add(new FileChange(mode2.Path, 0, this.GetLineCount(mode2.Hash, mode2.Mode))); continue; } if (!(!flag2 & flag)) { continue; } added.Add(new FileChange(mode.Path, this.GetLineCount(mode.Hash, mode.Mode), 0)); continue; } int num3 = 0; int num4 = 0; if ((mode2.Mode != TreeEntryMode.RegularExecutableFile) && (mode.Mode != TreeEntryMode.RegularExecutableFile)) { (int, int)linesChanged = DiffGenerator.GetLinesChanged(this.repositoryReader.ReadBlob(mode2.Hash), this.repositoryReader.ReadBlob(mode.Hash)); num3 = linesChanged.Item1; num4 = linesChanged.Item2; } modified.Add(new FileChange(mode.Path, num3, num4)); continue; } bool flag3 = dictionary2.TryGetValue(str3, out mode3); if (!(flag2 & flag) || ((mode2.Hash == mode.Hash) || (!(flag3 & flag) || (mode3.Hash == mode.Hash)))) { if ((flag2 | flag3) && !flag) { deleted.Add(new FileChange(mode2.Path, 0, this.GetLineCount(mode2.Hash, mode2.Mode))); continue; } if (!((!flag2 && !flag3) & flag)) { continue; } added.Add(new FileChange(mode.Path, this.GetLineCount(mode.Hash, mode.Mode), 0)); continue; } int numberOfLinesAdded = 0; int numberOfLinesDeleted = 0; if ((mode2.Mode != TreeEntryMode.RegularExecutableFile) && ((mode3.Mode != TreeEntryMode.RegularExecutableFile) && (mode.Mode != TreeEntryMode.RegularExecutableFile))) { (int, int)tuple1 = DiffGenerator.GetLinesChanged(this.repositoryReader.ReadBlob(mode2.Hash), this.repositoryReader.ReadBlob(mode3.Hash), this.repositoryReader.ReadBlob(mode.Hash)); numberOfLinesAdded = tuple1.Item1; numberOfLinesDeleted = tuple1.Item2; } modified.Add(new FileChange(mode.Path, numberOfLinesAdded, numberOfLinesDeleted)); } } return(new CommitDelta(added, deleted, modified)); }
/// <summary> /// For a specific commit this provides a list of files added, a list of files modified and a list of the files deleted by that commit. /// </summary> /// <param name="commitHash">The hash of the commit to run for</param> public CommitDelta GetChanges(string commitHash) { Commit commit = repositoryReader.ReadCommit(commitHash); List <FileChange> added = new List <FileChange>(); List <FileChange> deleted = new List <FileChange>(); List <FileChange> modified = new List <FileChange>(); if (commit.Parents.Count == 0 || commit.Parents.Count > 2) { return(new CommitDelta(added, deleted, modified)); } string commitHashParent1 = commit.Parents[0]; Dictionary <string, PathHashMode> filePathToHashParent1 = GetPathAndHashForFiles(commitHashParent1).ToDictionary(x => x.Path); Dictionary <string, PathHashMode> filePathToHashParent2 = null; if (commit.Parents.Count > 1) { string commitHashParent2 = commit.Parents[1]; filePathToHashParent2 = GetPathAndHashForFiles(commitHashParent2).ToDictionary(x => x.Path); } Dictionary <string, PathHashMode> filePathToHashNow = GetPathAndHashForFiles(commitHash).ToDictionary(x => x.Path); HashSet <string> allFilePaths = new HashSet <string>(Enumerable.Concat(filePathToHashNow.Keys, filePathToHashParent1.Keys)); if (filePathToHashParent2 != null) { allFilePaths.UnionWith(filePathToHashParent2.Keys); } foreach (string filePath in allFilePaths) { bool existedInCommitNow = filePathToHashNow.TryGetValue(filePath, out PathHashMode now); bool existedInCommitBefore1 = filePathToHashParent1.TryGetValue(filePath, out PathHashMode before1); if (filePathToHashParent2 != null) { bool existedInCommitBefore2 = filePathToHashParent2.TryGetValue(filePath, out PathHashMode before2); if ((existedInCommitBefore1 && existedInCommitNow && before1.Hash != now.Hash) && (existedInCommitBefore2 && existedInCommitNow && before2.Hash != now.Hash)) { int linesAdded = 0; int linesDeleted = 0; if (before1.Mode != TreeEntryMode.RegularExecutableFile && before2.Mode != TreeEntryMode.RegularExecutableFile && now.Mode != TreeEntryMode.RegularExecutableFile) { (linesAdded, linesDeleted) = DiffGenerator.GetLinesChanged(repositoryReader.ReadBlob(before1.Hash), repositoryReader.ReadBlob(before2.Hash), repositoryReader.ReadBlob(now.Hash)); } modified.Add(new FileChange(now.Path, linesAdded, linesDeleted)); } else if ((existedInCommitBefore1 || existedInCommitBefore2) && !existedInCommitNow) { deleted.Add(new FileChange(before1.Path, 0, GetLineCount(before1.Hash, before1.Mode))); } else if (!existedInCommitBefore1 && !existedInCommitBefore2 && existedInCommitNow) { added.Add(new FileChange(now.Path, GetLineCount(now.Hash, now.Mode), 0)); } } else if (existedInCommitBefore1 && existedInCommitNow && before1.Hash != now.Hash) { int linesAdded = 0; int linesDeleted = 0; if (before1.Mode != TreeEntryMode.RegularExecutableFile && now.Mode != TreeEntryMode.RegularExecutableFile) { (linesAdded, linesDeleted) = DiffGenerator.GetLinesChanged(repositoryReader.ReadBlob(before1.Hash), repositoryReader.ReadBlob(now.Hash)); } modified.Add(new FileChange(now.Path, linesAdded, linesDeleted)); } else if (existedInCommitBefore1 && !existedInCommitNow) { deleted.Add(new FileChange(before1.Path, 0, GetLineCount(before1.Hash, before1.Mode))); } else if (!existedInCommitBefore1 && existedInCommitNow) { added.Add(new FileChange(now.Path, GetLineCount(now.Hash, now.Mode), 0)); } } return(new CommitDelta(added, deleted, modified)); }