Skip to content

Commit c9157e4

Browse files
committed
Add IBelongToARepository with some implementations
1 parent 547daba commit c9157e4

13 files changed

+80
-6
lines changed

LibGit2Sharp.Tests/BranchFixture.cs

+2
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public void CanCreateAnUnbornBranch()
7575
// The branch now exists...
7676
Branch orphan = repo.Branches["orphan"];
7777
Assert.NotNull(orphan);
78+
AssertBelongsToARepository(repo, orphan);
7879

7980
// ...and points to that newly created commit
8081
Assert.Equal(c, orphan.Tip);
@@ -489,6 +490,7 @@ public void CanGetTrackingInformationFromBranchSharingNoHistoryWithItsTrackedBra
489490

490491
Assert.True(master.IsTracking);
491492
Assert.NotNull(master.TrackedBranch);
493+
AssertBelongsToARepository(repo, master.TrackedBranch);
492494

493495
Assert.NotNull(master.TrackingDetails);
494496
Assert.Equal(9, master.TrackingDetails.AheadBy);

LibGit2Sharp.Tests/CheckoutFixture.cs

+3
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@ public void CanCheckoutAnExistingBranch(string branchName)
3232

3333
Branch branch = repo.Branches[branchName];
3434
Assert.NotNull(branch);
35+
AssertBelongsToARepository(repo, branch);
3536

3637
Branch test = repo.Checkout(branch);
3738
Assert.False(repo.Info.IsHeadDetached);
39+
AssertBelongsToARepository(repo, test);
3840

