Esempio n. 1
0
        private void PrefetchCommits(ITracer tracer, GSDEnlistment enlistment, GitObjectsHttpRequestor objectRequestor, CacheServerInfo cacheServer)
        {
            bool               success;
            string             error      = string.Empty;
            PhysicalFileSystem fileSystem = new PhysicalFileSystem();
            GitRepo            repo       = new GitRepo(tracer, enlistment, fileSystem);
            GSDContext         context    = new GSDContext(tracer, fileSystem, repo, enlistment);
            GitObjects         gitObjects = new GSDGitObjects(context, objectRequestor);

            if (this.Verbose)
            {
                success = new PrefetchStep(context, gitObjects, requireCacheLock: false).TryPrefetchCommitsAndTrees(out error);
            }
            else
            {
                success = this.ShowStatusWhileRunning(
                    () => new PrefetchStep(context, gitObjects, requireCacheLock: false).TryPrefetchCommitsAndTrees(out error),
                    "Fetching commits and trees " + this.GetCacheServerDisplay(cacheServer, enlistment.RepoUrl));
            }

            if (!success)
            {
                this.ReportErrorAndExit(tracer, "Prefetching commits and trees failed: " + error);
            }
        }
Esempio n. 2
0
        public override bool TryInstallGitCommandHooks(GSDContext context, string executingDirectory, string hookName, string commandHookPath, out string errorMessage)
        {
            // The GitHooksLoader requires the following setup to invoke a hook:
            //      Copy GithooksLoader.exe to hook-name.exe
            //      Create a text file named hook-name.hooks that lists the applications to execute for the hook, one application per line

            string gitHooksloaderPath = Path.Combine(executingDirectory, GSDConstants.DotGit.Hooks.LoaderExecutable);

            if (!HooksInstaller.TryHooksInstallationAction(
                    () => HooksInstaller.CopyHook(context, gitHooksloaderPath, commandHookPath + GSDPlatform.Instance.Constants.ExecutableExtension),
                    out errorMessage))
            {
                errorMessage = "Failed to copy " + GSDConstants.DotGit.Hooks.LoaderExecutable + " to " + commandHookPath + GSDPlatform.Instance.Constants.ExecutableExtension + "\n" + errorMessage;
                return(false);
            }

            if (!HooksInstaller.TryHooksInstallationAction(
                    () => WindowsGitHooksInstaller.CreateHookCommandConfig(context, hookName, commandHookPath),
                    out errorMessage))
            {
                errorMessage = "Failed to create " + commandHookPath + GSDConstants.GitConfig.HooksExtension + "\n" + errorMessage;
                return(false);
            }

            return(true);
        }
        private void TestSetup()
        {
            ITracer            tracer     = new MockTracer();
            GSDEnlistment      enlistment = new MockGSDEnlistment();
            PhysicalFileSystem fileSystem = new MockFileSystem(new MockDirectory(enlistment.EnlistmentRoot, null, null));

            this.context = new GSDContext(tracer, fileSystem, null, enlistment);
        }
        public GitMaintenanceScheduler(GSDContext context, GitObjects gitObjects)
        {
            this.context    = context;
            this.gitObjects = gitObjects;
            this.stepTimers = new List <Timer>();
            this.queue      = new GitMaintenanceQueue(context);

            this.ScheduleRecurringSteps();
        }
 public LooseObjectsStep(
     GSDContext context,
     bool requireCacheLock = true,
     bool forceRun         = false,
     GitProcessChecker gitProcessChecker = null)
     : base(context, requireCacheLock, gitProcessChecker)
 {
     this.forceRun = forceRun;
 }
Esempio n. 6
0
 public void TearDown()
 {
     this.fileSystem          = null;
     this.gitProcess          = null;
     this.context             = null;
     this.gitParentPath       = null;
     this.gvfsMetadataPath    = null;
     this.enlistmentDirectory = null;
 }
