using System; using System.Collections; using System.Collections.Generic; using System.Linq; using LibGit2Sharp.Core; using LibGit2Sharp.Core.Handles; namespace LibGit2Sharp { /// /// The result of a blame operation. /// public class BlameHunkCollection : IEnumerable { private readonly IRepository repo; private readonly List hunks = new List(); /// /// For easy mocking /// protected BlameHunkCollection() { } internal BlameHunkCollection(Repository repo, RepositorySafeHandle repoHandle, string path, BlameOptions options) { this.repo = repo; var rawopts = new GitBlameOptions { version = 1, flags = options.Strategy.ToGitBlameOptionFlags(), MinLine = (uint)options.MinLine, MaxLine = (uint)options.MaxLine, }; if (options.StartingAt != null) { rawopts.NewestCommit = repo.Committish(options.StartingAt).Oid; } if (options.StoppingAt != null) { rawopts.OldestCommit = repo.Committish(options.StoppingAt).Oid; } using (var blameHandle = Proxy.git_blame_file(repoHandle, path, rawopts)) { var numHunks = NativeMethods.git_blame_get_hunk_count(blameHandle); for (uint i = 0; i < numHunks; ++i) { var rawHunk = Proxy.git_blame_get_hunk_byindex(blameHandle, i); hunks.Add(new BlameHunk(this.repo, rawHunk)); } } } /// /// Access blame hunks by index. /// /// The index of the hunk to retrieve /// The at the given index. public virtual BlameHunk this[int idx] { get { return hunks[idx]; } } /// /// Access blame hunks by the file line. /// /// Line number to search for /// The that contains the specified file line. public virtual BlameHunk HunkForLine(int line) { var hunk = hunks.FirstOrDefault(x => x.ContainsLine(line)); if (hunk != null) { return hunk; } throw new ArgumentOutOfRangeException("line", "No hunk for that line"); } /// /// Returns an enumerator that iterates through a collection. /// /// /// An object that can be used to iterate through the collection. /// /// 2 public virtual IEnumerator GetEnumerator() { return hunks.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }