public static void ResolveConflicts(string path, MergeFileFavor favor) { if(!GitManager.IsValidRepo) return; if (favor == MergeFileFavor.Normal) { GitExternalManager.HandleConflict(path); } else if (favor == MergeFileFavor.Ours) { var conflict = GitManager.Repository.Index.Conflicts[path]; var ours = conflict.Ours; if (ours != null) { GitManager.Repository.Index.Remove(ours.Path); GitManager.Repository.CheckoutPaths("ORIG_HEAD", new[] { ours.Path }); } } else if (favor == MergeFileFavor.Theirs) { var conflict = GitManager.Repository.Index.Conflicts[path]; var theirs = conflict.Theirs; if (theirs != null) { GitManager.Repository.Index.Remove(theirs.Path); GitManager.Repository.CheckoutPaths("MERGE_HEAD", new[] { theirs.Path }); } } //Debug.Log(EditorUtility.InvokeDiffTool(Path.GetFileName(theirs.Path) + " - Theirs", conflictPathTheirs, Path.GetFileName(ours.Path) + " - Ours", conflictPathOurs, "", conflictPathAncestor)); }
public void MergeCanSpecifyMergeFileFavorOption(MergeFileFavor fileFavorFlag) { const string conflictFile = "a.txt"; const string conflictBranchName = "conflicts"; string path = SandboxMergeTestRepo(); using (var repo = InitIsolatedRepository(path)) { Branch branch = repo.Branches[conflictBranchName]; Assert.NotNull(branch); var status = repo.RetrieveStatus(); MergeOptions mergeOptions = new MergeOptions() { MergeFileFavor = fileFavorFlag, }; MergeResult result = repo.Merge(branch, Constants.Signature, mergeOptions); Assert.Equal(MergeStatus.NonFastForward, result.Status); // Verify that the index and working directory are clean Assert.True(repo.Index.IsFullyMerged); Assert.False(repo.RetrieveStatus().IsDirty); // Get the blob containing the expected content. Blob expectedBlob = null; switch (fileFavorFlag) { case MergeFileFavor.Theirs: expectedBlob = repo.Lookup <Blob>("3dd9738af654bbf1c363f6c3bbc323bacdefa179"); break; case MergeFileFavor.Ours: expectedBlob = repo.Lookup <Blob>("610b16886ca829cebd2767d9196f3c4378fe60b5"); break; default: throw new Exception("Unexpected MergeFileFavor"); } Assert.NotNull(expectedBlob); // Verify the index has the expected contents IndexEntry entry = repo.Index[conflictFile]; Assert.NotNull(entry); Assert.Equal(expectedBlob.Id, entry.Id); // Verify the content of the file on disk matches what is expected. string expectedContent = expectedBlob.GetContentText(new FilteringOptions(conflictFile)); Assert.Equal(expectedContent, File.ReadAllText(Path.Combine(repo.Info.WorkingDirectory, conflictFile))); } }
/// <summary> /// Pulls current branch by merging changes from remote 'orgin' branch into this repository. /// The current head must be clean. /// Note that this is not a [CommandMethod]: Pull command is implemented by Solution driver /// so that potential reloading solution is handled. /// </summary> /// <param name="m">The monitor to use.</param> /// <returns> /// Success is true on success, false on error (such as merge conflicts) and in case of success, /// the result states whether a reload should be required or if nothing changed. /// </returns> public (bool Success, bool ReloadNeeded) Pull(IActivityMonitor m, MergeFileFavor mergeFileFavor) { using (m.OpenInfo($"Pulling branch '{CurrentBranchName}' in '{SubPath}'.")) { if (!FetchBranches(m) || !CheckCleanCommit(m)) { return(false, false); } EnsureBranch(m, CurrentBranchName); try { return(DoPull(m, mergeFileFavor)); } catch (Exception ex) { m.Error(ex); return(false, true); } } }
public void MergeCanSpecifyMergeFileFavorOption(MergeFileFavor fileFavorFlag) { const string conflictFile = "a.txt"; const string conflictBranchName = "conflicts"; string path = CloneMergeTestRepo(); using (var repo = InitIsolatedRepository(path)) { Branch branch = repo.Branches[conflictBranchName]; Assert.NotNull(branch); var status = repo.Index.RetrieveStatus(); MergeOptions mergeOptions = new MergeOptions() { MergeFileFavor = fileFavorFlag, }; MergeResult result = repo.Merge(branch, Constants.Signature, mergeOptions); Assert.Equal(MergeStatus.NonFastForward, result.Status); // Verify that the index and working directory are clean Assert.True(repo.Index.IsFullyMerged); Assert.False(repo.Index.RetrieveStatus().IsDirty); // Get the blob containing the expected content. Blob expectedBlob = null; switch (fileFavorFlag) { case MergeFileFavor.Theirs: expectedBlob = repo.Lookup<Blob>("3dd9738af654bbf1c363f6c3bbc323bacdefa179"); break; case MergeFileFavor.Ours: expectedBlob = repo.Lookup<Blob>("610b16886ca829cebd2767d9196f3c4378fe60b5"); break; default: throw new Exception("Unexpected MergeFileFavor"); } Assert.NotNull(expectedBlob); // Verify the index has the expected contents IndexEntry entry = repo.Index[conflictFile]; Assert.NotNull(entry); Assert.Equal(expectedBlob.Id, entry.Id); // Verify the content of the file on disk matches what is expected. string expectedContent = expectedBlob.GetContentText(new FilteringOptions(conflictFile)); Assert.Equal(expectedContent, File.ReadAllText(Path.Combine(repo.Info.WorkingDirectory, conflictFile))); } }
public static void ResolveConflicts(string path, MergeFileFavor favor) { if (!GitManager.IsValidRepo) { return; } if (favor == MergeFileFavor.Normal) { Object asset = AssetDatabase.LoadAssetAtPath(path, typeof(Object)); var arg = new CancelEventArgs(); if (OnHandleConflictEvent != null) { OnHandleConflictEvent.Invoke(path, asset, arg); } if (arg.Cancel) { return; } var conflict = GitManager.Repository.Index.Conflicts[path]; var ancestor = conflict.Ancestor; var ours = conflict.Ours; var theirs = conflict.Theirs; var ancestorBlob = (ancestor != null) ? (Blob)GitManager.Repository.Lookup(ancestor.Id) : null; var ourBlob = (ours != null) ? (Blob)GitManager.Repository.Lookup(ours.Id) : null; var theirBlob = (theirs != null) ? (Blob)GitManager.Repository.Lookup(theirs.Id) : null; var ourStream = (ours != null) ? ourBlob.GetContentStream(new FilteringOptions(ours.Path)) : null; var theirStream = (theirs != null) ? theirBlob.GetContentStream(new FilteringOptions(theirs.Path)) : null; var ancestorStream = (ancestor != null) ? ancestorBlob.GetContentStream(new FilteringOptions(ancestor.Path)) : null; var conflictPathOurs = Application.dataPath.Replace("Assets", "Temp/our_conflict_file_tmp"); var conflictPathTheirs = Application.dataPath.Replace("Assets", "Temp/their_conflict_file_tmp"); var conflictPathAncestor = Application.dataPath.Replace("Assets", "Temp/ancestor_conflict_file_tmp"); if (ourStream != null) { using (var ourOutputStream = File.Create(conflictPathOurs)) { ourStream.CopyTo(ourOutputStream); } } if (theirStream != null) { using (var theirOutputStream = File.Create(conflictPathTheirs)) { theirStream.CopyTo(theirOutputStream); } } if (ancestorStream != null) { using (var ancestorOutputStream = File.Create(conflictPathAncestor)) { ancestorStream.CopyTo(ancestorOutputStream); } } GitExternalManager.HandleConflict(conflictPathTheirs, conflictPathOurs, conflictPathAncestor, path, asset.GetType()); } else if (favor == MergeFileFavor.Ours) { var conflict = GitManager.Repository.Index.Conflicts[path]; var ours = conflict.Ours; if (ours != null) { GitManager.Repository.Index.Remove(ours.Path); GitManager.Repository.CheckoutPaths("ORIG_HEAD", new[] { ours.Path }); } } else if (favor == MergeFileFavor.Theirs) { var conflict = GitManager.Repository.Index.Conflicts[path]; var theirs = conflict.Theirs; if (theirs != null) { GitManager.Repository.Index.Remove(theirs.Path); GitManager.Repository.CheckoutPaths("MERGE_HEAD", new[] { theirs.Path }); } } //Debug.Log(EditorUtility.InvokeDiffTool(Path.GetFileName(theirs.Path) + " - Theirs", conflictPathTheirs, Path.GetFileName(ours.Path) + " - Ours", conflictPathOurs, "", conflictPathAncestor)); }