using System;
using System.Globalization;
using System.Runtime.InteropServices;
using LibGit2Sharp.Core;
namespace LibGit2Sharp
{
///
/// Representation of an entry in a .
///
public class TreeEntry : IEquatable
{
private readonly ObjectId parentTreeId;
private readonly Repository repo;
private readonly Lazy target;
private readonly ObjectId targetOid;
private readonly Lazy path;
private static readonly LambdaEqualityHelper equalityHelper =
new LambdaEqualityHelper(x => x.Name, x => x.parentTreeId);
///
/// Needed for mocking purposes.
///
protected TreeEntry()
{ }
internal TreeEntry(SafeHandle obj, ObjectId parentTreeId, Repository repo, FilePath parentPath)
{
this.parentTreeId = parentTreeId;
this.repo = repo;
targetOid = Proxy.git_tree_entry_id(obj);
GitObjectType treeEntryTargetType = Proxy.git_tree_entry_type(obj);
TargetType = treeEntryTargetType.ToTreeEntryTargetType();
target = new Lazy(RetrieveTreeEntryTarget);
Mode = Proxy.git_tree_entry_attributes(obj);
Name = Proxy.git_tree_entry_name(obj);
path = new Lazy(() => System.IO.Path.Combine(parentPath.Native, Name));
}
///
/// Gets the file mode.
///
public virtual Mode Mode { get; private set; }
///
/// Gets the filename.
///
public virtual string Name { get; private set; }
///
/// Gets the path.
/// The path is expressed in a relative form from the latest known . Path segments are separated with a forward or backslash, depending on the OS the libray is being run on."/>
///
public virtual string Path { get { return path.Value; } }
///
/// Gets the being pointed at.
///
public virtual GitObject Target { get { return target.Value; } }
internal ObjectId TargetId
{
get { return targetOid; }
}
///
/// Gets the of the being pointed at.
///
public virtual TreeEntryTargetType TargetType { get; private set; }
private GitObject RetrieveTreeEntryTarget()
{
switch (TargetType)
{
case TreeEntryTargetType.GitLink:
return new GitLink(repo, targetOid);
case TreeEntryTargetType.Blob:
case TreeEntryTargetType.Tree:
return GitObject.BuildFrom(repo, targetOid, TargetType.ToGitObjectType(), Path);
default:
throw new InvalidOperationException(
string.Format(CultureInfo.InvariantCulture,
"TreeEntry target of type '{0}' is not supported.",
TargetType));
}
}
///
/// Determines whether the specified is equal to the current .
///
/// The to compare with the current .
/// True if the specified is equal to the current ; otherwise, false.
public override bool Equals(object obj)
{
return Equals(obj as TreeEntry);
}
///
/// Determines whether the specified is equal to the current .
///
/// The to compare with the current .
/// True if the specified is equal to the current ; otherwise, false.
public bool Equals(TreeEntry other)
{
return equalityHelper.Equals(this, other);
}
///
/// Returns the hash code for this instance.
///
/// A 32-bit signed integer hash code.
public override int GetHashCode()
{
return equalityHelper.GetHashCode(this);
}
///
/// Tests if two are equal.
///
/// First to compare.
/// Second to compare.
/// True if the two objects are equal; false otherwise.
public static bool operator ==(TreeEntry left, TreeEntry right)
{
return Equals(left, right);
}
///
/// Tests if two are different.
///
/// First to compare.
/// Second to compare.
/// True if the two objects are different; false otherwise.
public static bool operator !=(TreeEntry left, TreeEntry right)
{
return !Equals(left, right);
}
}
}