diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index e99145627..73045d012 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -177,7 +177,10 @@ private void EagerlyLoadTheConfigIfAnyPathHaveBeenPassed(RepositoryOptions optio internal RepositorySafeHandle Handle { - get { return handle; } + get + { + return handle; + } } /// @@ -208,7 +211,10 @@ public Branch Head /// public Configuration Config { - get { return config.Value; } + get + { + return config.Value; + } } /// @@ -265,7 +271,10 @@ public ObjectDatabase ObjectDatabase /// public ReferenceCollection Refs { - get { return refs; } + get + { + return refs; + } } /// @@ -274,7 +283,10 @@ public ReferenceCollection Refs /// public IQueryableCommitLog Commits { - get { return commits; } + get + { + return commits; + } } /// @@ -282,7 +294,10 @@ public IQueryableCommitLog Commits /// public BranchCollection Branches { - get { return branches; } + get + { + return branches; + } } /// @@ -290,7 +305,10 @@ public BranchCollection Branches /// public TagCollection Tags { - get { return tags; } + get + { + return tags; + } } /// @@ -298,7 +316,10 @@ public TagCollection Tags /// public StashCollection Stashes { - get { return stashes; } + get + { + return stashes; + } } /// @@ -306,7 +327,10 @@ public StashCollection Stashes /// public RepositoryInformation Info { - get { return info.Value; } + get + { + return info.Value; + } } /// @@ -314,7 +338,10 @@ public RepositoryInformation Info /// public Diff Diff { - get { return diff; } + get + { + return diff; + } } /// @@ -322,7 +349,10 @@ public Diff Diff /// public NoteCollection Notes { - get { return notes; } + get + { + return notes; + } } /// @@ -330,7 +360,10 @@ public NoteCollection Notes /// public SubmoduleCollection Submodules { - get { return submodules; } + get + { + return submodules; + } } #region IDisposable Members @@ -474,7 +507,7 @@ private static string PathFromRevparseSpec(string spec) } var m = Regex.Match(spec, @"[^@^ ]*:(.*)"); - return (m.Groups.Count > 1) ? m.Groups[1].Value : null; + return (m.Groups.Count > 1) ? m.Groups [1].Value : null; } internal GitObject Lookup(string objectish, GitObjectType type, LookUpOptions lookUpOptions) @@ -515,7 +548,7 @@ internal GitObject Lookup(string objectish, GitObjectType type, LookUpOptions lo internal Commit LookupCommit(string committish) { - return (Commit)Lookup(committish, GitObjectType.Any, + return (Commit) Lookup(committish, GitObjectType.Any, LookUpOptions.ThrowWhenNoGitObjectHasBeenFound | LookUpOptions.DereferenceResultToCommit | LookUpOptions.ThrowWhenCanNotBeDereferencedToACommit); @@ -559,7 +592,7 @@ public static string Clone(string sourceUrl, string workdirPath, Credentials credentials = null) { CheckoutCallbacks checkoutCallbacks = CheckoutCallbacks.GenerateCheckoutCallbacks(onCheckoutProgress, null); - + var callbacks = new RemoteCallbacks(null, onTransferProgress, null, credentials); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); @@ -599,6 +632,7 @@ public static string Clone(string sourceUrl, string workdirPath, /// that checkout progress is reported through. /// to manage checkout notifications. /// The that was checked out. + [Obsolete] public Branch Checkout(string committishOrBranchSpec, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotifications) { Ensure.ArgumentNotNullOrEmptyString(committishOrBranchSpec, "committishOrBranchSpec"); @@ -619,7 +653,7 @@ public Branch Checkout(string committishOrBranchSpec, CheckoutModifiers checkout var reference = Reference.BuildFromPtr(refH, this); if (reference.IsLocalBranch()) { - Branch branch = Branches[reference.CanonicalName]; + Branch branch = Branches [reference.CanonicalName]; return Checkout(branch, checkoutModifiers, onCheckoutProgress, checkoutNotifications); } } @@ -650,6 +684,7 @@ public Branch Checkout(string committishOrBranchSpec, CheckoutModifiers checkout /// that checkout progress is reported through. /// to manage checkout notifications. /// The that was checked out. + [Obsolete] public Branch Checkout(Branch branch, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions) { Ensure.ArgumentNotNull(branch, "branch"); @@ -665,7 +700,7 @@ public Branch Checkout(Branch branch, CheckoutModifiers checkoutModifiers, Check var branchIsCurrentRepositoryHead = branch.IsCurrentRepositoryHead; if (!branch.IsRemote && !(branch is DetachedHead) && - string.Equals(Refs[branch.CanonicalName].TargetIdentifier, branch.Tip.Id.Sha, + string.Equals(Refs [branch.CanonicalName].TargetIdentifier, branch.Tip.Id.Sha, StringComparison.OrdinalIgnoreCase)) { Checkout(branch.Tip.Tree, checkoutModifiers, onCheckoutProgress, checkoutNotificationOptions, branch.CanonicalName, branch.Name, !branchIsCurrentRepositoryHead); @@ -689,13 +724,138 @@ public Branch Checkout(Branch branch, CheckoutModifiers checkoutModifiers, Check /// that checkout progress is reported through. /// to manage checkout notifications. /// The that was checked out. + [Obsolete] public Branch Checkout(Commit commit, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions) { - Checkout(commit.Tree, checkoutModifiers, onCheckoutProgress, checkoutNotificationOptions, commit.Id.Sha, commit.Id.Sha, true); + Checkout( + commit.Tree, + checkoutModifiers, + onCheckoutProgress, + checkoutNotificationOptions, + commit.Id.Sha, + commit.Id.Sha, + true); return Head; } + /// + /// Checkout the specified , reference or SHA. + /// + /// If the committishOrBranchSpec parameter resolves to a branch name, then the checked out HEAD + /// will point to the branch. Otherwise, the HEAD will be detached, pointing at the commit sha. + /// + /// + /// A revparse spec for the commit or branch to checkout. + /// The controlling the checkout behaviour. + /// The that was checked out. + public Branch Checkout(string committishOrBranchSpec, CheckoutOptions options) + { + Ensure.ArgumentNotNullOrEmptyString(committishOrBranchSpec, "committishOrBranchSpec"); + + var handles = Proxy.git_revparse_ext(handle, committishOrBranchSpec); + if (handles == null) + { + Ensure.GitObjectIsNotNull(null, committishOrBranchSpec); + } + + var objH = handles.Item1; + var refH = handles.Item2; + GitObject obj; + + try + { + if (!refH.IsInvalid) + { + var reference = Reference.BuildFromPtr(refH, this); + + if (reference.IsLocalBranch()) + { + Branch branch = this.Branches [reference.CanonicalName]; + + return this.Checkout(branch, options); + } + } + + obj = GitObject.BuildFrom( + this, + Proxy.git_object_id(objH), + Proxy.git_object_type(objH), + Repository.PathFromRevparseSpec(committishOrBranchSpec)); + } + finally + { + objH.Dispose(); + refH.Dispose(); + } + + Commit commit = obj.DereferenceToCommit(true); + + this.Checkout( + commit.Tree, + options, + commit.Id.Sha, + committishOrBranchSpec, + committishOrBranchSpec != "HEAD"); + + return this.Head; + } + /// + /// Checkout the specified + /// + /// Will detach the HEAD and make it point to this commit sha. + /// + /// + /// The to check out. + /// The controlling the checkout behaviour. + /// The that was checked out. + public Branch Checkout(Commit commit, CheckoutOptions options) + { + this.Checkout( + commit.Tree, + options, + commit.Id.Sha, + commit.Id.Sha, + true); + + return this.Head; + } + /// + /// Checkout the tip commit of the specified object. If this commit is the + /// current tip of the branch, will checkout the named branch. Otherwise, will checkout the tip commit + /// as a detached HEAD. + /// + /// The to check out. + /// The controlling the checkout behaviour. + /// The that was checked out. + public Branch Checkout(Branch branch, CheckoutOptions options) + { + Ensure.ArgumentNotNull(branch, "branch"); + + //Ensure the branch isn't unborn + if (branch.Tip == null) + { + throw new UnbornBranchException( + string.Format(CultureInfo.InvariantCulture, + "The tip of branch '{0}' is null. There's nothing to checkout.", branch.Name)); + } + + var branchIsCurrentRepositoryHead = branch.IsCurrentRepositoryHead; + + if (!branch.IsRemote && + !(branch is DetachedHead) && + string.Equals(this.Refs[branch.CanonicalName].TargetIdentifier, branch.Tip.Id.Sha,StringComparison.OrdinalIgnoreCase)) + { + this.Checkout(branch.Tip.Tree, options, branch.CanonicalName, branch.Name, !branchIsCurrentRepositoryHead); + } + else + { + this.Checkout(branch.Tip.Tree, options, branch.Tip.Id.Sha, branch.Name, !branchIsCurrentRepositoryHead); + } + + return this.Head; + } + private void LogCheckout(string previousHeadName, ObjectId newHeadTip, string newHeadSpec) { // Compute reflog message @@ -716,6 +876,7 @@ private void LogCheckout(string previousHeadName, ObjectId newHeadTip, string ne /// Target for the new HEAD. /// The spec which will be written as target in the reflog. /// Will a reflog entry be created. + [Obsolete] private void Checkout( Tree tree, CheckoutModifiers checkoutModifiers, @@ -726,11 +887,11 @@ private void Checkout( var previousHeadName = Info.IsHeadDetached ? Head.Tip.Sha : Head.Name; var opts = new CheckoutOptions - { - CheckoutModifiers = checkoutModifiers, - OnCheckoutProgress = onCheckoutProgress, - CheckoutNotificationOptions = checkoutNotificationOptions - }; + { + CheckoutModifiers = checkoutModifiers, + OnCheckoutProgress = onCheckoutProgress, + CheckoutNotificationOptions = checkoutNotificationOptions + }; CheckoutTree(tree, null, opts); @@ -742,6 +903,31 @@ private void Checkout( } } + /// + /// Internal implementation of Checkout that expects the ID of the checkout target + /// to already be in the form of a canonical branch name or a commit ID. + /// + /// The to checkout. + /// The controlling the checkout behaviour. + /// Target for the new HEAD. + /// The spec which will be written as target in the reflog. + /// True if a reflog entry will be created. + private void Checkout( + Tree tree, + CheckoutOptions options, + string headTarget, string refLogHeadSpec, bool writeReflogEntry) + { + var previousHeadName = this.Info.IsHeadDetached ? this.Head.Tip.Sha : this.Head.Name; + + this.CheckoutTree(tree, null, options); + this.Refs.UpdateTarget("HEAD", headTarget); + + if (writeReflogEntry) + { + this.LogCheckout(previousHeadName, Head.Tip.Id, refLogHeadSpec); + } + } + /// /// Checkout the specified tree. /// @@ -977,7 +1163,10 @@ internal T RegisterForCleanup(T disposable) where T : IDisposable /// public static string Version { - get { return versionRetriever.Value; } + get + { + return versionRetriever.Value; + } } private static string RetrieveVersion() @@ -1023,7 +1212,10 @@ public IEnumerable MergeHeads internal StringComparer PathComparer { - get { return pathCase.Value.Comparer; } + get + { + return pathCase.Value.Comparer; + } } internal bool PathStartsWith(string path, string value) @@ -1031,7 +1223,7 @@ internal bool PathStartsWith(string path, string value) return pathCase.Value.StartsWith(path, value); } - internal FilePath[] ToFilePaths(IEnumerable paths) + internal FilePath [] ToFilePaths(IEnumerable paths) { if (paths == null) {