diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/FileHistoryWindow.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/FileHistoryWindow.cs index 0c4f108f1..a00c12b9d 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/FileHistoryWindow.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/FileHistoryWindow.cs @@ -38,35 +38,52 @@ private static bool GitFileHistoryValidation() [SerializeField] private bool locked; [SerializeField] private FileHistoryView fileHistoryView = new FileHistoryView(); [SerializeField] private UnityEngine.Object selectedObject; - [SerializeField] private NPath selectedObjectPath; + [SerializeField] private NPath selectedObjectAssetPath; + [SerializeField] private string selectedObjectAssetPathStr; - public void SetSelectedPath(NPath path) + public void SetSelectedPath(NPath assetPath) { - selectedObjectPath = path; + var fullPath = Application.dataPath.ToNPath().Parent.Combine(assetPath); + this.fileHistoryView.SetFullPath(fullPath); + + selectedObjectAssetPathStr = assetPath; + selectedObjectAssetPath = assetPath; selectedObject = null; + if (selectedObjectAssetPath != NPath.Default) + { + selectedObject = AssetDatabase.LoadMainAssetAtPath(selectedObjectAssetPath.ToString()); + } + + InitializeAssetIcon(); + + // If we use selectedObjectAssetPath then this will break if the Unity project isn't located at the root + // of the git repository. + Repository.UpdateFileLog(fullPath) + .Start(); + } + + private void InitializeAssetIcon() + { Texture nodeIcon = null; - if (selectedObjectPath != NPath.Default) + if (selectedObjectAssetPath != NPath.Default) { - selectedObject = AssetDatabase.LoadMainAssetAtPath(path.ToString()); + selectedObject = AssetDatabase.LoadMainAssetAtPath(selectedObjectAssetPath.ToString()); - if (selectedObjectPath.DirectoryExists()) + if (selectedObjectAssetPath.DirectoryExists()) { nodeIcon = Styles.FolderIcon; } else { - nodeIcon = UnityEditorInternal.InternalEditorUtility.GetIconForFile(selectedObjectPath.ToString()); + nodeIcon = UnityEditorInternal.InternalEditorUtility.GetIconForFile(selectedObjectAssetPath.ToString()); } nodeIcon.hideFlags = HideFlags.HideAndDontSave; } selectedIcon = nodeIcon; - - Repository.UpdateFileLog(selectedObjectPath) - .Start(); } public override void Initialize(IApplicationManager applicationManager) @@ -131,14 +148,14 @@ public override void OnSelectionChange() if (!locked) { selectedObject = Selection.activeObject; - selectedObjectPath = NPath.Default; + selectedObjectAssetPath = NPath.Default; if (selectedObject != null) { - selectedObjectPath = AssetDatabase.GetAssetPath(selectedObject) + selectedObjectAssetPath = AssetDatabase.GetAssetPath(selectedObject) .ToNPath(); } - SetSelectedPath(selectedObjectPath); + SetSelectedPath(selectedObjectAssetPath); } } @@ -151,10 +168,21 @@ public override void Refresh() Redraw(); } + // Ideally we'd just call this in 'Initialize()' but that is too early in the domain reload and causes exceptions + private void RestoreFromDomainReload() + { + if (selectedObjectAssetPathStr != selectedObjectAssetPath && !string.IsNullOrEmpty(selectedObjectAssetPathStr)) + { + this.SetSelectedPath(selectedObjectAssetPathStr.ToNPath()); + } + } + public override void OnUI() { base.OnUI(); + RestoreFromDomainReload(); + if (selectedObject != null) { GUILayout.BeginVertical(Styles.HeaderStyle); @@ -209,7 +237,7 @@ private void DoHeaderGUI() GUILayout.Label(selectedIcon, GUILayout.Height(iconWidth), GUILayout.Width(iconHeight)); - GUILayout.Label(selectedObjectPath, Styles.FileHistoryLogTitleStyle); + GUILayout.Label(selectedObjectAssetPath, Styles.FileHistoryLogTitleStyle); GUILayout.FlexibleSpace(); diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/HistoryView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/HistoryView.cs index 3cab7852d..8a11755a2 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/HistoryView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/HistoryView.cs @@ -658,9 +658,16 @@ class FileHistoryView : HistoryBase [SerializeField] private GitLogEntry selectedEntry = GitLogEntry.Default; [SerializeField] private ChangesTree treeChanges = new ChangesTree { DisplayRootNode = false }; [SerializeField] private Vector2 detailsScroll; + [SerializeField] private NPath fullPath; [SerializeField] private CacheUpdateEvent lastFileLogChangedEvent; + public void SetFullPath(NPath inFullPath) + { + this.fullPath = inFullPath; + + } + public override void Refresh() { base.Refresh(); @@ -723,7 +730,14 @@ protected override void MaybeUpdateData() public override void OnGUI() { - DoHistoryGui(Rect.zero); + var lastRect = GUILayoutUtility.GetLastRect(); + DoHistoryGui(lastRect, entry => { + GenericMenu menu = new GenericMenu(); + string checkoutPrompt = string.Format("Checkout revision {0}", entry.ShortID); + menu.AddItem(new GUIContent(checkoutPrompt), false, () => { Checkout(entry); }); + menu.ShowAsContext(); + }, node => { + }); } protected override HistoryControl HistoryControl @@ -749,5 +763,42 @@ protected override Vector2 DetailsScroll get { return detailsScroll; } set { detailsScroll = value; } } + + private const string ConfirmCheckoutTitle = "Discard Changes?"; + private const string ConfirmCheckoutMessage = "You've made changes to file '{0}'. Overwrite these changes with the historical version?"; + private const string ConfirmCheckoutOK = "Overwrite"; + private const string ConfirmCheckoutCancel = "Cancel"; + + protected void Checkout(GitLogEntry entry) + { + GitClient.Status().ThenInUI((success, status) => + { + if (success) + { + bool promptUser = false; + + foreach (var e in status.Entries) + { + if (e.FullPath == this.fullPath) + { + // locally modified file; prompt user + promptUser = true; + break; + } + } + + if (!promptUser || EditorUtility.DisplayDialog(ConfirmCheckoutTitle, string.Format(ConfirmCheckoutMessage, this.fullPath), ConfirmCheckoutOK, ConfirmCheckoutCancel)) + { + GitClient.CheckoutVersion(entry.commitID, new string[] { this.fullPath }).ThenInUI((checkoutSuccess, result) => { + AssetDatabase.Refresh(); + }).Start(); + } + } + else + { + EditorUtility.DisplayDialog("Oops", "There was an error checking out this version of the file. Try again!", "OK"); + } + }).Start(); + } } }