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 + "'.", } } ;
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));