// Copyright (c) 2025 TerraByte Inc. // // A static class that persists the state of a multi-file reset operation // across script re-compilations, ensuring the process is not interrupted. using System.Linq; using UnityEditor; namespace Terra.Arbitrator.Services { [InitializeOnLoad] public static class BetterGitStatePersistence { internal const string ResetQueueKey = "BetterGit.ResetQueue"; // This static constructor runs automatically after every script compilation. static BetterGitStatePersistence() { // Use delayCall to ensure this runs after the editor is fully initialized. EditorApplication.delayCall += ContinueInterruptedReset; } public static void ContinueInterruptedReset() { while (true) { var queuedFiles = SessionState.GetString(ResetQueueKey, ""); if (string.IsNullOrEmpty(queuedFiles)) { return; // Nothing to do. } var fileList = queuedFiles.Split(';').ToList(); if (!fileList.Any()) { SessionState.EraseString(ResetQueueKey); return; } // Get the next file to process var fileToReset = fileList.First(); fileList.RemoveAt(0); // Update the session state with the remaining files BEFORE starting the operation. if (fileList.Any()) { SessionState.SetString(ResetQueueKey, string.Join(";", fileList)); } else { // Last file was processed, clear the key. SessionState.EraseString(ResetQueueKey); } // Create a GitChange object for the file to be reset. // This is a small, synchronous operation to get the file's current status. var change = GitService.GetChangeForFile(fileToReset); if (change == null) { // The File might have already been reset or state is unusual. // We'll log it and attempt to continue. UnityEngine.Debug.LogWarning($"Could not find status for {fileToReset}, skipping reset. It may have already been processed."); continue; } // Trigger the reset. After this, Unity will recompile if it was a script, // and this whole static constructor will run again. GitService.ResetFileChanges(change); break; } } } }