Esempio n. 7
0
        public static void CopyHook(GSDContext context, string sourcePath, string destinationPath)
        {
            Exception ex;

            if (!context.FileSystem.TryCopyToTempFileAndRename(sourcePath, destinationPath, out ex))
            {
                throw new RetryableException($"Error installing {sourcePath} to {destinationPath}", ex);
            }
        }
        public GitMaintenanceQueue(GSDContext context)
        {
            this.context = context;
            Thread worker = new Thread(() => this.RunQueue());

            worker.Name         = "MaintenanceWorker";
            worker.IsBackground = true;
            worker.Start();
        }
Esempio n. 9
0
 public PackfileMaintenanceStep(
     GSDContext context,
     bool requireObjectCacheLock = true,
     bool forceRun    = false,
     string batchSize = DefaultBatchSize,
     GitProcessChecker gitProcessChecker = null)
     : base(context, requireObjectCacheLock, gitProcessChecker)
 {
     this.forceRun  = forceRun;
     this.batchSize = batchSize;
 }
        private GSDGitObjects CreateTestableGSDGitObjects(MockHttpGitObjects httpObjects, MockFileSystemWithCallbacks fileSystem)
        {
            MockTracer    tracer     = new MockTracer();
            GSDEnlistment enlistment = new GSDEnlistment(TestEnlistmentRoot, "https://fakeRepoUrl", "fakeGitBinPath", gvfsHooksRoot: null, authentication: null);

            enlistment.InitializeCachePathsFromKey(TestLocalCacheRoot, TestObjectRoot);
            GitRepo repo = new GitRepo(tracer, enlistment, fileSystem, () => new MockLibGit2Repo(tracer));

            GSDContext    context = new GSDContext(tracer, fileSystem, repo, enlistment);
            GSDGitObjects dut     = new GSDGitObjects(context, httpObjects);

            return(dut);
        }
