4 using System.Diagnostics;
8 using SiliconStudio.Assets.Visitors;
9 using SiliconStudio.Core.Diagnostics;
11 namespace SiliconStudio.Assets.Diff
18 private static readonly
Logger Log = GlobalLogger.GetLogger(
"AssetMerge");
32 var key = Registry.CurrentUser.OpenSubKey(
"Software\\KDiff3");
35 var kDiffPath = key.GetValue(null) as
string;
36 if (kDiffPath != null)
38 DefaultMergeTool = Path.Combine(kDiffPath,
"kdiff3.exe");
42 if (DefaultMergeTool == null)
44 Log.Error(
"Unable to find a default merge tool");
49 Log.Error(
"Unable to find a default merge tool", ex);
57 public static string DefaultMergeTool {
get; set; }
74 if (assetFrom1 == null)
throw new ArgumentNullException(
"assetFrom1");
75 if (mergePolicy == null)
throw new ArgumentNullException(
"mergePolicy");
91 if (assetDiff == null)
throw new ArgumentNullException(
"assetDiff");
92 if (mergePolicy == null)
throw new ArgumentNullException(
"mergePolicy");
94 var allDiffs = assetDiff.Compute();
95 var diff3 = allDiffs.FindDifferences().ToList();
100 foreach (var diff3Node
in diff3)
105 changeType = mergePolicy(diff3Node);
109 result.Error(
"Unresolved conflict [{0}] on node [{1}/{2}/{3}]", diff3Node.ChangeType, diff3Node.BaseNode, diff3Node.Asset1Node, diff3Node.Asset2Node);
125 var dataInstance = diff3Node.Asset2Node != null ? diff3Node.Asset2Node.Instance : null;
128 diff3Node.ReplaceValue(dataInstance, node => node.Asset1Node, diff3Node.Asset2Node == null);
132 result.Error(
"Unexpected error while merging [{0}] on node [{1}]", ex, diff3Node.ChangeType, diff3Node.InstanceType);
152 if (assetBase0 == null && assetFrom1 == null && assetFrom2 == null)
157 if (!
File.Exists(DefaultMergeTool))
159 result.Error(
"Unable to use external diff3 merge tool [{0}]. File not found", DefaultMergeTool);
169 if (assetBase != null)
171 assetBase.Base = null;
182 var assetBasePath = Path.GetTempFileName();
183 var asset1Path = Path.GetTempFileName();
184 var asset2Path = Path.GetTempFileName();
187 AssetSerializer.Save(assetBasePath, assetBase);
188 AssetSerializer.Save(asset1Path, asset1);
189 AssetSerializer.Save(asset2Path, asset2);
193 result.Error(
"Unexpected error while serializing assets on disk before using diff tool", exception);
197 var outputPath = Path.GetTempFileName();
202 var process = Process.Start(DefaultMergeTool, string.Format(
"{0} {1} {2} -o {3}", assetBasePath, asset1Path, asset2Path, outputPath));
205 result.Error(
"Unable to launch diff3 tool exe from [{0}]", DefaultMergeTool);
209 process.WaitForExit();
211 if (process.ExitCode != 0)
213 result.Error(
"Error, failed to merge files");
219 result.Error(
"Unable to launch diff3 tool exe from [{0}]", ex, DefaultMergeTool);
222 if (!result.HasErrors)
228 if (mergedAsset != null)
230 if (assetFrom1 == null)
232 mergedAsset.Base = assetFrom2 == null ? assetBase0.Base : assetFrom2.Base;
236 mergedAsset.Base = assetFrom1.Base;
239 result.Asset = mergedAsset;
243 result.Error(
"Unexpected exception while loading merged assets from [{0}]", ex, outputPath);
static MergeResult Merge(Asset assetBase, Asset assetFrom1, Asset assetFrom2, MergePolicyDelegate mergePolicy)
Merges the specified assets from base and from2 into from1.
Result of a merge. Contains Asset != null if there are no errors.
Merges asset differences.
static MergeResult Merge(AssetDiff assetDiff, MergePolicyDelegate mergePolicy, bool previewOnly=false)
Merges the specified assets from base and from2 into from1.
static MergeResult MergeWithExternalTool(Asset assetBase0, Asset assetFrom1, Asset assetFrom2)
3-way merge assets using an external diff tool.
static object Load(string filePath)
Deserializes an Asset from the specified stream.
Base implementation for ILogger.
Main entry point for serializing/deserializing Asset.
object Clone()
Clones the current value of this cloner with the specified new shadow registry (optional) ...
Class AssetDiff. This class cannot be inherited.
Output message to log right away.
Allows to clone an asset or values stored in an asset.