示例#1
0
        private static void AcquireGlobalLock(string[] args)
        {
            try
            {
                if (ShouldLock(args))
                {
                    GVFSEnlistment enlistment = GVFSEnlistment.CreateFromCurrentDirectory(null, GitProcess.GetInstalledGitBinPath());
                    if (enlistment == null)
                    {
                        ExitWithError("This hook must be run from a GVFS repo");
                    }

                    if (EnlistmentIsReady(enlistment))
                    {
                        string fullCommand = "git " + string.Join(" ", args.Skip(1));
                        int    pid         = ProcessHelper.GetParentProcessId("git.exe");

                        Process parentProcess = null;
                        if (pid == GVFSConstants.InvalidProcessId ||
                            !ProcessHelper.TryGetProcess(pid, out parentProcess))
                        {
                            ExitWithError("GVFS.Hooks: Unable to find parent git.exe process " + "(PID: " + pid + ").");
                        }

                        using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName))
                        {
                            if (!pipeClient.Connect())
                            {
                                ExitWithError("The enlistment does not appear to be mounted. Use 'gvfs status' to check.");
                            }

                            NamedPipeMessages.AcquireLock.Request request =
                                new NamedPipeMessages.AcquireLock.Request(pid, fullCommand, ProcessHelper.GetCommandLine(parentProcess));

                            NamedPipeMessages.Message requestMessage = request.CreateMessage();
                            pipeClient.SendRequest(requestMessage);

                            NamedPipeMessages.AcquireLock.Response response = new NamedPipeMessages.AcquireLock.Response(pipeClient.ReadResponse());

                            if (response.Result == NamedPipeMessages.AcquireLock.AcceptResult)
                            {
                                return;
                            }
                            else if (response.Result == NamedPipeMessages.AcquireLock.MountNotReadyResult)
                            {
                                ExitWithError("GVFS has not finished initializing, please wait a few seconds and try again.");
                            }
                            else
                            {
                                int    retries = 0;
                                char[] waiting = { '\u2014', '\\', '|', '/' };
                                string message = string.Empty;
                                while (true)
                                {
                                    if (response.Result == NamedPipeMessages.AcquireLock.AcceptResult)
                                    {
                                        if (!Console.IsOutputRedirected)
                                        {
                                            Console.WriteLine("\r{0}...", message);
                                        }

                                        return;
                                    }
                                    else if (response.Result == NamedPipeMessages.AcquireLock.DenyGVFSResult)
                                    {
                                        message = "Waiting for GVFS to release the lock";
                                    }
                                    else if (response.Result == NamedPipeMessages.AcquireLock.DenyGitResult)
                                    {
                                        message = string.Format("Waiting for '{0}' to release the lock", response.ResponseData.ParsedCommand);
                                    }
                                    else
                                    {
                                        ExitWithError("Error when acquiring the lock. Unrecognized response: " + response.CreateMessage());
                                        tracer.RelatedError("Unknown LockRequestResponse: " + response);
                                    }

                                    if (Console.IsOutputRedirected && retries == 0)
                                    {
                                        Console.WriteLine("{0}...", message);
                                    }
                                    else if (!Console.IsOutputRedirected)
                                    {
                                        Console.Write("\r{0}..{1}", message, waiting[retries % waiting.Length]);
                                    }

                                    Thread.Sleep(500);

                                    pipeClient.SendRequest(requestMessage);
                                    response = new NamedPipeMessages.AcquireLock.Response(pipeClient.ReadResponse());
                                    retries++;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                EventMetadata metadata = new EventMetadata();
                metadata.Add("Error", e.ToString());
                tracer.RelatedError(metadata);

                ExitWithError(
                    "Unable to initialize Git command.",
                    "Ensure that GVFS is running.");
            }
        }
示例#2
0
        public void Execute()
        {
            // CmdParser doesn't strip quotes, and Path.Combine will throw
            this.GitBinPath = this.GitBinPath.Replace("\"", string.Empty);
            if (!GitProcess.GitExists(this.GitBinPath))
            {
                Console.WriteLine(
                    "Could not find git.exe {0}",
                    !string.IsNullOrWhiteSpace(this.GitBinPath) ? "at " + this.GitBinPath : "on %PATH%");
                return;
            }

            if (this.Commit != null && this.Branch != null)
            {
                Console.WriteLine("Cannot specify both a commit sha and a branch name to checkout.");
                return;
            }

            this.CacheServerUrl = Enlistment.StripObjectsEndpointSuffix(this.CacheServerUrl);

            this.SearchThreadCount   = this.SearchThreadCount > 0 ? this.SearchThreadCount : Environment.ProcessorCount;
            this.DownloadThreadCount = this.DownloadThreadCount > 0 ? this.DownloadThreadCount : Environment.ProcessorCount;
            this.IndexThreadCount    = this.IndexThreadCount > 0 ? this.IndexThreadCount : Environment.ProcessorCount;
            this.CheckoutThreadCount = this.CheckoutThreadCount > 0 ? this.CheckoutThreadCount : Environment.ProcessorCount;

            this.GitBinPath = !string.IsNullOrWhiteSpace(this.GitBinPath) ? this.GitBinPath : GitProcess.GetInstalledGitBinPath();

            Enlistment enlistment = (Enlistment)GVFSEnlistment.CreateFromCurrentDirectory(this.CacheServerUrl, this.GitBinPath)
                                    ?? GitEnlistment.CreateFromCurrentDirectory(this.CacheServerUrl, this.GitBinPath);

            if (enlistment == null)
            {
                Console.WriteLine("Must be run within a .git repo or GVFS enlistment");
                return;
            }

            string commitish = this.Commit ?? this.Branch ?? DefaultBranch;

            EventLevel maxVerbosity = this.Silent ? EventLevel.LogAlways : EventLevel.Informational;

            using (JsonEtwTracer tracer = new JsonEtwTracer("Microsoft.Git.FastFetch", "FastFetch"))
            {
                tracer.AddConsoleEventListener(maxVerbosity, Keywords.Any);
                tracer.WriteStartEvent(
                    enlistment.EnlistmentRoot,
                    enlistment.RepoUrl,
                    enlistment.CacheServerUrl,
                    new EventMetadata
                {
                    { "TargetCommitish", commitish },
                });

                FetchHelper fetchHelper = this.GetFetchHelper(tracer, enlistment);

                fetchHelper.MaxRetries = this.MaxRetries;

                if (!FetchHelper.TryLoadPathWhitelist(this.PathWhitelist, this.PathWhitelistFile, tracer, fetchHelper.PathWhitelist))
                {
                    Environment.ExitCode = 1;
                    return;
                }

                try
                {
                    bool isBranch = this.Commit == null;
                    fetchHelper.FastFetch(commitish, isBranch);
                    if (fetchHelper.HasFailures)
                    {
                        Environment.ExitCode = 1;
                    }
                }
                catch (AggregateException e)
                {
                    Environment.ExitCode = 1;
                    foreach (Exception ex in e.Flatten().InnerExceptions)
                    {
                        tracer.RelatedError(ex.ToString());
                    }
                }
                catch (Exception e)
                {
                    Environment.ExitCode = 1;
                    tracer.RelatedError(e.ToString());
                }

                EventMetadata stopMetadata = new EventMetadata();
                stopMetadata.Add("Success", Environment.ExitCode == 0);
                tracer.Stop(stopMetadata);
            }

            if (Debugger.IsAttached)
            {
                Console.ReadKey();
            }
        }