Esempio n. 11
0
        public static bool TryUpdateHooks(GSDContext context, out string errorMessage)
        {
            errorMessage = string.Empty;
            foreach (HookData hook in NativeHooks)
            {
                if (!TryUpdateHook(context, hook, out errorMessage))
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 12
0
        private void TestSetup()
        {
            this.gitProcess = new MockGitProcess();

            // Create enlistment using git process
            GSDEnlistment enlistment = new MockGSDEnlistment(this.gitProcess);

            PhysicalFileSystem fileSystem = new MockFileSystem(new MockDirectory(enlistment.EnlistmentRoot, null, null));

            // Create and return Context
            this.tracer  = new MockTracer();
            this.context = new GSDContext(this.tracer, fileSystem, repository: null, enlistment: enlistment);
        }
Esempio n. 13
0
        public override bool TryInstallGitCommandHooks(GSDContext context, string executingDirectory, string hookName, string commandHookPath, out string errorMessage)
        {
            errorMessage = null;

            string gvfsHooksPath = Path.Combine(executingDirectory, GSDPlatform.Instance.Constants.GSDHooksExecutableName);

            File.WriteAllText(
                commandHookPath,
                $"#!/bin/sh\n{gvfsHooksPath} {hookName} \"$@\"");
            GSDPlatform.Instance.FileSystem.ChangeMode(commandHookPath, Convert.ToUInt16("755", 8));

            return(true);
        }
        private static string MergeHooks(GSDContext context, string configSettingName, string hookName)
        {
            GitProcess configProcess = new GitProcess(context.Enlistment);
            string     filename;

            string[] defaultHooksLines = { };

            if (configProcess.TryGetFromConfig(configSettingName, forceOutsideEnlistment: true, value: out filename) && filename != null)
            {
                filename          = filename.Trim(' ', '\n');
                defaultHooksLines = File.ReadAllLines(filename);
            }

            return(HooksInstaller.MergeHooksData(defaultHooksLines, filename, hookName));
        }
Esempio n. 15
0
        private void TestSetup()
        {
            ITracer tracer = new MockTracer();

            this.enlistment = new MockGSDEnlistment();

            // We need to have the EnlistmentRoot and GitObjectsRoot available for jobs to run
            this.fileSystem = new ReadyFileSystem(new string[]
            {
                this.enlistment.EnlistmentRoot,
                this.enlistment.GitObjectsRoot
            });

            this.context    = new GSDContext(tracer, this.fileSystem, null, this.enlistment);
            this.gitObjects = new MockPhysicalGitObjects(tracer, this.fileSystem, this.enlistment, null);
        }
        public static void CreateHookCommandConfig(GSDContext context, string hookName, string commandHookPath)
        {
            string targetPath = commandHookPath + GSDConstants.GitConfig.HooksExtension;

            try
            {
                string configSetting = GSDConstants.GitConfig.HooksPrefix + hookName;
                string mergedHooks   = MergeHooks(context, configSetting, hookName);

                string    contents = string.Format(HooksConfigContentTemplate, configSetting, mergedHooks);
                Exception ex;
                if (!context.FileSystem.TryWriteTempFileAndRename(targetPath, contents, out ex))
                {
                    throw new RetryableException("Error installing " + targetPath, ex);
                }
            }
            catch (IOException io)
            {
                throw new RetryableException("Error installing " + targetPath, io);
            }
        }
Esempio n. 17
0
        public void SetUp()
        {
            MockTracer tracer = new MockTracer();

            string enlistmentRoot  = Path.Combine("mock:", "GSD", "UnitTests", "Repo");
            string statusCachePath = Path.Combine("mock:", "GSD", "UnitTests", "Repo", GSDPlatform.Instance.Constants.DotGSDRoot, "gitStatusCache");

            this.gitProcess = new MockGitProcess();
            this.gitProcess.SetExpectedCommandResult($"--no-optional-locks status \"--serialize={statusCachePath}", () => new GitProcess.Result(string.Empty, string.Empty, 0), true);
            MockGSDEnlistment enlistment = new MockGSDEnlistment(enlistmentRoot, "fake://repoUrl", "fake://gitBinPath", null, this.gitProcess);

            enlistment.InitializeCachePathsFromKey("fake:\\gvfsSharedCache", "fakeCacheKey");

            this.gitParentPath    = enlistment.WorkingDirectoryBackingRoot;
            this.gvfsMetadataPath = enlistment.DotGSDRoot;

            this.enlistmentDirectory = new MockDirectory(
                enlistmentRoot,
                new MockDirectory[]
            {
                new MockDirectory(this.gitParentPath, folders: null, files: null),
            },
                null);

            this.enlistmentDirectory.CreateFile(Path.Combine(this.gitParentPath, ".git", "config"), ".git config Contents", createDirectories: true);
            this.enlistmentDirectory.CreateFile(Path.Combine(this.gitParentPath, ".git", "HEAD"), ".git HEAD Contents", createDirectories: true);
            this.enlistmentDirectory.CreateFile(Path.Combine(this.gitParentPath, ".git", "logs", "HEAD"), "HEAD Contents", createDirectories: true);
            this.enlistmentDirectory.CreateFile(Path.Combine(this.gitParentPath, ".git", "info", "always_exclude"), "always_exclude Contents", createDirectories: true);
            this.enlistmentDirectory.CreateDirectory(Path.Combine(this.gitParentPath, ".git", "objects", "pack"));

            this.fileSystem = new MockFileSystem(this.enlistmentDirectory);
            this.fileSystem.AllowMoveFile = true;
            this.fileSystem.DeleteNonExistentFileThrowsException = false;

            this.context = new GSDContext(
                tracer,
                this.fileSystem,
                new MockGitRepo(tracer, enlistment, this.fileSystem),
                enlistment);
        }
Esempio n. 18
0
        public static bool InstallHooks(GSDContext context, out string error)
        {
            error = string.Empty;
            try
            {
                foreach (HookData hook in NativeHooks)
                {
                    string installedHookPath = Path.Combine(ExecutingDirectory, hook.ExecutableName);
                    string targetHookPath    = Path.Combine(context.Enlistment.WorkingDirectoryBackingRoot, hook.Path + GSDPlatform.Instance.Constants.ExecutableExtension);
                    if (!TryHooksInstallationAction(() => CopyHook(context, installedHookPath, targetHookPath), out error))
                    {
                        error = "Failed to copy " + installedHookPath + "\n" + error;
                        return(false);
                    }
                }
            }
            catch (Exception e)
            {
                error = e.ToString();
                return(false);
            }

            return(true);
        }
Esempio n. 19
0
 public PrefetchStep(GSDContext context, GitObjects gitObjects, bool requireCacheLock = true)
     : base(context, requireCacheLock)
 {
     this.GitObjects = gitObjects;
 }
Esempio n. 20
0
        protected override void Execute(GSDEnlistment enlistment)
        {
            string errorMessage            = null;
            string mountExecutableLocation = null;

            using (JsonTracer tracer = new JsonTracer(GSDConstants.GSDEtwProviderName, "ExecuteMount"))
            {
                PhysicalFileSystem fileSystem = new PhysicalFileSystem();
                GitRepo            gitRepo    = new GitRepo(tracer, enlistment, fileSystem);
                GSDContext         context    = new GSDContext(tracer, fileSystem, gitRepo, enlistment);

                if (!HooksInstaller.InstallHooks(context, out errorMessage))
                {
                    this.ReportErrorAndExit("Error installing hooks: " + errorMessage);
                }

                CacheServerInfo cacheServer = this.ResolvedCacheServer ?? CacheServerResolver.GetCacheServerFromConfig(enlistment);

                tracer.AddLogFileEventListener(
                    GSDEnlistment.GetNewGSDLogFileName(enlistment.GSDLogsRoot, GSDConstants.LogFileTypes.MountVerb),
                    EventLevel.Verbose,
                    Keywords.Any);
                tracer.WriteStartEvent(
                    enlistment.EnlistmentRoot,
                    enlistment.RepoUrl,
                    cacheServer.Url,
                    new EventMetadata
                {
                    { "Unattended", this.Unattended },
                    { "IsElevated", GSDPlatform.Instance.IsElevated() },
                    { "NamedPipeName", enlistment.NamedPipeName },
                    { nameof(this.EnlistmentRootPathParameter), this.EnlistmentRootPathParameter },
                });

                RetryConfig     retryConfig     = null;
                ServerGSDConfig serverGSDConfig = this.DownloadedGSDConfig;
                if (!this.SkipVersionCheck)
                {
                    string authErrorMessage;
                    if (!this.TryAuthenticate(tracer, enlistment, out authErrorMessage))
                    {
                        this.Output.WriteLine("    WARNING: " + authErrorMessage);
                        this.Output.WriteLine("    Mount will proceed, but new files cannot be accessed until GSD can authenticate.");
                    }

                    if (serverGSDConfig == null)
                    {
                        if (retryConfig == null)
                        {
                            retryConfig = this.GetRetryConfig(tracer, enlistment);
                        }

                        serverGSDConfig = this.QueryGSDConfig(tracer, enlistment, retryConfig);
                    }

                    this.ValidateClientVersions(tracer, enlistment, serverGSDConfig, showWarnings: true);

                    CacheServerResolver cacheServerResolver = new CacheServerResolver(tracer, enlistment);
                    cacheServer = cacheServerResolver.ResolveNameFromRemote(cacheServer.Url, serverGSDConfig);
                    this.Output.WriteLine("Configured cache server: " + cacheServer);
                }

                this.InitializeLocalCacheAndObjectsPaths(tracer, enlistment, retryConfig, serverGSDConfig, cacheServer);

                if (!this.ShowStatusWhileRunning(
                        () => { return(this.PerformPreMountValidation(tracer, enlistment, out mountExecutableLocation, out errorMessage)); },
                        "Validating repo"))
                {
                    this.ReportErrorAndExit(tracer, errorMessage);
                }

                if (!this.SkipVersionCheck)
                {
                    string error;
                    if (!RepoMetadata.TryInitialize(tracer, enlistment.DotGSDRoot, out error))
                    {
                        this.ReportErrorAndExit(tracer, error);
                    }

                    try
                    {
                        GitProcess git = new GitProcess(enlistment);
                        this.LogEnlistmentInfoAndSetConfigValues(tracer, git, enlistment);
                    }
                    finally
                    {
                        RepoMetadata.Shutdown();
                    }
                }

                if (!this.ShowStatusWhileRunning(
                        () => { return(this.TryMount(tracer, enlistment, mountExecutableLocation, out errorMessage)); },
                        "Mounting"))
                {
                    this.ReportErrorAndExit(tracer, errorMessage);
                }

                if (!this.Unattended)
                {
                    tracer.RelatedInfo($"{nameof(this.Execute)}: Registering for automount");

                    if (this.ShowStatusWhileRunning(
                            () => { return(this.RegisterMount(enlistment, out errorMessage)); },
                            "Registering for automount"))
                    {
                        tracer.RelatedInfo($"{nameof(this.Execute)}: Registered for automount");
                    }
                    else
                    {
                        this.Output.WriteLine("    WARNING: " + errorMessage);
                        tracer.RelatedInfo($"{nameof(this.Execute)}: Failed to register for automount");
                    }
                }
            }
        }
Esempio n. 21
0
        public void Mount(EventLevel verbosity, Keywords keywords)
        {
            this.currentState = MountState.Mounting;

            // We must initialize repo metadata before starting the pipe server so it
            // can immediately handle status requests
            string error;

            if (!RepoMetadata.TryInitialize(this.tracer, this.enlistment.DotGSDRoot, out error))
            {
                this.FailMountAndExit("Failed to load repo metadata: " + error);
            }

            string gitObjectsRoot;

            if (!RepoMetadata.Instance.TryGetGitObjectsRoot(out gitObjectsRoot, out error))
            {
                this.FailMountAndExit("Failed to determine git objects root from repo metadata: " + error);
            }

            string localCacheRoot;

            if (!RepoMetadata.Instance.TryGetLocalCacheRoot(out localCacheRoot, out error))
            {
                this.FailMountAndExit("Failed to determine local cache path from repo metadata: " + error);
            }

            string blobSizesRoot;

            if (!RepoMetadata.Instance.TryGetBlobSizesRoot(out blobSizesRoot, out error))
            {
                this.FailMountAndExit("Failed to determine blob sizes root from repo metadata: " + error);
            }

            this.tracer.RelatedEvent(
                EventLevel.Informational,
                "CachePathsLoaded",
                new EventMetadata
            {
                { "gitObjectsRoot", gitObjectsRoot },
                { "localCacheRoot", localCacheRoot },
                { "blobSizesRoot", blobSizesRoot },
            });

            this.enlistment.InitializeCachePaths(localCacheRoot, gitObjectsRoot, blobSizesRoot);

            using (NamedPipeServer pipeServer = this.StartNamedPipe())
            {
                this.tracer.RelatedEvent(
                    EventLevel.Informational,
                    $"{nameof(this.Mount)}_StartedNamedPipe",
                    new EventMetadata {
                    { "NamedPipeName", this.enlistment.NamedPipeName }
                });

                this.context = this.CreateContext();

                if (this.context.Unattended)
                {
                    this.tracer.RelatedEvent(EventLevel.Critical, GSDConstants.UnattendedEnvironmentVariable, null);
                }

                this.ValidateMountPoints();

                string errorMessage;
                if (!HooksInstaller.TryUpdateHooks(this.context, out errorMessage))
                {
                    this.FailMountAndExit(errorMessage);
                }

                GSDPlatform.Instance.ConfigureVisualStudio(this.enlistment.GitBinPath, this.tracer);

                this.MountAndStartWorkingDirectoryCallbacks(this.cacheServer);

                Console.Title = "GSD " + ProcessHelper.GetCurrentProcessVersion() + " - " + this.enlistment.EnlistmentRoot;

                this.tracer.RelatedEvent(
                    EventLevel.Informational,
                    "Mount",
                    new EventMetadata
                {
                    // Use TracingConstants.MessageKey.InfoMessage rather than TracingConstants.MessageKey.CriticalMessage
                    // as this message should not appear as an error
                    { TracingConstants.MessageKey.InfoMessage, "Virtual repo is ready" },
                },
                    Keywords.Telemetry);

                this.currentState = MountState.Ready;

                this.unmountEvent.WaitOne();
            }
        }
Esempio n. 22
0
        private void TestSetup(DateTime lastRun)
        {
            string lastRunTime = EpochConverter.ToUnixEpochSeconds(lastRun).ToString();

            // Create GitProcess
            this.gitProcess = new MockGitProcess();
            this.gitProcess.SetExpectedCommandResult(
                PrunePackedCommand,
                () => new GitProcess.Result(string.Empty, string.Empty, GitProcess.Result.SuccessCode));

            // Create enlistment using git process
            GSDEnlistment enlistment = new MockGSDEnlistment(this.gitProcess);

            string packPrefix = Path.Combine(enlistment.GitPackRoot, "from-loose");

            this.packCommand = $"pack-objects {packPrefix} --non-empty --window=0 --depth=0 -q";

            this.gitProcess.SetExpectedCommandResult(
                this.packCommand,
                () => new GitProcess.Result(string.Empty, string.Empty, GitProcess.Result.SuccessCode));

            // Create a last run time file
            MockFile timeFile = new MockFile(Path.Combine(enlistment.GitObjectsRoot, "info", LooseObjectsStep.LooseObjectsLastRunFileName), lastRunTime);

            // Create info directory to hold last run time file
            MockDirectory infoRoot = new MockDirectory(Path.Combine(enlistment.GitObjectsRoot, "info"), null, new List <MockFile>()
            {
                timeFile
            });

            // Create Hex Folder 1 with 1 File
            MockDirectory hex1 = new MockDirectory(
                Path.Combine(enlistment.GitObjectsRoot, "AA"),
                null,
                new List <MockFile>()
            {
                new MockFile(Path.Combine(enlistment.GitObjectsRoot, "AA", "1156f4f2b850673090c285289ea8475d629fe1"), "one")
            });

            // Create Hex Folder 2 with 2 Files
            MockDirectory hex2 = new MockDirectory(
                Path.Combine(enlistment.GitObjectsRoot, "F1"),
                null,
                new List <MockFile>()
            {
                new MockFile(Path.Combine(enlistment.GitObjectsRoot, "F1", "1156f4f2b850673090c285289ea8475d629fe2"), "two"),
                new MockFile(Path.Combine(enlistment.GitObjectsRoot, "F1", "1156f4f2b850673090c285289ea8475d629fe3"), "three")
            });

            // Create NonHex Folder with 4 Files
            MockDirectory nonhex = new MockDirectory(
                Path.Combine(enlistment.GitObjectsRoot, "ZZ"),
                null,
                new List <MockFile>()
            {
                new MockFile(Path.Combine(enlistment.GitObjectsRoot, "ZZ", "1156f4f2b850673090c285289ea8475d629fe4"), "4"),
                new MockFile(Path.Combine(enlistment.GitObjectsRoot, "ZZ", "1156f4f2b850673090c285289ea8475d629fe5"), "5"),
                new MockFile(Path.Combine(enlistment.GitObjectsRoot, "ZZ", "1156f4f2b850673090c285289ea8475d629fe6"), "6"),
                new MockFile(Path.Combine(enlistment.GitObjectsRoot, "ZZ", "1156f4f2b850673090c285289ea8475d629fe7"), "7")
            });

            MockDirectory pack = new MockDirectory(
                enlistment.GitPackRoot,
                null,
                new List <MockFile>());

            // Create git objects directory
            MockDirectory gitObjectsRoot = new MockDirectory(enlistment.GitObjectsRoot, new List <MockDirectory>()
            {
                infoRoot, hex1, hex2, nonhex, pack
            }, null);

            // Add object directory to file System
            List <MockDirectory> directories = new List <MockDirectory>()
            {
                gitObjectsRoot
            };
            PhysicalFileSystem fileSystem = new MockFileSystem(new MockDirectory(enlistment.EnlistmentRoot, directories, null));

            // Create and return Context
            this.tracer  = new MockTracer();
            this.context = new GSDContext(this.tracer, fileSystem, repository: null, enlistment: enlistment);
        }
Esempio n. 23
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));
        }
