Esempio n. 1
0
        private Result GitClone()
        {
            string gitBinPath = ScalarPlatform.Instance.GitInstallation.GetInstalledGitBinPath();

            if (string.IsNullOrWhiteSpace(gitBinPath))
            {
                return(new Result(ScalarConstants.GitIsNotInstalledError));
            }

            GitProcess git = new GitProcess(this.enlistment);

            // protocol.version=2 is broken right now.
            git.SetInLocalConfig("protocol.version", "1");

            git.SetInLocalConfig("remote.origin.url", this.RepositoryURL);
            git.SetInLocalConfig("remote.origin.fetch", "+refs/heads/*:refs/remotes/origin/*");
            git.SetInLocalConfig("remote.origin.promisor", "true");
            git.SetInLocalConfig("remote.origin.partialCloneFilter", "blob:none");

            string branch = this.Branch ?? "master";

            git.SetInLocalConfig($"branch.{branch}.remote", "origin");
            git.SetInLocalConfig($"branch.{branch}.merge", $"refs/heads/{branch}");

            if (!this.FullClone)
            {
                GitProcess.SparseCheckoutInit(this.enlistment);
            }

            this.context = new ScalarContext(this.tracer, this.fileSystem, this.enlistment);

            // Set required and optional config.
            // Explicitly pass useGvfsProtocol: true as the enlistment can not discover that setting from
            // Git config yet. Other verbs will discover this automatically from the config we set now.
            ConfigStep configStep = new ConfigStep(this.context, useGvfsProtocol: false);

            if (!configStep.TrySetConfig(out string configError))
            {
                return(new Result($"Failed to set initial config: {configError}"));
            }

            GitProcess.Result fetchResult = null;
            if (!this.ShowStatusWhileRunning(() =>
            {
                using (ITracer activity = this.tracer.StartActivity("git-fetch-partial", EventLevel.LogAlways))
                {
                    fetchResult = git.ForegroundFetch("origin");
                    return(fetchResult.ExitCodeIsSuccess);
                }
            },
                                             "Fetching objects from remote"))
            {
                if (!fetchResult.Errors.Contains("filtering not recognized by server"))
                {
                    return(new Result($"Failed to complete regular clone: {fetchResult?.Errors}"));
                }
            }

            if (fetchResult.ExitCodeIsFailure &&
                !this.ShowStatusWhileRunning(() =>
            {
                using (ITracer activity = this.tracer.StartActivity("git-fetch", EventLevel.LogAlways))
                {
                    git.DeleteFromLocalConfig("remote.origin.promisor");
                    git.DeleteFromLocalConfig("remote.origin.partialCloneFilter");
                    fetchResult = git.ForegroundFetch("origin");
                    return(fetchResult.ExitCodeIsSuccess);
                }
            },
                                             "Fetching objects from remote"))
            {
                return(new Result($"Failed to complete regular clone: {fetchResult?.Errors}"));
            }

            GitProcess.Result checkoutResult = null;

            if (!this.ShowStatusWhileRunning(() =>
            {
                using (ITracer activity = this.tracer.StartActivity("git-checkout", EventLevel.LogAlways))
                {
                    checkoutResult = git.ForceCheckout(branch);
                    return(checkoutResult.ExitCodeIsSuccess);
                }
            },
                                             $"Checking out '{branch}'"))
            {
                return(new Result($"Failed to complete regular clone: {checkoutResult?.Errors}"));
            }
            return(new Result(true));
        }