MergeAction.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. 
  2. using System;
  3. namespace GitMerge
  4. {
  5. using UnityEngine;
  6. using UnityEditor;
  7. /// <summary>
  8. /// Each MergeAction represents a single, specific merge conflict.
  9. /// This can be a GameObject added or deleted in one of the versions,
  10. /// a Component added or deleted on a GameObject,
  11. /// or a single property changed on a Component.
  12. /// </summary>
  13. public abstract class MergeAction
  14. {
  15. // Don't highlight objects if not in merge phase.
  16. // Prevents highlighting while automerging.
  17. public static bool inMergePhase;
  18. // A MergeAction is considered "merged" when, at some point,
  19. // "our", "their" or a new version has been applied.
  20. public bool merged { protected set; get; }
  21. public GameObject ours { protected set; get; }
  22. public GameObject theirs { protected set; get; }
  23. // Flags that indicate how this MergeAction has been resolved.
  24. protected bool usingOurs;
  25. protected bool usingTheirs;
  26. protected bool usingNew;
  27. public Action mergeAction;
  28. protected bool wasResolvedAutomatically;
  29. public MergeAction(GameObject ours, GameObject theirs)
  30. {
  31. this.ours = ours;
  32. this.theirs = theirs;
  33. }
  34. /// <summary>
  35. /// Apply "our" change in the conflict, dismissing "their"s.
  36. /// </summary>
  37. public void UseOurs()
  38. {
  39. try
  40. {
  41. mergeAction = ApplyOurs;
  42. }
  43. catch
  44. {
  45. return;
  46. }
  47. merged = true;
  48. usingOurs = true;
  49. usingTheirs = false;
  50. usingNew = false;
  51. wasResolvedAutomatically = !inMergePhase;
  52. if (GitMergeWindow.autofocus)
  53. {
  54. HighlightObject();
  55. }
  56. RefreshPrefabInstance();
  57. }
  58. /// <summary>
  59. /// Apply "their" change in the conflict, dismissing "our"s.
  60. /// </summary>
  61. public void UseTheirs()
  62. {
  63. try
  64. {
  65. mergeAction = ApplyTheirs;
  66. }
  67. catch
  68. {
  69. return;
  70. }
  71. merged = true;
  72. usingOurs = false;
  73. usingTheirs = true;
  74. usingNew = false;
  75. wasResolvedAutomatically = !inMergePhase;
  76. if (GitMergeWindow.autofocus)
  77. {
  78. HighlightObject();
  79. }
  80. RefreshPrefabInstance();
  81. }
  82. /// <summary>
  83. /// Mark this <see cref="MergeAction"/> to use a new value instead of either of the conflicting ones.
  84. /// </summary>
  85. public void UsedNew()
  86. {
  87. merged = true;
  88. usingOurs = false;
  89. usingTheirs = false;
  90. usingNew = true;
  91. wasResolvedAutomatically = !inMergePhase;
  92. RefreshPrefabInstance();
  93. }
  94. /// <summary>
  95. /// Refreshes the prefab instance, if there is any.
  96. /// We change the prefab directly, so we have to do this to see the changes in the scene view.
  97. /// </summary>
  98. private static void RefreshPrefabInstance()
  99. {
  100. if (MergeManagerBase.isMergingPrefab)
  101. {
  102. PrefabUtility.RevertObjectOverride(MergeManagerPrefab.ourPrefabInstance, InteractionMode.AutomatedAction);
  103. }
  104. }
  105. // The implementations of these methods conatain the actual merging steps
  106. protected abstract void ApplyOurs();
  107. protected abstract void ApplyTheirs();
  108. /// <summary>
  109. /// Displays the MergeAction.
  110. /// </summary>
  111. /// <returns>True when the represented conflict has now been merged.</returns>
  112. public bool OnGUIMerge()
  113. {
  114. var wasMerged = merged;
  115. if (merged)
  116. {
  117. GUI.backgroundColor = wasResolvedAutomatically ? new Color(.9f, .9f, .3f, 1) : new Color(.2f, .8f, .2f, 1);
  118. }
  119. else
  120. {
  121. GUI.backgroundColor = new Color(1f, .25f, .25f, 1);
  122. }
  123. GUILayout.BeginHorizontal(Resources.styles.mergeAction);
  124. GUI.backgroundColor = Color.white;
  125. OnGUI();
  126. GUI.color = Color.white;
  127. GUILayout.EndHorizontal();
  128. return merged && !wasMerged;
  129. }
  130. // The actual UI of the MergeAction depends on the actual type
  131. public abstract void OnGUI();
  132. private void HighlightObject()
  133. {
  134. // Highlight the instance of the prefab, not the prefab itself
  135. // Otherwise, "ours".
  136. var objectToHighlight = MergeManagerBase.isMergingPrefab ? MergeManagerPrefab.ourPrefabInstance.GetChildWithEqualPath(ours) : ours;
  137. if (objectToHighlight && inMergePhase && objectToHighlight.hideFlags == HideFlags.None)
  138. {
  139. objectToHighlight.Highlight();
  140. }
  141. }
  142. }
  143. }