diff options
author | Keith Dahlby <dahlbyk@gmail.com> | 2011-10-03 06:02:42 +0400 |
---|---|---|
committer | nulltoken <emeric.fermas@gmail.com> | 2011-10-10 10:12:01 +0400 |
commit | e3df5105f02e46ca416e1c46d9caf13893836a96 (patch) | |
tree | 5002bd1e775770d439db8960d6b7c35fbe6b936e | |
parent | 13d02d146732348a4edeb5a28b23d251783c8c4d (diff) |
Add tracking branch details. Closes #75
-rw-r--r-- | LibGit2Sharp.Tests/BranchFixture.cs | 28 | ||||
-rw-r--r-- | LibGit2Sharp.Tests/Resources/testrepo.git/config | 0 | ||||
-rw-r--r-- | LibGit2Sharp/Branch.cs | 57 |
3 files changed, 82 insertions, 3 deletions
diff --git a/LibGit2Sharp.Tests/BranchFixture.cs b/LibGit2Sharp.Tests/BranchFixture.cs index 7a98d70e..88b61968 100644 --- a/LibGit2Sharp.Tests/BranchFixture.cs +++ b/LibGit2Sharp.Tests/BranchFixture.cs @@ -231,6 +231,32 @@ namespace LibGit2Sharp.Tests } [Test] + public void TrackingInformationIsEmptyForNonTrackingBranch() + { + using (var repo = new Repository(Constants.BareTestRepoPath)) + { + Branch branch = repo.Branches["test"]; + branch.IsTracking.ShouldBeFalse(); + branch.TrackedBranch.ShouldBeNull(); + branch.AheadBy.ShouldEqual(0); + branch.BehindBy.ShouldEqual(0); + } + } + + [Test] + public void CanGetTrackingInformationForTrackingBranch() + { + using (var repo = new Repository(Constants.StandardTestRepoPath)) + { + Branch master = repo.Branches["master"]; + master.IsTracking.ShouldBeTrue(); + master.TrackedBranch.ShouldEqual(repo.Branches["refs/remotes/origin/master"]); + master.AheadBy.ShouldEqual(1); + master.BehindBy.ShouldEqual(0); + } + } + + [Test] public void CanWalkCommitsFromAnotherBranch() { using (var repo = new Repository(Constants.BareTestRepoPath)) @@ -284,7 +310,7 @@ namespace LibGit2Sharp.Tests Branch detachedHead = repo.Branches.Checkout(commitPointer); repo.Info.IsHeadDetached.ShouldBeTrue(); - + detachedHead.IsRemote.ShouldBeFalse(); detachedHead.CanonicalName.ShouldEqual(detachedHead.Name); detachedHead.CanonicalName.ShouldEqual("(no branch)"); diff --git a/LibGit2Sharp.Tests/Resources/testrepo.git/config b/LibGit2Sharp.Tests/Resources/testrepo.git/config new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/LibGit2Sharp.Tests/Resources/testrepo.git/config diff --git a/LibGit2Sharp/Branch.cs b/LibGit2Sharp/Branch.cs index 2f9e0cd3..bc7a7de5 100644 --- a/LibGit2Sharp/Branch.cs +++ b/LibGit2Sharp/Branch.cs @@ -1,5 +1,6 @@ using System; using System.Globalization; +using System.Linq; using LibGit2Sharp.Core; namespace LibGit2Sharp @@ -12,6 +13,8 @@ namespace LibGit2Sharp private static readonly LambdaEqualityHelper<Branch> equalityHelper = new LambdaEqualityHelper<Branch>(new Func<Branch, object>[] { x => x.CanonicalName, x => x.Tip }); + private readonly Lazy<Branch> trackedBranch; + /// <summary> /// Initializes a new instance of the <see cref = "Branch" /> class. /// </summary> @@ -19,7 +22,7 @@ namespace LibGit2Sharp /// <param name = "reference">The reference.</param> /// <param name = "canonicalName">The full name of the reference</param> internal Branch(Repository repo, Reference reference, string canonicalName) - : base(repo, reference, _ => canonicalName) + : this(repo, reference, _ => canonicalName) { } @@ -32,8 +35,14 @@ namespace LibGit2Sharp /// <param name = "repo">The repo.</param> /// <param name = "reference">The reference.</param> internal Branch(Repository repo, Reference reference) - : base(repo, reference, r => r.TargetIdentifier) + : this(repo, reference, r => r.TargetIdentifier) + { + } + + private Branch(Repository repo, Reference reference, Func<Reference, string> canonicalNameSelector) + : base(repo, reference, canonicalNameSelector) { + trackedBranch = new Lazy<Branch>(ResolveTrackedBranch); } /// <summary> @@ -65,6 +74,26 @@ namespace LibGit2Sharp get { return IsRemoteBranch(CanonicalName); } } + public Branch TrackedBranch + { + get { return trackedBranch.Value; } + } + + public bool IsTracking + { + get { return TrackedBranch != null; } + } + + public int AheadBy + { + get { return IsTracking ? repo.Commits.QueryBy(new Filter { Since = Tip, Until = TrackedBranch }).Count() : 0; } + } + + public int BehindBy + { + get { return IsTracking ? repo.Commits.QueryBy(new Filter { Since = TrackedBranch, Until = Tip }).Count() : 0; } + } + /// <summary> /// Gets a value indicating whether this instance is current branch (HEAD) in the repository. /// </summary> @@ -125,6 +154,30 @@ namespace LibGit2Sharp return equalityHelper.GetHashCode(this); } + private Branch ResolveTrackedBranch() + { + var trackedRemote = repo.Config.Get<string>(string.Concat("branch.", Name, ".remote")); + if (trackedRemote == null) + { + return null; + } + + var trackedRefName = repo.Config.Get<string>(string.Concat("branch.", Name, ".merge")); + if (trackedRefName == null) + { + return null; + } + + var remoteRefName = ResolveTrackedReference(trackedRemote, trackedRefName); + return repo.Branches[remoteRefName]; + } + + private string ResolveTrackedReference(string trackedRemote, string trackedRefName) + { + //TODO: To be replaced by native libgit2 git_branch_tracked_reference() when available. + return trackedRefName.Replace("refs/heads/", string.Concat("refs/remotes/", trackedRemote, "/")); + } + private static bool IsRemoteBranch(string canonicalName) { return canonicalName.StartsWith("refs/remotes/", StringComparison.Ordinal); |