/// <summary> /// Traverses all dependencies beginning in the given directory. /// </summary> /// <param name="visitor">The <see cref="IVisitor"/> that should be called at each dependency and project visit.</param> /// <param name="directory">The directory containing a GitDepend.json file.</param> public void TraverseDependencies(IVisitor visitor, string directory) { // Make sure we are working with something here. if (visitor == null || string.IsNullOrEmpty(directory)) { return; } directory = _fileSystem.Path.GetFullPath(directory); // If the directory doesn't exist we are done. if (!_fileSystem.Directory.Exists(directory)) { visitor.ReturnCode = ReturnCode.GitRepositoryNotFound; return; } string dir; ReturnCode code; var config = _factory.LoadFromDirectory(directory, out dir, out code); if (code != ReturnCode.Success) { visitor.ReturnCode = code; return; } foreach (var dependency in config.Dependencies) { dependency.Directory = _fileSystem.Path.GetFullPath(_fileSystem.Path.Combine(dir, dependency.Directory)); // If the dependency does not exist on disk we need to clone it. if (!_fileSystem.Directory.Exists(dependency.Directory)) { _console.WriteLine($"Cloning {dependency.Name} into {dependency.Directory}"); code = _git.Clone(dependency.Url, dependency.Directory, dependency.Branch); _console.WriteLine(); // If something went wrong with git we are done. if (code != ReturnCode.Success) { visitor.ReturnCode = code; return; } } // Visit all dependencies of this dependency. TraverseDependencies(visitor, dependency.Directory); // If something went wrong with a dependency we are done. if (visitor.ReturnCode != ReturnCode.Success) { return; } // Make sure to only visit dependencies once. if (!_visitedDependencies.Contains(dependency.Directory)) { _visitedDependencies.Add(dependency.Directory); // Visit the dependency. code = visitor.VisitDependency(dir, dependency); // If something went wrong visiting the dependency we are done. if (code != ReturnCode.Success) { visitor.ReturnCode = code; return; } } } // Make sure to only visit projects once. if (!_visitedProjects.Contains(dir)) { _visitedProjects.Add(dir); // Visit the project. code = visitor.VisitProject(dir, config); _console.WriteLine(); // If something went wrong visiting the project we are done. if (code != ReturnCode.Success) { visitor.ReturnCode = code; } } }
// throws ProcessException public void Process() { try { var srcRepo = git.OpenGitRepo(srcRepoPath); IGitRepo intermediateRepo; var intermediateRepoPath = config.GetIntermediateRepoPath(srcRepoPath); // 이미 리포지토리가 있으면 더 이상 진행하지 않는다 if (intermediateRepoPath == null) { intermediateRepoPath = MakeNewIntermidateRepoPath(srcRepoPath); // 클론 시켜서 임시저장소를 하나 더 만든다 git.Clone(srcRepoPath, intermediateRepoPath); config.AddIntermediateRepo(srcRepoPath, intermediateRepoPath); intermediateRepo = git.OpenGitRepo(intermediateRepoPath); } else { intermediateRepo = git.OpenGitRepo(intermediateRepoPath); } // var branchName = srcRepo.GetCurrentBranchName(); // branchName에 auto자가 붙으면 저장하지 않는다 if (branchName.StartsWith("autosave/")) { throw new ProcessException(ProcessException.Reason.WorkingOnAutosaveBranch); } intermediateRepo.FetchBranch("origin", branchName); var autosaveBranchName = $"autosave/{branchName}"; if (intermediateRepo.BranchExists(autosaveBranchName)) { // git checkout autosave/master intermediateRepo.CheckoutBranch(autosaveBranchName); } else { // git checkout -b autosave/master --track origin/master intermediateRepo.CheckoutNewBranchTrackingOriginBranch(autosaveBranchName, branchName); } intermediateRepo.MergeOurs("origin", branchName); intermediateRepo.ReadTree("origin", branchName); MirrorWorkingTree(srcRepo, srcRepoPath, intermediateRepoPath, true); intermediateRepo.AddAll(); // DateTime. intermediateRepo.Commit($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} {branchName}"); intermediateRepo.PushBranch("origin", autosaveBranchName); } catch (GitCloneException) { throw new ProcessException(ProcessException.Reason.CloneFailed); } catch { throw new UnreachableCodeException(); } }