static public LoadFromUrlResult LoadFromUrl(string sourceUrl)
        {
            var parsedUrl = ParseGitHubObjectUrl(sourceUrl);

            if (parsedUrl == null)
            {
                return new LoadFromUrlResult
                       {
                           Error = "Failed to parse string '" + sourceUrl + "' as GitHub object URL.",
                       }
            }
            ;

            var refLooksLikeCommit = Regex.IsMatch(parsedUrl.@ref, "[A-Fa-f0-9]{40}");

            var tempWorkingDirectory = Kalmit.Filesystem.CreateRandomDirectoryInTempDirectory();

            var gitRepositoryLocalDirectory = Path.Combine(tempWorkingDirectory, "git-repository");

            //  https://github.com/libgit2/libgit2sharp/wiki/git-clone
            Repository.Clone(parsedUrl.repository, gitRepositoryLocalDirectory, new CloneOptions {
                Checkout = false
            });

            Composition.TreeComponent literalNodeObject = null;

            using (var gitRepository = new Repository(gitRepositoryLocalDirectory))
            {
                var commit = gitRepository.Lookup(parsedUrl.@ref) as Commit;

                if (commit == null)
                {
                    return new LoadFromUrlResult
                           {
                               Error = "I did not find the commit for ref '" + parsedUrl.@ref + "'.",
                           }
                }
                ;

                var pathNodesNames = parsedUrl.path.Split('/', StringSplitOptions.RemoveEmptyEntries);

                var findGitObjectResult =
                    FindGitObjectAtPath(commit.Tree, pathNodesNames);

                var linkedObject = findGitObjectResult?.Success;

                if (linkedObject == null)
                {
                    return new LoadFromUrlResult
                           {
                               Error = "I did not find an object at path '" + parsedUrl.path + "'.",
                           }
                }
                ;
Example #2
0
        static public LoadFromUrlResult LoadFromUrl(string sourceUrl)
        {
            var parsedUrl = ParseGitHubObjectUrl(sourceUrl);

            if (parsedUrl == null)
                return new LoadFromUrlResult
                {
                    Error = "Failed to parse string '" + sourceUrl + "' as GitHub object URL.",
                };

            var refLooksLikeCommit = Regex.IsMatch(parsedUrl.@ref, "[A-Fa-f0-9]{40}");

            var tempWorkingDirectory = Kalmit.Filesystem.CreateRandomDirectoryInTempDirectory();

            var gitRepositoryLocalDirectory = Path.Combine(tempWorkingDirectory, "git-repository");

            //  https://github.com/libgit2/libgit2sharp/wiki/git-clone
            Repository.Clone(parsedUrl.repository, gitRepositoryLocalDirectory, new CloneOptions { Checkout = false });

            Composition.TreeComponent literalNodeObject = null;
            string urlInCommit = null;
            string urlInFirstParentCommitWithSameValueAtThisPath = null;
            (string hash, CommitContent content)? rootCommit = null;
            (string hash, CommitContent content)? firstParentCommitWithSameTree = null;

            using (var gitRepository = new Repository(gitRepositoryLocalDirectory))
            {
                var commit = gitRepository.Lookup(parsedUrl.@ref) as Commit;

                if (commit == null)
                    return new LoadFromUrlResult
                    {
                        Error = "I did not find the commit for ref '" + parsedUrl.@ref + "'.",
                    };

                urlInCommit = BackToUrl(parsedUrl.WithRef(commit.Sha));

                rootCommit = GetCommitHashAndContent(commit);

                var pathNodesNames = parsedUrl.path.Split('/', StringSplitOptions.RemoveEmptyEntries);

                var findGitObjectResult =
                    FindGitObjectAtPath(commit.Tree, pathNodesNames);

                var linkedObject = findGitObjectResult?.Success;

                if (linkedObject == null)
                    return new LoadFromUrlResult
                    {
                        Error = "I did not find an object at path '" + parsedUrl.path + "'.",
                    };

                IEnumerable<Commit> traceBackTreeParents()
                {
                    var queue = new Queue<Commit>();

                    queue.Enqueue(commit);

                    while (queue.TryDequeue(out var currentCommit))
                    {
                        yield return currentCommit;

                        foreach (var parent in currentCommit.Parents)
                        {
                            if (FindGitObjectAtPath(parent.Tree, pathNodesNames)?.Success?.Sha != linkedObject?.Sha)
                                continue;

                            queue.Enqueue(parent);
                        }
                    }
                }

                firstParentCommitWithSameTree =
                    GetCommitHashAndContent(traceBackTreeParents().OrderBy(commit => commit.Author.When).First());

                urlInFirstParentCommitWithSameValueAtThisPath =
                    BackToUrl(parsedUrl.WithRef(firstParentCommitWithSameTree.Value.hash));