3941
Assert.False(test.IsRemote);
4042
Assert.True(test.IsCurrentRepositoryHead);
@@ -114,6 +116,7 @@ public void CanCheckoutAnArbitraryCommit(string commitPointer, bool checkoutByCo
114116
Assert.False(repo.Index.RetrieveStatus().IsDirty);
115117

116118
var commit = repo.Lookup<Commit>(commitPointer);
119+
AssertBelongsToARepository(repo, commit);
117120

118121
Branch detachedHead = checkoutByCommitOrBranchSpec ? repo.Checkout(commitPointer) : repo.Checkout(commit);
119122

LibGit2Sharp.Tests/MetaFixture.cs

+24-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ namespace LibGit2Sharp.Tests
1212
{
1313
public class MetaFixture
1414
{
15+
private static readonly HashSet<Type> explicitOnlyInterfaces = new HashSet<Type>
16+
{
17+
typeof(IBelongToARepository),
18+
};
19+
1520
[Fact]
1621
public void PublicTestMethodsAreFactsOrTheories()
1722
{
@@ -114,7 +119,7 @@ public void LibGit2SharpPublicInterfacesCoverAllPublicMembers()
114119
var methodsMissingFromInterfaces =
115120
from t in Assembly.GetAssembly(typeof(IRepository)).GetExportedTypes()
116121
where !t.IsInterface
117-
where t.GetInterfaces().Any(i => i.IsPublic && i.Namespace == typeof(IRepository).Namespace)
122+
where t.GetInterfaces().Any(i => i.IsPublic && i.Namespace == typeof(IRepository).Namespace && !explicitOnlyInterfaces.Contains(i))
118123
let interfaceTargetMethods = from i in t.GetInterfaces()
119124
from im in t.GetInterfaceMap(i).TargetMethods
120125
select im
@@ -126,6 +131,24 @@ from tm in t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | Bindin
126131
methodsMissingFromInterfaces.ToArray()));
127132
}
128133

134+
[Fact]
135+
public void LibGit2SharpExplicitOnlyInterfacesAreIndeedExplicitOnly()
136+
{
137+
var methodsMissingFromInterfaces =
138+
from t in Assembly.GetAssembly(typeof(IRepository)).GetExportedTypes()
139+
where t.GetInterfaces().Any(explicitOnlyInterfaces.Contains)
140+
let interfaceTargetMethods = from i in t.GetInterfaces()
141+
where explicitOnlyInterfaces.Contains(i)
142+
from im in t.GetInterfaceMap(i).TargetMethods
143+
select im
144+
from tm in t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
145+
where interfaceTargetMethods.Contains(tm)
146+
select t.Name + " has public method " + tm.Name + " which should be explicitly implemented.";
147+
148+
Assert.Equal("", string.Join(Environment.NewLine,
149+
methodsMissingFromInterfaces.ToArray()));
150+
}
151+
129152
[Fact]
130153
public void EnumsWithFlagsHaveMutuallyExclusiveValues()
131154
{

LibGit2Sharp.Tests/RemoteFixture.cs

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public void CanGetRemoteOrigin()
1414
{
1515
Remote origin = repo.Network.Remotes["origin"];
1616
Assert.NotNull(origin);
17+
AssertBelongsToARepository(repo, origin);
1718
Assert.Equal("origin", origin.Name);
1819
Assert.Equal("c:/GitHub/libgit2sharp/Resources/testrepo.git", origin.Url);
1920
}
@@ -38,6 +39,7 @@ public void CanEnumerateTheRemotes()
3839
foreach (Remote remote in repo.Network.Remotes)
3940
{
4041
Assert.NotNull(remote);
42+
AssertBelongsToARepository(repo, remote);
4143
count++;
4244
}
4345

LibGit2Sharp.Tests/SubmoduleFixture.cs

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public void CanRetrieveTheCommitIdsOfASubmodule(string name, string headId, stri
6060
{
6161
var submodule = repo.Submodules[name];
6262
Assert.NotNull(submodule);
63+
AssertBelongsToARepository(repo, submodule);
6364
Assert.Equal(name, submodule.Name);
6465

6566
Assert.Equal((ObjectId)headId, submodule.HeadCommitId);

LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs

+6
Original file line numberDiff line numberDiff line change
@@ -412,5 +412,11 @@ public static bool StreamEquals(Stream one, Stream two)
412412

413413
return true;
414414
}
415+
416+
public void AssertBelongsToARepository<T>(IRepository repo, T instance)
417+
where T : IBelongToARepository
418+
{
419+
Assert.Same(repo, ((IBelongToARepository)instance).Repository);
420+
}
415421
}
416422
}

LibGit2Sharp/GitObject.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace LibGit2Sharp
1111
/// A GitObject
1212
/// </summary>
1313
[DebuggerDisplay("{DebuggerDisplay,nq}")]
14-
public abstract class GitObject : IEquatable<GitObject>
14+
public abstract class GitObject : IEquatable<GitObject>, IBelongToARepository
1515
{
1616
internal static IDictionary<Type, ObjectType> TypeToKindMap =
1717
new Dictionary<Type, ObjectType>
@@ -154,5 +154,7 @@ private string DebuggerDisplay
154154
{
155155
get { return Id.ToString(7); }
156156
}
157+
158+
IRepository IBelongToARepository.Repository { get { return repo; } }
157159
}
158160
}

LibGit2Sharp/IBelongToARepository.cs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
namespace LibGit2Sharp
2+
{
3+
/// <summary>
4+
/// Can be used to reference the <see cref="IRepository" /> from which
5+
/// an instance was created.
6+
/// <para>
7+
/// While convenient in some situations (e.g. Checkout branch bound to UI element),
8+
/// it is important to ensure instances created from an <see cref="IRepository" />
9+
/// are not used after it is disposed.
10+
/// </para>
11+
/// <para>
12+
/// It's generally better to create <see cref="IRepository" /> and dependant instances
13+
/// on demand, with a short lifespan.
14+
/// </para>
15+
/// </summary>
16+
public interface IBelongToARepository
17+
{
18+
/// <summary>
19+
/// The <see cref="IRepository" /> from which this instance was created.
20+
/// <para>
21+
/// The returned value should not be disposed.
22+
/// </para>
23+
/// </summary>
24+
IRepository Repository { get; }
25+
}
26+
}

