using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using LibGit2Sharp.Core; using LibGit2Sharp.Core.Handles; namespace LibGit2Sharp { /// /// The is the reflog of a given , as a enumerable of . /// Reflog is a mechanism to record when the tip of a is updated. /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class ReflogCollection : IEnumerable { internal readonly Repository repo; private readonly string canonicalName; /// /// Needed for mocking purposes. /// protected ReflogCollection() { } /// /// Initializes a new instance of the class. /// /// The repo. /// the canonical name of the to retrieve reflog entries on. internal ReflogCollection(Repository repo, string canonicalName) { Ensure.ArgumentNotNullOrEmptyString(canonicalName, "canonicalName"); Ensure.ArgumentNotNull(repo, "repo"); this.repo = repo; this.canonicalName = canonicalName; } #region Implementation of IEnumerable /// /// Returns an enumerator that iterates through the collection. /// /// The enumerator returns the by descending order (last reflog entry is returned first). /// /// /// An object that can be used to iterate through the collection. public IEnumerator GetEnumerator() { var entries = new List(); using (ReferenceSafeHandle reference = Proxy.git_reference_lookup(repo.Handle, canonicalName, true)) using (ReflogSafeHandle reflog = Proxy.git_reflog_read(reference)) { var entriesCount = Proxy.git_reflog_entrycount(reflog); for (int i = 0; i < entriesCount; i++) { ReflogEntrySafeHandle handle = Proxy.git_reflog_entry_byindex(reflog, i); entries.Add(new ReflogEntry(handle)); } } return entries.GetEnumerator(); } /// /// Returns an enumerator that iterates through the collection. /// /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion private string DebuggerDisplay { get { return string.Format(CultureInfo.InvariantCulture, "Count = {0}", this.Count()); } } /// /// Add a new to the current . It will be created as first item of the collection /// The native reflog object will be saved right after inserting the entry. /// /// the of the new target the will point out to. /// the message associated with the new . /// of the comitter. internal virtual void Append(ObjectId target, string reflogMessage, Signature committer) { using (ReferenceSafeHandle reference = Proxy.git_reference_lookup(repo.Handle, canonicalName, true)) using (ReflogSafeHandle reflog = Proxy.git_reflog_read(reference)) { string prettifiedMessage = Proxy.git_message_prettify(reflogMessage); Proxy.git_reflog_append(reflog, target, committer, prettifiedMessage); } } /// /// Add a new to the current . It will be created as first item of the collection /// The native reflog object will be saved right after inserting the entry. /// /// The will be built from the current Git configuration. /// /// /// the of the new target the will point out to. /// the message associated with the new . internal void Append(ObjectId target, string reflogMessage) { Signature author = repo.Config.BuildSignatureFromGlobalConfiguration(DateTimeOffset.Now, false); Append(target, reflogMessage, author); } } }