예제 #1
0
        private bool TryMount(ITracer tracer, GSDEnlistment enlistment, string mountExecutableLocation, out string errorMessage)
        {
            if (!GSDVerb.TrySetRequiredGitConfigSettings(enlistment))
            {
                errorMessage = "Unable to configure git repo";
                return(false);
            }

            const string ParamPrefix = "--";

            tracer.RelatedInfo($"{nameof(this.TryMount)}: Launching background process('{mountExecutableLocation}') for {enlistment.EnlistmentRoot}");

            GSDPlatform.Instance.StartBackgroundVFS4GProcess(
                tracer,
                mountExecutableLocation,
                new[]
            {
                enlistment.EnlistmentRoot,
                ParamPrefix + GSDConstants.VerbParameters.Mount.Verbosity,
                this.Verbosity,
                ParamPrefix + GSDConstants.VerbParameters.Mount.Keywords,
                this.KeywordsCsv,
                ParamPrefix + GSDConstants.VerbParameters.Mount.StartedByService,
                this.StartedByService.ToString(),
                ParamPrefix + GSDConstants.VerbParameters.Mount.StartedByVerb,
                true.ToString()
            });

            tracer.RelatedInfo($"{nameof(this.TryMount)}: Waiting for repo to be mounted");
            return(GSDEnlistment.WaitUntilMounted(tracer, enlistment.EnlistmentRoot, this.Unattended, out errorMessage));
        }
예제 #2
0
        private Result CreateClone(
            ITracer tracer,
            GSDEnlistment enlistment,
            GitObjectsHttpRequestor objectRequestor,
            GitRefs refs,
            string branch)
        {
            Result initRepoResult = this.TryInitRepo(tracer, refs, enlistment);

            if (!initRepoResult.Success)
            {
                return(initRepoResult);
            }

            PhysicalFileSystem fileSystem = new PhysicalFileSystem();
            string             errorMessage;

            if (!this.TryCreateAlternatesFile(fileSystem, enlistment, out errorMessage))
            {
                return(new Result("Error configuring alternate: " + errorMessage));
            }

            GitRepo       gitRepo    = new GitRepo(tracer, enlistment, fileSystem);
            GSDContext    context    = new GSDContext(tracer, fileSystem, gitRepo, enlistment);
            GSDGitObjects gitObjects = new GSDGitObjects(context, objectRequestor);

            if (!this.TryDownloadCommit(
                    refs.GetTipCommitId(branch),
                    enlistment,
                    objectRequestor,
                    gitObjects,
                    gitRepo,
                    out errorMessage))
            {
                return(new Result(errorMessage));
            }

            if (!GSDVerb.TrySetRequiredGitConfigSettings(enlistment) ||
                !GSDVerb.TrySetOptionalGitConfigSettings(enlistment))
            {
                return(new Result("Unable to configure git repo"));
            }

            CacheServerResolver cacheServerResolver = new CacheServerResolver(tracer, enlistment);

            if (!cacheServerResolver.TrySaveUrlToLocalConfig(objectRequestor.CacheServer, out errorMessage))
            {
                return(new Result("Unable to configure cache server: " + errorMessage));
            }

            GitProcess git = new GitProcess(enlistment);
            string     originBranchName = "origin/" + branch;

            GitProcess.Result createBranchResult = git.CreateBranchWithUpstream(branch, originBranchName);
            if (createBranchResult.ExitCodeIsFailure)
            {
                return(new Result("Unable to create branch '" + originBranchName + "': " + createBranchResult.Errors + "\r\n" + createBranchResult.Output));
            }

            File.WriteAllText(
                Path.Combine(enlistment.WorkingDirectoryBackingRoot, GSDConstants.DotGit.Head),
                "ref: refs/heads/" + branch);

            if (!this.TryDownloadRootGitAttributes(enlistment, gitObjects, gitRepo, out errorMessage))
            {
                return(new Result(errorMessage));
            }

            this.CreateGitScript(enlistment);

            string installHooksError;

            if (!HooksInstaller.InstallHooks(context, out installHooksError))
            {
                tracer.RelatedError(installHooksError);
                return(new Result(installHooksError));
            }

            // TODO: Move this to be after the mount?
            GitProcess.Result forceCheckoutResult = git.ForceCheckout(branch);
            if (forceCheckoutResult.ExitCodeIsFailure && forceCheckoutResult.Errors.IndexOf("unable to read tree") > 0)
            {
                // It is possible to have the above TryDownloadCommit() fail because we
                // already have the commit and root tree we intend to check out, but
                // don't have a tree further down the working directory. If we fail
                // checkout here, its' because we don't have these trees and the
                // read-object hook is not available yet. Force downloading the commit
                // again and retry the checkout.

                if (!this.TryDownloadCommit(
                        refs.GetTipCommitId(branch),
                        enlistment,
                        objectRequestor,
                        gitObjects,
                        gitRepo,
                        out errorMessage,
                        checkLocalObjectCache: false))
                {
                    return(new Result(errorMessage));
                }

                forceCheckoutResult = git.ForceCheckout(branch);
            }

            if (!RepoMetadata.TryInitialize(tracer, enlistment.DotGSDRoot, out errorMessage))
            {
                tracer.RelatedError(errorMessage);
                return(new Result(errorMessage));
            }

            try
            {
                RepoMetadata.Instance.SaveCloneMetadata(tracer, enlistment);
                this.LogEnlistmentInfoAndSetConfigValues(tracer, git, enlistment);
            }
            catch (Exception e)
            {
                tracer.RelatedError(e.ToString());
                return(new Result(e.Message));
            }
            finally
            {
                RepoMetadata.Shutdown();
            }

            return(new Result(true));
        }