@@ -21,6 +21,14 @@ public abstract class GitObject : IEquatable<GitObject>, IBelongToARepository
2121 { typeof ( Blob ) , ObjectType . Blob } ,
2222 { typeof ( TagAnnotation ) , ObjectType . Tag } ,
2323 } ;
24+ internal static IDictionary < Type , GitObjectType > TypeToGitKindMap =
25+ new Dictionary < Type , GitObjectType >
26+ {
27+ { typeof ( Commit ) , GitObjectType . Commit } ,
28+ { typeof ( Tree ) , GitObjectType . Tree } ,
29+ { typeof ( Blob ) , GitObjectType . Blob } ,
30+ { typeof ( TagAnnotation ) , GitObjectType . Tag } ,
31+ } ;
2432
2533 private static readonly LambdaEqualityHelper < GitObject > equalityHelper =
2634 new LambdaEqualityHelper < GitObject > ( x => x . Id ) ;
@@ -83,19 +91,32 @@ internal static GitObject BuildFrom(Repository repo, ObjectId id, GitObjectType
8391 }
8492 }
8593
86- internal Commit DereferenceToCommit ( bool throwsIfCanNotBeDereferencedToACommit )
94+ internal T Peel < T > ( bool throwOnError ) where T : GitObject
8795 {
88- using ( GitObjectSafeHandle peeledHandle = Proxy . git_object_peel ( repo . Handle , Id , GitObjectType . Commit , throwsIfCanNotBeDereferencedToACommit ) )
96+ GitObjectType kind ;
97+ if ( ! TypeToGitKindMap . TryGetValue ( typeof ( T ) , out kind ) )
8998 {
90- if ( peeledHandle == null )
91- {
92- return null ;
93- }
99+ throw new ArgumentException ( "Invalid type passed to peel" ) ;
100+ }
94101
95- return ( Commit ) BuildFrom ( repo , Proxy . git_object_id ( peeledHandle ) , GitObjectType . Commit , null ) ;
102+ using ( var handle = Proxy . git_object_peel ( repo . Handle , Id , kind , throwOnError ) )
103+ {
104+ return ( T ) BuildFrom ( this . repo , Proxy . git_object_id ( handle ) , kind , null ) ;
96105 }
97106 }
98107
108+ /// <summary>
109+ /// Peel this object to the specified type
110+ ///
111+ /// It will throw if the object cannot be peeled to the type.
112+ /// </summary>
113+ /// <typeparam name="T">The kind of <see cref="GitObject"/> to peel to.</typeparam>
114+ /// <returns>The peeled object</returns>
115+ public T Peel < T > ( ) where T : GitObject
116+ {
117+ return Peel < T > ( true ) ;
118+ }
119+
99120 /// <summary>
100121 /// Determines whether the specified <see cref="Object"/> is equal to the current <see cref="GitObject"/>.
101122 /// </summary>
0 commit comments