public override void Initialize() { if (!FindGitRoot()) { Debug.LogError("[VCS] Unable to find .git folder, git support disabled"); return; } Thread m_asyncthread = new Thread(() => { while (true) { try { if (inPlayMode) { Thread.Sleep(100); continue; } // Update locks var newLockFiles = new Dictionary <string, LockedFile>(); GitHelper.RunGitCommand("lfs locks", proc => { if (!proc.WaitForExit(5000)) { return(true); } return(false); }, result => { try { var parts = result.Split('\t'); var path = parts[0]; var user = parts[1]; var locked = new LockedFile(); locked.Path = path; locked.User = user; newLockFiles.Add(path.Trim(), locked); } catch (System.Exception ex) { Debug.LogError("[VCS Async] " + ex); } }, error => { Debug.LogError("[VCS]" + error); return(true); } ); var changes = GenerateRecursiveModifiedList(); lock (_actionQueueLock) { var cnt = LockedFiles.Count; int hash = 0; foreach (var v in LockedFiles) { hash += v.Key.GetHashCode() ^ v.Value.User.GetHashCode(); } int modPathHash = 0; foreach (var v in ModifiedPaths) { modPathHash += v.GetHashCode(); } _toRunOnMainThread.Enqueue(() => { // Locked files if (cnt == LockedFiles.Count) { int newhash = 0; foreach (var v in LockedFiles) { newhash += v.Key.GetHashCode() ^ v.Value.User.GetHashCode(); } // Let's make sure that the super lazy hashes match if (newhash == hash) { foreach (var v in LockedFiles) { if (v.Value.FileLock != null) { v.Value.FileLock.Close(); } } LockedFiles.Clear(); _lockedFiles = newLockFiles; foreach (var v in LockedFiles) { if (v.Value.User != GitHelper.Username && GitHelper.PreventEditsOnRemoteLock) { try { v.Value.FileLock = new FileStream(v.Key, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); } catch (System.Exception ex) { Debug.LogError("Failed to create file lock for " + v.Key + ": " + ex); } } } } } // Ensure that paths diffs haven't been modified externally int nmodPathHash = 0; foreach (var v in ModifiedPaths) { nmodPathHash += v.GetHashCode(); } if (nmodPathHash == modPathHash) { ModifiedPaths.Clear(); foreach (var v in changes) { ModifiedPaths.Add(v); } } UpdateLockedFiles(); }); } Thread.Sleep(2000); } catch (ThreadAbortException ex) { throw ex; } catch (System.Exception ex) { Debug.LogError("[VCS Async] " + ex); } } }); m_asyncthread.Name = "Git Async Thread"; m_asyncthread.Start(); // Preserves locked files for play mode, etc AssemblyReloadEvents.beforeAssemblyReload += () => { m_asyncthread.Abort(); UpdateLockedFiles(); }; UnityEditor.SceneManagement.EditorSceneManager.sceneSaved += (scn) => { if (GitHelper.SceneAutoLock) { if (string.IsNullOrEmpty(scn.path)) { return; } if (!IsFileLockedByLocalUser(scn.path)) { GitLockFile(new string[] { scn.path }); } } }; EditorApplication.playModeStateChanged += (s) => { if (s == PlayModeStateChange.ExitingEditMode) { UpdateLockedFiles(); } }; EditorApplication.projectWindowItemOnGUI += (string guid, Rect rect) => { var path = AssetDatabase.GUIDToAssetPath(guid); var iconRect = rect; var oldBack = GUI.backgroundColor; GUI.backgroundColor = new Color(0, 0, 0, 0); if (ModifiedPaths.Contains(path)) { GUI.Box(iconRect, VCSHelper.ModifiedItemIcon); } if (IsFileLocked(path)) { GUI.Box(iconRect, new GUIContent(VCSHelper.LocalLockIcon, "Locked by " + LockedFiles[path].User + " (local user)")); } else if (IsFileLocked(path)) { GUI.Box(iconRect, new GUIContent(VCSHelper.RemoteLockIcon, "Locked by " + LockedFiles[path].User)); } GUI.backgroundColor = oldBack; }; if (!GitHelper.Configured) { if (EditorUtility.DisplayDialog("Version Control", "You have not yet set up your GitHub username and you will not be able to lock files. Would you like to open the configuration window?", "Yes", "No")) { VCSConfigWindow.OpenWindow(); } } else { LoadLockedFilesFromEditorPrefs(); RefreshGitLockTypes(); } }
public void RefreshGitLocks() { foreach (var v in LockedFiles) { if (v.Value.FileLock != null) { v.Value.FileLock.Close(); } } LockedFiles.Clear(); GitHelper.RunGitCommand("lfs locks", proc => { try { while (!proc.HasExited) { if (EditorUtility.DisplayCancelableProgressBar("Version Control", "Refreshing LFS locks...", 0)) { proc.Kill(); return(true); } Thread.Sleep(16); } } finally { EditorUtility.ClearProgressBar(); } return(false); }, result => { var parts = result.Split('\t'); var path = parts[0]; var user = parts[1]; var locked = new LockedFile(); locked.Path = path; locked.User = user; if (user != GitHelper.Username && GitHelper.PreventEditsOnRemoteLock) { try { locked.FileLock = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); } catch (System.Exception ex) { Debug.LogError("Failed to create file lock for " + path + ": " + ex); } } LockedFiles.Add(path.Trim(), locked); }, error => { Debug.LogError(error); return(true); } ); UpdateLockedFiles(); EditorApplication.RepaintProjectWindow(); }