Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2sharp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJameson Miller <jamill@microsoft.com>2013-01-22 08:07:05 +0400
committernulltoken <emeric.fermas@gmail.com>2013-01-22 18:22:17 +0400
commit6aad7fd187028cf91e22998b79f9cd2a177e2ab0 (patch)
tree624aba93cb03d64be709b66ec9ab3af85cf0c6a6
parent91da7861cabe59c231a38d1f9c9b80e5440aa641 (diff)
Checkout branch as snapshot
-rw-r--r--LibGit2Sharp.Tests/CheckoutFixture.cs54
-rw-r--r--LibGit2Sharp/Branch.cs10
-rw-r--r--LibGit2Sharp/Repository.cs27
3 files changed, 80 insertions, 11 deletions
diff --git a/LibGit2Sharp.Tests/CheckoutFixture.cs b/LibGit2Sharp.Tests/CheckoutFixture.cs
index 6df94fe6..3b219f3e 100644
--- a/LibGit2Sharp.Tests/CheckoutFixture.cs
+++ b/LibGit2Sharp.Tests/CheckoutFixture.cs
@@ -233,10 +233,10 @@ namespace LibGit2Sharp.Tests
// Assert that normal checkout throws exception
// for the conflict.
- Assert.Throws<LibGit2SharpException>(() => master.Checkout());
+ Assert.Throws<LibGit2SharpException>(() => repo.Checkout(master.CanonicalName));
// Checkout with force option should succeed.
- master.Checkout(CheckoutOptions.Force, null);
+ repo.Checkout(master.CanonicalName, CheckoutOptions.Force, null);
// Assert that master branch is checked out.
Assert.True(repo.Branches["master"].IsCurrentRepositoryHead);
@@ -504,6 +504,56 @@ namespace LibGit2Sharp.Tests
}
}
+ [Fact]
+ public void CheckoutBranchSnapshot()
+ {
+ SelfCleaningDirectory scd = BuildSelfCleaningDirectory();
+
+ using (var repo = Repository.Init(scd.DirectoryPath))
+ {
+ PopulateBasicRepository(repo);
+
+ // Get the current status of master
+ // and the current tip.
+ Branch initial = repo.Branches["master"];
+ Commit initialCommit = initial.Tip;
+
+ // Add commit to master
+ string fullPath = Path.Combine(repo.Info.WorkingDirectory, originalFilePath);
+ File.WriteAllText(fullPath, "Update : hello from master branch!\n");
+ repo.Index.Stage(fullPath);
+ repo.Commit("2nd commit", Constants.Signature, Constants.Signature);
+
+ initial.Checkout();
+
+ // Head should point at initial commit.
+ Assert.Equal(repo.Head.Tip, initialCommit);
+ Assert.False(repo.Index.RetrieveStatus().IsDirty);
+ // Verify that HEAD is detached.
+ Assert.Equal(repo.Refs["HEAD"].TargetIdentifier, initial.Tip.Sha);
+ }
+ }
+
+ [Fact]
+ public void CheckingOutRemoteBranchResultsInDetachedHead()
+ {
+ TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo(StandardTestRepoWorkingDirPath);
+ using (var repo = new Repository(path.RepositoryPath))
+ {
+ Branch master = repo.Branches["master"];
+ Assert.True(master.IsCurrentRepositoryHead);
+
+ // Set the working directory to the current head
+ ResetAndCleanWorkingDirectory(repo);
+
+ repo.Checkout("refs/remotes/origin/master");
+
+ // Verify that HEAD is detached.
+ Assert.Equal(repo.Refs["HEAD"].TargetIdentifier, repo.Branches["origin/master"].Tip.Sha);
+
+ }
+ }
+
/// <summary>
/// Helper method to populate a simple repository with
/// a single file and two branches.
diff --git a/LibGit2Sharp/Branch.cs b/LibGit2Sharp/Branch.cs
index 8744b2ff..da7e8dd7 100644
--- a/LibGit2Sharp/Branch.cs
+++ b/LibGit2Sharp/Branch.cs
@@ -189,7 +189,10 @@ namespace LibGit2Sharp
}
/// <summary>
- /// Checkout this branch.
+ /// Checkout the tip commit of this <see cref = "Branch" /> 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.
/// </summary>
public virtual void Checkout()
{
@@ -197,7 +200,10 @@ namespace LibGit2Sharp
}
/// <summary>
- /// Checkout this branch with a callback for progress reporting.
+ /// Checkout the tip commit of this <see cref = "Branch" /> object
+ /// with a callback for progress reporting. 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.
/// </summary>
/// <param name="checkoutOptions">Options controlling checkout behavior.</param>
/// <param name="onCheckoutProgress">Callback method to report checkout progress updates through.</param>
diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs
index 668da5bd..08452cf3 100644
--- a/LibGit2Sharp/Repository.cs
+++ b/LibGit2Sharp/Repository.cs
@@ -517,7 +517,9 @@ namespace LibGit2Sharp
}
/// <summary>
- /// Checkout the specified <see cref = "Branch" />.
+ /// Checkout the tip commit of the specified <see cref = "Branch" /> 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.
/// </summary>
/// <param name="branch">The <see cref = "Branch" /> to check out. </param>
/// <param name="checkoutOptions"><see cref = "CheckoutOptions" /> controlling checkout behavior.</param>
@@ -527,14 +529,25 @@ namespace LibGit2Sharp
{
Ensure.ArgumentNotNull(branch, "branch");
- // Get the current tip commit of the branch, instead of
- // relying on branch.Tip, which references the commit at
- // the time the passed in branch object was created.
- Commit commit = LookupCommit(branch.CanonicalName);
- CheckoutTree(commit.Tree, checkoutOptions, onCheckoutProgress);
+ // Make sure this is not an unborn branch.
+ if (branch.Tip.Tree == null)
+ {
+ throw new Exception("branch tip is null, nothing to checkout.");
+ }
+
+ CheckoutTree(branch.Tip.Tree, checkoutOptions, onCheckoutProgress);
// Update HEAD.
- Refs.UpdateTarget("HEAD", branch.CanonicalName);
+ if (!branch.IsRemote &&
+ string.Equals(Refs[branch.CanonicalName].TargetIdentifier, branch.Tip.Id.Sha,
+ StringComparison.OrdinalIgnoreCase))
+ {
+ Refs.UpdateTarget("HEAD", branch.CanonicalName);
+ }
+ else
+ {
+ Refs.UpdateTarget("HEAD", branch.Tip.Id.Sha);
+ }
return Head;
}