private void HandleDehydrateFolders(NamedPipeMessages.Message message, NamedPipeServer.Connection connection)
        {
            NamedPipeMessages.DehydrateFolders.Request request = new NamedPipeMessages.DehydrateFolders.Request(message);

            this.tracer.RelatedInfo($"Received dehydrate folders request with body {message.Body}");

            NamedPipeMessages.DehydrateFolders.Response response;
            if (this.currentState == MountState.Ready)
            {
                response = new NamedPipeMessages.DehydrateFolders.Response(NamedPipeMessages.DehydrateFolders.DehydratedResult);
                string[] folders = request.Folders.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string folder in folders)
                {
                    if (this.fileSystemCallbacks.TryDehydrateFolder(folder, out string errorMessage))
                    {
                        response.SuccessfulFolders.Add(folder);
                    }
                    else
                    {
                        response.FailedFolders.Add($"{folder}\0{errorMessage}");
                    }
                }

                // Since placeholders and modified paths could have changed with the dehydrate, the index needs to be rebuilt
                GitProcess gitProcess = new GitProcess(this.enlistment);
                gitProcess.ForceCheckout(GVFSConstants.DotGit.HeadName);
            }
            else
            {
                response = new NamedPipeMessages.DehydrateFolders.Response(NamedPipeMessages.DehydrateFolders.MountNotReadyResult);
            }

            connection.TrySendResponse(response.CreateMessage());
        }
        private void SendDehydrateMessage(ITracer tracer, GVFSEnlistment enlistment, List <string> folderErrors, string[] folders)
        {
            NamedPipeMessages.DehydrateFolders.Response response = null;

            try
            {
                using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName))
                {
                    if (!pipeClient.Connect())
                    {
                        this.ReportErrorAndExit("Unable to connect to GVFS.  Try running 'gvfs mount'");
                    }

                    NamedPipeMessages.DehydrateFolders.Request request = new NamedPipeMessages.DehydrateFolders.Request(string.Join(FolderListSeparator, folders));
                    pipeClient.SendRequest(request.CreateMessage());
                    response = NamedPipeMessages.DehydrateFolders.Response.FromMessage(NamedPipeMessages.Message.FromString(pipeClient.ReadRawResponse()));
                }
            }
            catch (BrokenPipeException e)
            {
                this.ReportErrorAndExit("Unable to communicate with GVFS: " + e.ToString());
            }

            if (response != null)
            {
                foreach (string folder in response.SuccessfulFolders)
                {
                    this.WriteMessage(tracer, $"{folder} folder {this.ActionName} successful.");
                }

                foreach (string folder in response.FailedFolders)
                {
                    this.WriteMessage(tracer, $"{folder} folder failed to {this.ActionName}. You may need to reset the working directory by deleting {folder}, running `git reset --hard`, and retry the {this.ActionName}.");
                    folderErrors.Add(folder);
                }
            }
        }
Example #3
0
        private void HandleDehydrateFolders(NamedPipeMessages.Message message, NamedPipeServer.Connection connection)
        {
            NamedPipeMessages.DehydrateFolders.Request request = new NamedPipeMessages.DehydrateFolders.Request(message);

            EventMetadata metadata = new EventMetadata();

            metadata.Add(nameof(request.Folders), request.Folders);
            metadata.Add(TracingConstants.MessageKey.InfoMessage, "Received dehydrate folders request");
            this.tracer.RelatedEvent(EventLevel.Informational, nameof(this.HandleDehydrateFolders), metadata);

            NamedPipeMessages.DehydrateFolders.Response response;
            if (this.currentState == MountState.Ready)
            {
                response = new NamedPipeMessages.DehydrateFolders.Response(NamedPipeMessages.DehydrateFolders.DehydratedResult);
                string[]      folders          = request.Folders.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                StringBuilder resetFolderPaths = new StringBuilder();
                foreach (string folder in folders)
                {
                    if (this.fileSystemCallbacks.TryDehydrateFolder(folder, out string errorMessage))
                    {
                        response.SuccessfulFolders.Add(folder);
                    }
                    else
                    {
                        response.FailedFolders.Add($"{folder}\0{errorMessage}");
                    }

                    resetFolderPaths.Append($"\"{folder.Replace(Path.DirectorySeparatorChar, GVFSConstants.GitPathSeparator)}\" ");
                }

                // Since modified paths could have changed with the dehydrate, the paths that were dehydrated need to be reset in the index
                string     resetPaths = resetFolderPaths.ToString();
                GitProcess gitProcess = new GitProcess(this.enlistment);

                EventMetadata resetIndexMetadata = new EventMetadata();
                resetIndexMetadata.Add(nameof(resetPaths), resetPaths);

                GitProcess.Result refreshIndexResult;
                this.resetForDehydrateInProgress = true;
                try
                {
                    // Because we've set resetForDehydrateInProgress to true, this call to 'git reset' will also force
                    // the projection to be updated (required because 'git reset' will adjust the skip worktree bits in
                    // the index).
                    refreshIndexResult = gitProcess.Reset(GVFSConstants.DotGit.HeadName, resetPaths);
                }
                finally
                {
                    this.resetForDehydrateInProgress = false;
                }

                resetIndexMetadata.Add(nameof(refreshIndexResult.ExitCode), refreshIndexResult.ExitCode);
                resetIndexMetadata.Add(nameof(refreshIndexResult.Output), refreshIndexResult.Output);
                resetIndexMetadata.Add(nameof(refreshIndexResult.Errors), refreshIndexResult.Errors);
                resetIndexMetadata.Add(TracingConstants.MessageKey.InfoMessage, $"{nameof(this.HandleDehydrateFolders)}: Reset git index");
                this.tracer.RelatedEvent(EventLevel.Informational, $"{nameof(this.HandleDehydrateFolders)}_ResetIndex", resetIndexMetadata);
            }
            else
            {
                response = new NamedPipeMessages.DehydrateFolders.Response(NamedPipeMessages.DehydrateFolders.MountNotReadyResult);
            }

            connection.TrySendResponse(response.CreateMessage());
        }