Skip to content
Browse files

Move AheadBy/BehindBy into new TrackingDetails

Also removes common ancestor check for AheadBy/BehindBy to align with
git.git behavior. Fixes #301.
  • Loading branch information...
1 parent 69582c4 commit 8caf13c442271c32b462d3d58d74d7b3f6d8977c @dahlbyk dahlbyk committed Mar 19, 2013
View
60 LibGit2Sharp.Tests/BranchFixture.cs
@@ -355,10 +355,13 @@ public void CanGetInformationFromUnbornBranch()
Assert.Null(head.Tip);
Assert.Null(head["huh?"]);
- Assert.Null(head.AheadBy);
- Assert.Null(head.BehindBy);
Assert.False(head.IsTracking);
Assert.Null(head.TrackedBranch);
+
+ Assert.NotNull(head.TrackingDetails);
+ Assert.Null(head.TrackingDetails.AheadBy);
+ Assert.Null(head.TrackingDetails.BehindBy);
+ Assert.Null(head.TrackingDetails.CommonAncestor);
}
}
@@ -372,9 +375,12 @@ public void CanGetTrackingInformationFromBranchSharingNoHistoryWithItsTrackedBra
repo.Refs.UpdateTarget("refs/remotes/origin/master", "origin/test");
Assert.True(master.IsTracking);
- Assert.Null(master.AheadBy);
- Assert.Null(master.BehindBy);
Assert.NotNull(master.TrackedBranch);
+
+ Assert.NotNull(master.TrackingDetails);
+ Assert.Equal(9, master.TrackingDetails.AheadBy);
+ Assert.Equal(2, master.TrackingDetails.BehindBy);
+ Assert.Null(repo.Head.TrackingDetails.CommonAncestor);
}
}
@@ -386,8 +392,11 @@ public void TrackingInformationIsEmptyForNonTrackingBranch()
Branch branch = repo.Branches["test"];
Assert.False(branch.IsTracking);
Assert.Null(branch.TrackedBranch);
- Assert.Null(branch.AheadBy);
- Assert.Null(branch.BehindBy);
+
+ Assert.NotNull(branch.TrackingDetails);
+ Assert.Null(branch.TrackingDetails.AheadBy);
+ Assert.Null(branch.TrackingDetails.BehindBy);
+ Assert.Null(branch.TrackingDetails.CommonAncestor);
}
}
@@ -399,8 +408,11 @@ public void CanGetTrackingInformationForTrackingBranch()
Branch master = repo.Branches["master"];
Assert.True(master.IsTracking);
Assert.Equal(repo.Branches["refs/remotes/origin/master"], master.TrackedBranch);
- Assert.Equal(2, master.AheadBy);
- Assert.Equal(2, master.BehindBy);
+
+ Assert.NotNull(master.TrackingDetails);
+ Assert.Equal(2, master.TrackingDetails.AheadBy);
+ Assert.Equal(2, master.TrackingDetails.BehindBy);
+ Assert.Equal(repo.Lookup<Commit>("4c062a6"), master.TrackingDetails.CommonAncestor);
}
}
@@ -412,8 +424,11 @@ public void CanGetTrackingInformationForLocalTrackingBranch()
var branch = repo.Branches["track-local"];
Assert.True(branch.IsTracking);
Assert.Equal(repo.Branches["master"], branch.TrackedBranch);
- Assert.Equal(2, branch.AheadBy);
- Assert.Equal(2, branch.BehindBy);
+
+ Assert.NotNull(branch.TrackingDetails);
+ Assert.Equal(2, branch.TrackingDetails.AheadBy);
+ Assert.Equal(2, branch.TrackingDetails.BehindBy);
+ Assert.Equal(repo.Lookup<Commit>("4c062a6"), branch.TrackingDetails.CommonAncestor);
}
}
@@ -752,6 +767,11 @@ public void DetachedHeadIsNotATrackingBranch()
Assert.False(repo.Head.IsTracking);
Assert.Null(repo.Head.TrackedBranch);
+
+ Assert.NotNull(repo.Head.TrackingDetails);
+ Assert.Null(repo.Head.TrackingDetails.AheadBy);
+ Assert.Null(repo.Head.TrackingDetails.BehindBy);
+ Assert.Null(repo.Head.TrackingDetails.CommonAncestor);
}
}
@@ -776,8 +796,10 @@ public void TrackedBranchExistsFromDefaultConfigInEmptyClone()
Assert.NotNull(repo.Head.TrackedBranch);
Assert.Null(repo.Head.TrackedBranch.Tip);
- Assert.Null(repo.Head.AheadBy);
- Assert.Null(repo.Head.BehindBy);
+ Assert.NotNull(repo.Head.TrackingDetails);
+ Assert.Null(repo.Head.TrackingDetails.AheadBy);
+ Assert.Null(repo.Head.TrackingDetails.BehindBy);
+ Assert.Null(repo.Head.TrackingDetails.CommonAncestor);
Assert.NotNull(repo.Head.Remote);
Assert.Equal("origin", repo.Head.Remote.Name);
@@ -788,9 +810,12 @@ public void TrackedBranchExistsFromDefaultConfigInEmptyClone()
Assert.NotNull(repo.Head.Tip);
Assert.NotNull(repo.Head.TrackedBranch);
+ Assert.Null(repo.Head.TrackedBranch.Tip);
- Assert.Null(repo.Head.AheadBy);
- Assert.Null(repo.Head.BehindBy);
+ Assert.NotNull(repo.Head.TrackingDetails);
+ Assert.Null(repo.Head.TrackingDetails.AheadBy);
+ Assert.Null(repo.Head.TrackingDetails.BehindBy);
+ Assert.Null(repo.Head.TrackingDetails.CommonAncestor);
}
}
@@ -807,8 +832,11 @@ public void RemoteBranchesDoNotTrackAnything()
Assert.NotNull(branch.Remote);
Assert.False(branch.IsTracking);
Assert.Null(branch.TrackedBranch);
- Assert.Null(branch.AheadBy);
- Assert.Null(branch.BehindBy);
+
+ Assert.NotNull(branch.TrackingDetails);
+ Assert.Null(branch.TrackingDetails.AheadBy);
+ Assert.Null(branch.TrackingDetails.BehindBy);
+ Assert.Null(branch.TrackingDetails.CommonAncestor);
}
}
}
View
44 LibGit2Sharp/Branch.cs
@@ -94,48 +94,36 @@ public virtual bool IsTracking
get { return TrackedBranch != null; }
}
- private bool ExistsPathToTrackedBranch()
- {
- if (!IsTracking)
- {
- return false;
- }
-
- if (Tip == null || TrackedBranch.Tip == null)
- {
- return false;
- }
-
- if (repo.Commits.FindCommonAncestor(Tip, TrackedBranch.Tip) == null)
- {
- return false;
- }
-
- return true;
- }
-
/// <summary>
- /// Gets the number of commits, starting from the <see cref="Tip"/>, that have been performed on this local branch and aren't known from the remote one.
+ /// Gets the number of commits that exist in this local branch but don't exist in the tracked one.
/// <para>
- /// This property will return null if there is no remote branch linked to this local branch, or if the remote branch and the local branch do
- /// not share a common ancestor.
+ /// This property will return null if there is no tracked branch linked to this local branch.
/// </para>
/// </summary>
+ [Obsolete("This property will be removed in the next release. Please use TrackingDetails.AheadBy instead.")]
public virtual int? AheadBy
{
- get { return ExistsPathToTrackedBranch() ? Proxy.git_graph_ahead_behind(repo.Handle, TrackedBranch.Tip.Id, Tip.Id).Item1 : (int?)null; }
+ get { return TrackingDetails.AheadBy; }
}
/// <summary>
- /// Gets the number of commits that exist in the remote branch, on top of <see cref="Tip"/>, and aren't known from the local one.
+ /// Gets the number of commits that exist in the tracked branch but don't exist in this local one.
/// <para>
- /// This property will return null if there is no remote branch linked to this local branch, or if the remote branch and the local branch do
- /// not share a common ancestor.
+ /// This property will return null if there is no tracked branch linked to this local branch.
/// </para>
/// </summary>
+ [Obsolete("This property will be removed in the next release. Please use TrackingDetails.BehindBy instead.")]
public virtual int? BehindBy
{
- get { return ExistsPathToTrackedBranch() ? Proxy.git_graph_ahead_behind(repo.Handle, TrackedBranch.Tip.Id, Tip.Id).Item2 : (int?)null; }
+ get { return TrackingDetails.BehindBy; }
+ }
+
+ /// <summary>
+ /// Gets additional information about the tracked branch.
+ /// </summary>
+ public virtual BranchTrackingDetails TrackingDetails
+ {
+ get { return new BranchTrackingDetails(repo, this); }
}
/// <summary>
View
87 LibGit2Sharp/BranchTrackingDetails.cs
@@ -0,0 +1,87 @@
+using LibGit2Sharp.Core;
+using LibGit2Sharp.Core.Compat;
+
+namespace LibGit2Sharp
+{
+ /// <summary>
+ /// Tracking information for a <see cref="Branch" />
+ /// </summary>
+ public class BranchTrackingDetails
+ {
+ private readonly Repository repo;
+ private readonly Branch branch;
+ private readonly Lazy<Tuple<int?, int?>> aheadBehind;
+ private readonly Lazy<Commit> commonAncestor;
+
+ /// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected BranchTrackingDetails()
+ { }
+
+ internal BranchTrackingDetails(Repository repo, Branch branch)
+ {
+ this.repo = repo;
+ this.branch = branch;
+
+ aheadBehind = new Lazy<Tuple<int?, int?>>(ResolveAheadBehind);
+ commonAncestor = new Lazy<Commit>(ResolveCommonAncestor);
+ }
+
+ /// <summary>
+ /// Gets the number of commits that exist in this local branch but don't exist in the tracked one.
+ /// <para>
+ /// This property will return null if there is no tracked branch linked to this local branch.
+ /// </para>
+ /// </summary>
+ public virtual int? AheadBy
+ {
+ get { return aheadBehind.Value.Item1; }
+ }
+
+ /// <summary>
+ /// Gets the number of commits that exist in the tracked branch but don't exist in this local one.
+ /// <para>
+ /// This property will return null if there is no tracked branch linked to this local branch.
+ /// </para>
+ /// </summary>
+ public virtual int? BehindBy
+ {
+ get { return aheadBehind.Value.Item2; }
+ }
+
+ /// <summary>
+ /// Gets the common ancestor of the local branch and its tracked remote branch.
+ /// <para>
+ /// This property will return null if there is no tracked branch linked to this local branch,
+ /// or if either branch is an orphan.
+ /// </para>
+ /// </summary>
+ public virtual Commit CommonAncestor
+ {
+ get { return commonAncestor.Value; }
+ }
+
+ private Tuple<int?, int?> ResolveAheadBehind()
+ {
+ return branch.IsTracking
+ ? Proxy.git_graph_ahead_behind(repo.Handle, branch.TrackedBranch.Tip, branch.Tip)
+ : new Tuple<int?, int?>(null, null);
+ }
+
+ private Commit ResolveCommonAncestor()
+ {
+ if (!branch.IsTracking)
+ {
+ return null;
+ }
+
+ if (branch.Tip == null || branch.TrackedBranch.Tip == null)
+ {
+ return null;
+ }
+
+ return repo.Commits.FindCommonAncestor(branch.Tip, branch.TrackedBranch.Tip);
+ }
+ }
+}
View
13 LibGit2Sharp/Core/Proxy.cs
@@ -604,10 +604,15 @@ public static void git_diff_print_patch(DiffListSafeHandle diff, NativeMethods.g
#region git_graph_
- public static Tuple<int, int> git_graph_ahead_behind(RepositorySafeHandle repo, ObjectId firstId, ObjectId secondId)
+ public static Tuple<int?, int?> git_graph_ahead_behind(RepositorySafeHandle repo, Commit first, Commit second)
{
- GitOid oid1 = firstId.Oid;
- GitOid oid2 = secondId.Oid;
+ if (first == null || second == null)
+ {
+ return new Tuple<int?, int?>(null, null);
+ }
+
+ GitOid oid1 = first.Id.Oid;
+ GitOid oid2 = second.Id.Oid;
using (ThreadAffinity())
{
@@ -618,7 +623,7 @@ public static void git_diff_print_patch(DiffListSafeHandle diff, NativeMethods.g
Ensure.ZeroResult(res);
- return new Tuple<int, int>((int)ahead, (int)behind);
+ return new Tuple<int?, int?>((int)ahead, (int)behind);
}
}
View
1 LibGit2Sharp/LibGit2Sharp.csproj
@@ -62,6 +62,7 @@
<Compile Include="Branch.cs" />
<Compile Include="BranchCollection.cs" />
<Compile Include="BranchCollectionExtensions.cs" />
+ <Compile Include="BranchTrackingDetails.cs" />
<Compile Include="BranchUpdater.cs" />
<Compile Include="Changes.cs" />
<Compile Include="CheckoutCallbacks.cs" />

0 comments on commit 8caf13c

Please sign in to comment.
Something went wrong with that request. Please try again.