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));
		}
Example #2
0
        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)));
            }
        }
Example #3
0
        /// <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);
                }
            }
        }
Example #4
0
        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));
        }