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); } } }
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()); }