string TryFindCommit( RepositoryInfoOptions options, Repository r, out Commit commit, out CIBranchVersionMode ciVersionMode, out string branchNameForCIVersion )
{
ciVersionMode = CIBranchVersionMode.None;
commit = null;
branchNameForCIVersion = null;
string commitSha = options.StartingCommitSha;
// Find current commit (the head) if none is provided.
if( string.IsNullOrWhiteSpace( commitSha ) )
{
IEnumerable<string> branchNames;
if( string.IsNullOrWhiteSpace( options.StartingBranchName ) )
{
// locCommit is here because one cannot use an out parameter inside a lambda.
var locCommit = commit = r.Head.Tip;
if( locCommit == null ) return "Unitialized Git repository.";
// Save the branches!
// By doing this, when we are in 'Detached Head' state (the head of the repository is on a commit and not on a branch: git checkout <sha>),
// we can detect that it is the head of a branch and hence apply possible options (mainly CI) for it.
// We take into account only the branches from options.RemoteName remote here.
string branchName = r.Head.FriendlyName;
if( branchName == "(no branch)" )
{
string remotePrefix = options.RemoteName + '/';
branchNames = r.Branches
.Where( b => b.Tip == locCommit && (!b.IsRemote || b.FriendlyName.StartsWith( remotePrefix )) )
.Select( b => b.IsRemote ? b.FriendlyName.Substring( remotePrefix.Length ) : b.FriendlyName );
}
else branchNames = new[] { branchName };
}
else
{
Branch br = r.Branches[options.StartingBranchName] ?? r.Branches[ options.RemoteName + '/' + options.StartingBranchName];
if( br == null ) return string.Format( "Unknown StartingBranchName: '{0}' (also tested on remote '{1}/{0}').", options.StartingBranchName, options.RemoteName );
commit = br.Tip;
branchNames = new[] { options.StartingBranchName };
}
RepositoryInfoOptionsBranch bOpt;
if( options.Branches != null
&& (bOpt = options.Branches.FirstOrDefault( b => branchNames.Contains( b.Name ) )) != null
&& bOpt.CIVersionMode != CIBranchVersionMode.None )
{
ciVersionMode = bOpt.CIVersionMode;
branchNameForCIVersion = string.IsNullOrWhiteSpace( bOpt.VersionName ) ? bOpt.Name : bOpt.VersionName;
}
}
else
{
commit = r.Lookup<Commit>( commitSha );
if( commit == null ) return string.Format( "Commit '{0}' not found.", commitSha );
}
return null;
}