|
@@ -1,9 +1,11 @@
|
|
|
-using UnityEngine;
|
|
|
+using System;
|
|
|
+using UnityEngine;
|
|
|
using UnityEditor;
|
|
|
using UnityEngine.SceneManagement;
|
|
|
using System.Linq;
|
|
|
using System.Collections.Generic;
|
|
|
using GitMerge.Utilities;
|
|
|
+using Object = UnityEngine.Object;
|
|
|
|
|
|
namespace GitMerge
|
|
|
{
|
|
@@ -24,6 +26,7 @@ namespace GitMerge
|
|
|
|
|
|
private MergeFilter filter = new MergeFilter();
|
|
|
private MergeFilterBar filterBar = new MergeFilterBar();
|
|
|
+ private ConflictWatcher conflictWatcher = new ConflictWatcher();
|
|
|
|
|
|
public bool mergeInProgress => mergeManager != null;
|
|
|
|
|
@@ -32,6 +35,9 @@ namespace GitMerge
|
|
|
private int tab = 0;
|
|
|
private List<GameObjectMergeActions> mergeActionsFiltered;
|
|
|
|
|
|
+ private Texture2D brokenLogo;
|
|
|
+ private Texture2D fixedLogo;
|
|
|
+
|
|
|
[MenuItem("Window/GitMerge")]
|
|
|
static void OpenEditor()
|
|
|
{
|
|
@@ -44,12 +50,22 @@ namespace GitMerge
|
|
|
|
|
|
private void OnEnable()
|
|
|
{
|
|
|
+ brokenLogo = UnityEngine.Resources.Load<Texture2D>("chain-broken");
|
|
|
+ fixedLogo = UnityEngine.Resources.Load<Texture2D>("check");
|
|
|
pageView.NumElementsPerPage = 200;
|
|
|
filterBar.filter = filter;
|
|
|
filter.OnChanged += CacheMergeActions;
|
|
|
+ conflictWatcher.OnConflict += InitializeMerge;
|
|
|
+ Selection.selectionChanged += Repaint;
|
|
|
+ EditorApplication.hierarchyWindowItemOnGUI += HighlightItems;
|
|
|
LoadSettings();
|
|
|
}
|
|
|
|
|
|
+ private void OnDisable()
|
|
|
+ {
|
|
|
+ conflictWatcher.OnConflict -= InitializeMerge;
|
|
|
+ }
|
|
|
+
|
|
|
private static void LoadSettings()
|
|
|
{
|
|
|
automerge = EditorPrefs.GetBool(EDITOR_PREFS_AUTOMERGE, true);
|
|
@@ -84,6 +100,9 @@ namespace GitMerge
|
|
|
{
|
|
|
Resources.DrawLogo();
|
|
|
DrawTabButtons();
|
|
|
+ EditorGUILayout.Space();
|
|
|
+ DrawHorizontalDivider();
|
|
|
+ EditorGUILayout.Space();
|
|
|
switch (tab)
|
|
|
{
|
|
|
case 0:
|
|
@@ -138,28 +157,87 @@ namespace GitMerge
|
|
|
var path = PathDetectingDragAndDropField("Drag a scene or prefab here to start merging", 80);
|
|
|
if (path != null)
|
|
|
{
|
|
|
- var asset = AssetDatabase.LoadAssetAtPath<Object>(path);
|
|
|
+ InitializeMerge(path);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void HighlightItems(int instanceID, Rect selectionRect)
|
|
|
+ {
|
|
|
+ var target = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
|
|
|
+
|
|
|
+ Texture2D drawableLogo;
|
|
|
+
|
|
|
+ if (target == null)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool isResolved = false;
|
|
|
+ bool found = false;
|
|
|
+
|
|
|
+ if (mergeManager is { allMergeActions: not null })
|
|
|
+ {
|
|
|
+ GlobalObjectId targetId = GlobalObjectId.GetGlobalObjectIdSlow(target);
|
|
|
+
|
|
|
+ foreach (var mergeAction in mergeManager.allMergeActions)
|
|
|
+ {
|
|
|
+ GlobalObjectId actionId = GlobalObjectId.GetGlobalObjectIdSlow(mergeAction.ours);
|
|
|
|
|
|
- if (IsPrefabAsset(asset))
|
|
|
- {
|
|
|
- var manager = new MergeManagerPrefab(this, vcs);
|
|
|
- if (manager.TryInitializeMerge(path))
|
|
|
- {
|
|
|
- this.mergeManager = manager;
|
|
|
- CacheMergeActions();
|
|
|
- }
|
|
|
- }
|
|
|
- else if (IsSceneAsset(asset))
|
|
|
+ if (targetId.targetObjectId == actionId.targetObjectId)
|
|
|
{
|
|
|
- var manager = new MergeManagerScene(this, vcs);
|
|
|
- if (manager.TryInitializeMerge(path))
|
|
|
- {
|
|
|
- this.mergeManager = manager;
|
|
|
- CacheMergeActions();
|
|
|
- }
|
|
|
+ found = true;
|
|
|
+ isResolved = mergeAction.merged;
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ if (!found) return;
|
|
|
+
|
|
|
+ if (!isResolved)
|
|
|
+ {
|
|
|
+ drawableLogo = brokenLogo;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ drawableLogo = fixedLogo;
|
|
|
+ }
|
|
|
+
|
|
|
+ var iconSize = 16;
|
|
|
+
|
|
|
+ var iconRect = new Rect(
|
|
|
+ selectionRect.xMax - iconSize - 2,
|
|
|
+ selectionRect.y + (selectionRect.height - iconSize) / 2f,
|
|
|
+ iconSize,
|
|
|
+ iconSize
|
|
|
+ );
|
|
|
+
|
|
|
+ GUI.DrawTexture(iconRect, drawableLogo, ScaleMode.ScaleToFit);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void InitializeMerge(string path)
|
|
|
+ {
|
|
|
+ if (path == null) return;
|
|
|
+ var asset = AssetDatabase.LoadAssetAtPath<Object>(path);
|
|
|
+
|
|
|
+ if (IsPrefabAsset(asset))
|
|
|
+ {
|
|
|
+ var manager = new MergeManagerPrefab(this, vcs);
|
|
|
+ if (manager.TryInitializeMerge(path))
|
|
|
+ {
|
|
|
+ this.mergeManager = manager;
|
|
|
+ CacheMergeActions();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (IsSceneAsset(asset))
|
|
|
+ {
|
|
|
+ var manager = new MergeManagerScene(this, vcs);
|
|
|
+ if (manager.TryInitializeMerge(path))
|
|
|
+ {
|
|
|
+ this.mergeManager = manager;
|
|
|
+ CacheMergeActions();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private static bool IsPrefabAsset(Object asset)
|
|
@@ -274,9 +352,25 @@ namespace GitMerge
|
|
|
mergeManager.AbortMerge();
|
|
|
mergeManager = null;
|
|
|
}
|
|
|
+ // Confirm merge if possible
|
|
|
+ if (mergeManager != null && mergeManager.isMergingDone)
|
|
|
+ {
|
|
|
+ GUI.backgroundColor = Color.green;
|
|
|
+ if (GUI.Button(new Rect(400, 36, 300, 22), "Confirm merge"))
|
|
|
+ {
|
|
|
+ mergeManager.CompleteMerge();
|
|
|
+ mergeManager = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
GUI.backgroundColor = Color.white;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ private void DrawHorizontalDivider()
|
|
|
+ {
|
|
|
+ var rect = EditorGUILayout.GetControlRect(false, 1);
|
|
|
+ EditorGUI.DrawRect(rect, new Color(0.4f, 0.4f, 0.4f, 1f)); // Dark gray line
|
|
|
+ }
|
|
|
|
|
|
/// <summary>
|
|
|
/// Displays all MergeActions and the "apply merge" button if a merge is in progress.
|
|
@@ -284,15 +378,17 @@ namespace GitMerge
|
|
|
private void DisplayMergeProcess()
|
|
|
{
|
|
|
DrawCommandBar();
|
|
|
+ EditorGUILayout.Space();
|
|
|
+ DrawHorizontalDivider();
|
|
|
|
|
|
var done = DisplayMergeActions();
|
|
|
- GUILayout.BeginHorizontal();
|
|
|
- if (done && GUILayout.Button("Apply merge", GUILayout.Height(40)))
|
|
|
- {
|
|
|
- mergeManager.CompleteMerge();
|
|
|
- mergeManager = null;
|
|
|
- }
|
|
|
- GUILayout.EndHorizontal();
|
|
|
+ // GUILayout.BeginHorizontal();
|
|
|
+ // if (done && GUILayout.Button("Apply merge", GUILayout.Height(40)))
|
|
|
+ // {
|
|
|
+ // mergeManager.CompleteMerge();
|
|
|
+ // mergeManager = null;
|
|
|
+ // }
|
|
|
+ // GUILayout.EndHorizontal();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -313,11 +409,17 @@ namespace GitMerge
|
|
|
{
|
|
|
if (GUILayout.Button(new GUIContent("Use ours", "Use theirs for all. Do not apply merge automatically.")))
|
|
|
{
|
|
|
- mergeManager.allMergeActions.ForEach((action) => action.UseOurs());
|
|
|
+ mergeManager.allMergeActions.ForEach((action) =>
|
|
|
+ {
|
|
|
+ action.UseOurs(true);
|
|
|
+ });
|
|
|
}
|
|
|
if (GUILayout.Button(new GUIContent("Use theirs", "Use theirs for all. Do not apply merge automatically.")))
|
|
|
{
|
|
|
- mergeManager.allMergeActions.ForEach((action) => action.UseTheirs());
|
|
|
+ mergeManager.allMergeActions.ForEach((action) =>
|
|
|
+ {
|
|
|
+ action.UseTheirs(true);
|
|
|
+ });
|
|
|
}
|
|
|
GUILayout.FlexibleSpace();
|
|
|
}
|
|
@@ -356,6 +458,8 @@ namespace GitMerge
|
|
|
{
|
|
|
mergeActionsFiltered = mergeManager.allMergeActions;
|
|
|
}
|
|
|
+
|
|
|
+ mergeActionsFiltered = mergeManager.allMergeActions.Where((actions) => !actions.applied).ToList();
|
|
|
}
|
|
|
}
|
|
|
}
|