using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using LibGit2Sharp.Core;
using LibGit2Sharp.Core.Handles;
namespace LibGit2Sharp
{
///
/// A log of commits in a
///
public sealed class CommitLog : IQueryableCommitLog
{
private readonly Repository repo;
private readonly CommitFilter queryFilter;
///
/// Initializes a new instance of the class.
/// The commits will be enumerated according in reverse chronological order.
///
/// The repository.
internal CommitLog(Repository repo)
: this(repo, new CommitFilter())
{
}
///
/// Initializes a new instance of the class.
///
/// The repository.
/// The filter to use in querying commits
internal CommitLog(Repository repo, CommitFilter queryFilter)
{
this.repo = repo;
this.queryFilter = queryFilter;
}
///
/// Gets the current sorting strategy applied when enumerating the log
///
public CommitSortStrategies SortedBy
{
get { return queryFilter.SortBy; }
}
#region IEnumerable Members
///
/// Returns an enumerator that iterates through the log.
///
/// An object that can be used to iterate through the log.
public IEnumerator GetEnumerator()
{
return new CommitEnumerator(repo, queryFilter);
}
///
/// Returns an enumerator that iterates through the log.
///
/// An object that can be used to iterate through the log.
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
///
/// Returns the list of commits of the repository matching the specified .
///
/// The options used to control which commits will be returned.
/// A list of commits, ready to be enumerated.
public ICommitLog QueryBy(CommitFilter filter)
{
Ensure.ArgumentNotNull(filter, "filter");
Ensure.ArgumentNotNull(filter.Since, "filter.Since");
Ensure.ArgumentNotNullOrEmptyString(filter.Since.ToString(), "filter.Since");
return new CommitLog(repo, filter);
}
///
/// Find the best possible merge base given two s.
///
/// The first .
/// The second .
/// The merge base or null if none found.
[Obsolete("This method will be removed in the next release. Please use ObjectDatabase.FindMergeBase() instead.")]
public Commit FindMergeBase(Commit first, Commit second)
{
return repo.ObjectDatabase.FindMergeBase(first, second);
}
///
/// Find the best possible merge base given two or more according to the .
///
/// The s for which to find the merge base.
/// The strategy to leverage in order to find the merge base.
/// The merge base or null if none found.
[Obsolete("This method will be removed in the next release. Please use ObjectDatabase.FindMergeBase() instead.")]
public Commit FindMergeBase(IEnumerable commits, MergeBaseFindingStrategy strategy)
{
return repo.ObjectDatabase.FindMergeBase(commits, strategy);
}
private class CommitEnumerator : IEnumerator
{
private readonly Repository repo;
private readonly RevWalkerSafeHandle handle;
private ObjectId currentOid;
public CommitEnumerator(Repository repo, CommitFilter filter)
{
this.repo = repo;
handle = Proxy.git_revwalk_new(repo.Handle);
repo.RegisterForCleanup(handle);
Sort(filter.SortBy);
Push(filter.SinceList);
Hide(filter.UntilList);
FirstParentOnly(filter.FirstParentOnly);
}
#region IEnumerator Members
public Commit Current
{
get { return repo.Lookup(currentOid); }
}
object IEnumerator.Current
{
get { return Current; }
}
public bool MoveNext()
{
ObjectId id = Proxy.git_revwalk_next(handle);
if (id == null)
{
return false;
}
currentOid = id;
return true;
}
public void Reset()
{
Proxy.git_revwalk_reset(handle);
}
#endregion
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
handle.SafeDispose();
}
private delegate void HidePushSignature(RevWalkerSafeHandle handle, ObjectId id);
private void InternalHidePush(IList