Esempio n. 24
0
 public WatchForStopStep(GitMaintenanceQueue queue, GSDContext context)
     : base(context, requireObjectCacheLock: true)
 {
     this.Queue          = queue;
     this.EventTriggered = new ManualResetEvent(false);
 }
Esempio n. 25
0
 public TestGitMaintenanceStep(GSDContext context)
     : base(context, requireObjectCacheLock: true)
 {
     this.EventTriggered = new ManualResetEvent(initialState: false);
 }
Esempio n. 26
0
 public MockGitStatusCache(GSDContext context, TimeSpan backoff)
     : base(context, backoff)
 {
 }
 public CheckMethodStep(GSDContext context, WhenToStop when)
     : base(context, requireObjectCacheLock: true)
 {
     this.when = when;
 }
Esempio n. 28
0
 public PostFetchStep(GSDContext context, List <string> packIndexes, bool requireObjectCacheLock = true)
     : base(context, requireObjectCacheLock)
 {
     this.packIndexes = packIndexes;
 }
Esempio n. 29
0
 public GitMaintenanceStep(GSDContext context, bool requireObjectCacheLock, GitProcessChecker gitProcessChecker = null)
 {
     this.Context = context;
     this.RequireObjectCacheLock = requireObjectCacheLock;
     this.GitProcessChecker      = gitProcessChecker ?? new GitProcessChecker();
 }
        private void TestSetup(DateTime lastRun, bool failOnVerify = false)
        {
            string lastRunTime = EpochConverter.ToUnixEpochSeconds(lastRun).ToString();

            this.gitProcess = new MockGitProcess();

            // Create enlistment using git process
            GSDEnlistment enlistment = new MockGSDEnlistment(this.gitProcess);

            // Create a last run time file
            MockFile timeFile = new MockFile(Path.Combine(enlistment.GitObjectsRoot, "info", PackfileMaintenanceStep.PackfileLastRunFileName), lastRunTime);

            // Create info directory to hold last run time file
            MockDirectory info = new MockDirectory(
                Path.Combine(enlistment.GitObjectsRoot, "info"),
                null,
                new List <MockFile>()
            {
                timeFile
            });

            // Create pack info
            MockDirectory pack = new MockDirectory(
                enlistment.GitPackRoot,
                null,
                new List <MockFile>()
            {
                new MockFile(Path.Combine(enlistment.GitPackRoot, "pack-1.pack"), "one"),
                new MockFile(Path.Combine(enlistment.GitPackRoot, "pack-1.idx"), "1"),
                new MockFile(Path.Combine(enlistment.GitPackRoot, "pack-2.pack"), "two"),
                new MockFile(Path.Combine(enlistment.GitPackRoot, "pack-2.idx"), "2"),
                new MockFile(Path.Combine(enlistment.GitPackRoot, "pack-3.pack"), "three"),
                new MockFile(Path.Combine(enlistment.GitPackRoot, "pack-3.idx"), "3"),
                new MockFile(Path.Combine(enlistment.GitPackRoot, KeepName), string.Empty),
                new MockFile(Path.Combine(enlistment.GitPackRoot, StaleIdxName), "4"),
            });

            // Create git objects directory
            MockDirectory gitObjectsRoot = new MockDirectory(enlistment.GitObjectsRoot, new List <MockDirectory>()
            {
                info, pack
            }, null);

            // Add object directory to file System
            List <MockDirectory> directories = new List <MockDirectory>()
            {
                gitObjectsRoot
            };
            PhysicalFileSystem fileSystem = new MockFileSystem(new MockDirectory(enlistment.EnlistmentRoot, directories, null));

            MockGitRepo repository = new MockGitRepo(this.tracer, enlistment, fileSystem);

            // Create and return Context
            this.tracer  = new MockTracer();
            this.context = new GSDContext(this.tracer, fileSystem, repository, enlistment);

            this.gitProcess.SetExpectedCommandResult(
                this.ExpireCommand,
                () => new GitProcess.Result(string.Empty, string.Empty, GitProcess.Result.SuccessCode));
            this.gitProcess.SetExpectedCommandResult(
                this.VerifyCommand,
                () => new GitProcess.Result(string.Empty, string.Empty, failOnVerify ? GitProcess.Result.GenericFailureCode : GitProcess.Result.SuccessCode));
            this.gitProcess.SetExpectedCommandResult(
                this.RepackCommand,
                () => new GitProcess.Result(string.Empty, string.Empty, GitProcess.Result.SuccessCode));
        }