NuGitRepository(NuGitWorkspace workspace, GitRepositoryName name) : base( IOPath.Combine( Guard.NotNull(workspace, nameof(workspace)).RootPath, Guard.NotNull(name, nameof(name)))) { Workspace = workspace; }
Traverse( NuGitWorkspace workspace, IEnumerable <Dependency> dependencies, NuGitRepository requiredBy, IDictionary <GitRepositoryName, GitCommitName> checkedOut, ISet <GitRepositoryName> visited, Action <Dependency, NuGitRepository> onVisited ) { Guard.NotNull(workspace, nameof(workspace)); Guard.NotNull(dependencies, nameof(dependencies)); Guard.NotNull(checkedOut, nameof(checkedOut)); Guard.NotNull(visited, nameof(visited)); Guard.NotNull(onVisited, nameof(onVisited)); var unvisited = dependencies.Where(d => !visited.Contains(d.Url.RepositoryName)).ToList().AsReadOnly(); // // Clone any dependency repos that aren't present // foreach (var d in unvisited) { if (workspace.FindRepository(d.Url.RepositoryName) != null) { continue; } Clone(workspace.RootPath, d.Url); } // // Visit each dependency // foreach (var d in dependencies) { var name = d.Url.RepositoryName; var repo = workspace.GetRepository(name); var commit = d.CommitName; checkedOut.TryGetValue(name, out var checkedOutCommit); // // First visit wins // if (checkedOutCommit == null) { using (LogicalOperation.Start($"Restoring {d.Url.RepositoryName} to {d.CommitName}")) { var commitId = repo.GetCommitId(commit); var headId = repo.GetCommitId(); var isCheckedOutToCommit = headId == commitId; var hasUncommittedChanges = repo.HasUncommittedChanges(); if (repo.HasUncommittedChanges()) { Trace.TraceError("Uncommitted changes"); throw new UserException($"Uncommitted changes in {name}"); } else if (isCheckedOutToCommit) { Trace.TraceInformation($"Already checked out"); } else { CheckOut(repo, commit); } checkedOut.Add(name, commit); visited.Add(name); onVisited(d, repo); continue; } } // // Subsequent visits specifying different commits get a warning // if (commit != checkedOutCommit) { Trace.TraceWarning( StringExtensions.FormatInvariant( "{0} depends on {1}#{2} but #{3} has already been checked out", requiredBy.Name, name, commit, checkedOutCommit)); continue; } // // Subsequent visits specifying the same commit do nothing // } // // Recurse // foreach (var d in unvisited) { var name = d.Url.RepositoryName; var repo = workspace.FindRepository(name); Traverse( workspace, repo.ReadDotNuGit().Dependencies, repo, checkedOut, visited, onVisited); } }