MergeAction.cs 4.9 KB

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