/// <summary>
        /// Creates a dynamic repository based on the repository info
        /// </summary>
        /// <param name="repositoryInfo">The source repository information.</param>
        /// <param name="dynamicRepsitoryPath">The path to create the dynamic repository, NOT thread safe.</param>
        /// <param name="targetBranch"></param>
        /// <param name="targetCommit"></param>
        /// <returns>The git repository.</returns>
        public static DynamicRepository CreateOrOpen(RepositoryInfo repositoryInfo, string dynamicRepsitoryPath, string targetBranch, string targetCommit)
        {
            if (string.IsNullOrWhiteSpace(dynamicRepsitoryPath) || !Directory.Exists(dynamicRepsitoryPath))
                throw new GitToolsException(string.Format("Dynamic repository path {0} does not exist, ensure it is created before trying to create dynamic repository.", dynamicRepsitoryPath));
            if (string.IsNullOrWhiteSpace(targetBranch))
                throw new GitToolsException("Dynamic Git repositories must have a target branch");
            if (string.IsNullOrWhiteSpace(targetCommit))
                throw new GitToolsException("Dynamic Git repositories must have a target commit");

            var tempRepositoryPath = GetAndLockTemporaryRepositoryPath(repositoryInfo.Url, dynamicRepsitoryPath);
            var dynamicRepositoryPath = CreateDynamicRepository(tempRepositoryPath, repositoryInfo, targetBranch, targetCommit);

            return new DynamicRepository(new Repository(dynamicRepositoryPath), () => ReleaseDynamicRepoLock(tempRepositoryPath));
        }
        /// <summary>
        /// Creates a dynamic repository based on the repository info
        /// </summary>
        /// <param name="repositoryInfo">The source repository information.</param>
        /// <param name="dynamicRepsitoryPath">The path to create the dynamic repository, NOT thread safe.</param>
        /// <param name="targetBranch"></param>
        /// <param name="targetCommit"></param>
        /// <returns>The git repository.</returns>
        public static DynamicRepository CreateOrOpen(RepositoryInfo repositoryInfo, string dynamicRepsitoryPath, string targetBranch, string targetCommit)
        {
            if (string.IsNullOrWhiteSpace(dynamicRepsitoryPath) || !Directory.Exists(dynamicRepsitoryPath))
            {
                throw new GitToolsException(string.Format("Dynamic repository path {0} does not exist, ensure it is created before trying to create dynamic repository.", dynamicRepsitoryPath));
            }
            if (string.IsNullOrWhiteSpace(targetBranch))
            {
                throw new GitToolsException("Dynamic Git repositories must have a target branch");
            }
            if (string.IsNullOrWhiteSpace(targetCommit))
            {
                throw new GitToolsException("Dynamic Git repositories must have a target commit");
            }

            var tempRepositoryPath    = GetAndLockTemporaryRepositoryPath(repositoryInfo.Url, dynamicRepsitoryPath);
            var dynamicRepositoryPath = CreateDynamicRepository(tempRepositoryPath, repositoryInfo, targetBranch, targetCommit);

            return(new DynamicRepository(new Repository(dynamicRepositoryPath), () => ReleaseDynamicRepoLock(tempRepositoryPath)));
        }
        static string CreateDynamicRepository(string targetPath, RepositoryInfo repositoryInfo, string targetBranch, string targetCommit)
        {
            Log.Info(string.Format("Creating dynamic repository at '{0}'", targetPath));

            var gitDirectory = Path.Combine(targetPath, ".git");
            if (Directory.Exists(gitDirectory))
            {
                Log.Info("Git repository already exists");
                using (var repo = new Repository(gitDirectory))
                {
                    // We need to fetch before we can checkout the commit
                    var remote = GitRepositoryHelper.EnsureOnlyOneRemoteIsDefined(repo);
                    GitRepositoryHelper.Fetch(repositoryInfo.Authentication, remote, repo);
                    CheckoutCommit(repo, targetCommit);
                }
                GitRepositoryHelper.NormalizeGitDirectory(gitDirectory, repositoryInfo.Authentication, noFetch: true, currentBranch: targetBranch);

                return gitDirectory;
            }

            CloneRepository(repositoryInfo.Url, gitDirectory, repositoryInfo.Authentication);

            using (var repo = new Repository(gitDirectory))
            {
                CheckoutCommit(repo, targetCommit);
            }

            // Normalize (download branches) before using the branch
            GitRepositoryHelper.NormalizeGitDirectory(gitDirectory, repositoryInfo.Authentication, noFetch: true, currentBranch: targetBranch);

            return gitDirectory;
        }