LibGit2Sharp/LibGit2Sharp.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
<Compile Include="Core\Handles\IndexNameEntrySafeHandle.cs" />
8585
<Compile Include="Core\Handles\IndexReucEntrySafeHandle.cs" />
8686
<Compile Include="EntryExistsException.cs" />
87+
<Compile Include="IBelongToARepository.cs" />
8788
<Compile Include="IndexNameEntryCollection.cs" />
8889
<Compile Include="ContentChangeStats.cs" />
8990
<Compile Include="BuiltInFeatures.cs" />

LibGit2Sharp/Reference.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace LibGit2Sharp
1010
/// A Reference to another git object
1111
/// </summary>
1212
[DebuggerDisplay("{DebuggerDisplay,nq}")]
13-
public abstract class Reference : IEquatable<Reference>
13+
public abstract class Reference : IEquatable<Reference>, IBelongToARepository
1414
{
1515
private static readonly LambdaEqualityHelper<Reference> equalityHelper =
1616
new LambdaEqualityHelper<Reference>(x => x.CanonicalName, x => x.TargetIdentifier);
@@ -209,5 +209,7 @@ private string DebuggerDisplay
209209
"{0} => \"{1}\"", CanonicalName, TargetIdentifier);
210210
}
211211
}
212+
213+
IRepository IBelongToARepository.Repository { get { return repo; } }
212214
}
213215
}

LibGit2Sharp/ReferenceWrapper.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace LibGit2Sharp
1010
/// </summary>
1111
/// <typeparam name="TObject">The type of the referenced Git object.</typeparam>
1212
[DebuggerDisplay("{DebuggerDisplay,nq}")]
13-
public abstract class ReferenceWrapper<TObject> : IEquatable<ReferenceWrapper<TObject>> where TObject : GitObject
13+
public abstract class ReferenceWrapper<TObject> : IEquatable<ReferenceWrapper<TObject>>, IBelongToARepository where TObject : GitObject
1414
{
1515
/// <summary>
1616
/// The repository.
@@ -160,5 +160,7 @@ private string DebuggerDisplay
160160
(TargetObject != null) ? TargetObject.Id.ToString(7) : "?");
161161
}
162162
}
163+
164+
IRepository IBelongToARepository.Repository { get { return repo; } }
163165
}
164166
}

LibGit2Sharp/Remote.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace LibGit2Sharp
1212
/// A remote repository whose branches are tracked.
1313
/// </summary>
1414
[DebuggerDisplay("{DebuggerDisplay,nq}")]
15-
public class Remote : IEquatable<Remote>
15+
public class Remote : IEquatable<Remote>, IBelongToARepository
1616
{
1717
private static readonly LambdaEqualityHelper<Remote> equalityHelper =
1818
new LambdaEqualityHelper<Remote>(x => x.Name, x => x.Url);
@@ -174,5 +174,7 @@ private string DebuggerDisplay
174174
"{0} => {1}", Name, Url);
175175
}
176176
}
177+
178+
IRepository IBelongToARepository.Repository { get { return repository; } }
177179
}
178180
}

LibGit2Sharp/Submodule.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace LibGit2Sharp
99
/// A Submodule.
1010
/// </summary>
1111
[DebuggerDisplay("{DebuggerDisplay,nq}")]
12-
public class Submodule : IEquatable<Submodule>
12+
public class Submodule : IEquatable<Submodule>, IBelongToARepository
1313
{
1414
private static readonly LambdaEqualityHelper<Submodule> equalityHelper =
1515
new LambdaEqualityHelper<Submodule>(x => x.Name, x => x.HeadCommitId);
@@ -155,5 +155,7 @@ private string DebuggerDisplay
155155
"{0} => {1}", Name, Url);
156156
}
157157
}
158+
159+
IRepository IBelongToARepository.Repository { get { return repo; } }
158160
}
159161
}

0 commit comments

Comments
 (0)