using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using LibGit2Sharp.Core;
namespace LibGit2Sharp
{
///
/// The collection of Branches in a
///
public class BranchCollection : IEnumerable
{
private readonly Repository repo;
///
/// Initializes a new instance of the class.
///
/// The repo.
internal BranchCollection(Repository repo)
{
this.repo = repo;
}
///
/// Gets the with the specified name.
///
public Branch this[string name]
{
get { return repo.Refs.Resolve(NormalizeToCanonicalName(name)); }
}
#region IEnumerable Members
///
/// Returns an enumerator that iterates through the collection.
///
/// An object that can be used to iterate through the collection.
public IEnumerator GetEnumerator()
{
return Libgit2UnsafeHelper.ListAllReferenceNames(repo.Handle, GitReferenceType.ListAll)
.Where(LooksLikeABranchName)
.Select(n => this[n])
.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
///
/// Checkout the branch with the specified by name.
///
/// The name of the branch to checkout.
///
public Branch Checkout(string name)
{
// TODO: This does not yet checkout (write) the working directory
Ensure.ArgumentNotNullOrEmptyString(name, "name");
repo.Refs.UpdateTarget("HEAD", this[name].CanonicalName);
return this[name];
}
///
/// Create a new local branch with the specified name
///
/// The name of the branch.
/// The target sha or branch name.
///
public Branch Create(string name, string target)
{
ObjectId id = ObjectId.CreateFromMaybeSha(target);
if (id == null)
{
target = NormalizeToCanonicalName(target);
}
repo.Refs.Create(NormalizeToCanonicalName(name), target);
return this[name];
}
///
/// Deletes the branch with the specified name.
///
/// The name of the branch to delete.
public void Delete(string name)
{
Ensure.ArgumentNotNullOrEmptyString(name, "name");
repo.Refs.Delete(this[name].CanonicalName); //TODO: To be replaced by native libgit2 git_branch_delete() when available.
}
private static bool LooksLikeABranchName(string referenceName)
{
return referenceName.StartsWith("refs/heads/", StringComparison.Ordinal) || referenceName.StartsWith("refs/remotes/", StringComparison.Ordinal);
}
private static string NormalizeToCanonicalName(string name)
{
Ensure.ArgumentNotNullOrEmptyString(name, "name");
if (LooksLikeABranchName(name))
{
return name;
}
return string.Format(CultureInfo.InvariantCulture, "refs/heads/{0}", name);
}
}
}