/// <summary>
        ///     Get a tree item blob from github.
        /// </summary>
        /// <param name="path">Base path of final git file</param>
        /// <param name="treeItem">Tree item to retrieve</param>
        /// <param name="owner">Organization</param>
        /// <param name="repo">Repository</param>
        /// <returns>Git file with tree item contents.</returns>
        private async Task <GitFile> GetGitItemImpl(string path, TreeItem treeItem, string owner, string repo)
        {
            Octokit.Blob blob = await ExponentialRetry.RetryAsync(
                async() => await Client.Git.Blob.Get(owner, repo, treeItem.Sha),
                ex => _logger.LogError(ex, $"Failed to get blob at sha {treeItem.Sha}"),
                ex => ex is ApiException apiex && apiex.StatusCode >= HttpStatusCode.InternalServerError);

            ContentEncoding encoding;

            switch (blob.Encoding.Value)
            {
            case EncodingType.Base64:
                encoding = ContentEncoding.Base64;
                break;

            case EncodingType.Utf8:
                encoding = ContentEncoding.Utf8;
                break;

            default:
                throw new NotImplementedException($"Unknown github encoding type {blob.Encoding.StringValue}");
            }
            GitFile newFile = new GitFile(
                path + "/" + treeItem.Path,
                blob.Content,
                encoding,
                treeItem.Mode);

            return(newFile);
        }
        /// <summary>
        ///     Retrieve a set of file under a specific path at a commit
        /// </summary>
        /// <param name="repoUri">Repository URI</param>
        /// <param name="commit">Commit to get files at</param>
        /// <param name="path">Path to retrieve files from</param>
        /// <returns>Set of files under <paramref name="path"/> at <paramref name="commit"/></returns>
        public async Task <List <GitFile> > GetFilesAtCommitAsync(string repoUri, string commit, string path)
        {
            path = path.Replace('\\', '/');
            path = path.TrimStart('/').TrimEnd('/');

            (string owner, string repo) = ParseRepoUri(repoUri);

            if (string.IsNullOrEmpty(owner) || string.IsNullOrEmpty(repo))
            {
                _logger.LogInformation($"'owner' or 'repository' couldn't be inferred from '{repoUri}'. " +
                                       $"Not getting files from 'eng/common...'");
                return(new List <GitFile>());
            }

            TreeResponse pathTree = await GetTreeForPathAsync(owner, repo, commit, path);

            TreeResponse recursiveTree = await GetRecursiveTreeAsync(owner, repo, pathTree.Sha);

            GitFile[] files = await Task.WhenAll(
                recursiveTree.Tree.Where(treeItem => treeItem.Type == TreeType.Blob)
                .Select(
                    async treeItem =>
            {
                Blob blob = await ExponentialRetry.RetryAsync(
                    async() => await Client.Git.Blob.Get(owner, repo, treeItem.Sha),
                    ex => _logger.LogError(ex, $"Failed to get blob at sha {treeItem.Sha}"),
                    ex => ex is ApiException apiex && apiex.StatusCode >= HttpStatusCode.InternalServerError);

                ContentEncoding encoding;
                switch (blob.Encoding.Value)
                {
                case EncodingType.Base64:
                    encoding = ContentEncoding.Base64;
                    break;

                case EncodingType.Utf8:
                    encoding = ContentEncoding.Utf8;
                    break;

                default:
                    throw new NotImplementedException($"Unknown github encoding type {blob.Encoding.StringValue}");
                }
                return(new GitFile(
                           path + "/" + treeItem.Path,
                           blob.Content,
                           encoding)
                {
                    Mode = treeItem.Mode
                });
            }));

            return(files.ToList());
        }