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); } } }