private bool CheckForRemoteRevision(ConflictData item)
        {
            if (!string.IsNullOrEmpty(item.Remote.Filename))
                return true;

            string caption = string.Format(fileModifiedLocallyAndDelededRemotelyLong.Text,
                item.Filename,
                GetLocalSideString(),
                GetRemoteSideString());

            using (var frm = new FormModifiedDeletedCreated(string.Format(keepModifiedButtonText.Text + " ({0})", GetLocalSideString()),
                string.Format(deleteFileButtonText.Text + " ({0})", GetRemoteSideString()),
                keepBaseButtonText.Text,
                caption))
            {
                frm.ShowDialog(this);
                if (frm.KeepBase) //base
                    ChooseBaseOnConflict(item.Filename);
                if (frm.KeepLocal) //delete
                    ChooseLocalOnConflict(item.Filename);
                if (frm.KeepRemote) //remote
                    Module.RunGitCmd("rm -- \"" + item.Filename + "\"");
            }
            return false;
        }
        private void ResolveFilesConflict(ConflictData item)
        {
            string[] filenames = Module.CheckoutConflictedFiles(item);
            try
            {
                if (CheckForLocalRevision(item) &&
                    CheckForRemoteRevision(item))
                {
                    if (TryMergeWithScript(item.Filename, filenames[0], filenames[1], filenames[2]))
                    {
                        Cursor.Current = Cursors.Default;
                        return;
                    }

                    if (FileHelper.IsBinaryFile(Module, item.Local.Filename))
                    {
                        if (MessageBox.Show(this, string.Format(fileIsBinary.Text, _mergetool),
                            _binaryFileWarningCaption.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Warning,
                            MessageBoxDefaultButton.Button2) == DialogResult.No)
                        {
                            BinairyFilesChooseLocalBaseRemote(item);
                            return;
                        }
                    }

                    string arguments = _mergetoolCmd;
                    //Check if there is a base file. If not, ask user to fall back to 2-way merge.
                    //git doesn't support 2-way merge, but we can try to adjust attributes to fix this.
                    //For kdiff3 this is easy; just remove the 3rd file from the arguments. Since the
                    //filenames are quoted, this takes a little extra effort. We need to remove these 
                    //quotes also. For tortoise and araxis a little bit more magic is needed.
                    if (item.Base.Filename == null)
                    {
                        var text = string.Format(noBaseRevision.Text, item.Filename);
                        DialogResult result = MessageBox.Show(this, text, _noBaseFileMergeCaption.Text, 
                            MessageBoxButtons.YesNoCancel);
                        if (result == DialogResult.Yes)
                            Use2WayMerge(ref arguments);

                        if (result == DialogResult.Cancel)
                            return;
                    }

                    arguments = arguments.Replace("$BASE", filenames[0]);
                    arguments = arguments.Replace("$LOCAL", filenames[1]);
                    arguments = arguments.Replace("$REMOTE", filenames[2]);
                    arguments = arguments.Replace("$MERGED", item.Filename);

                    //get timestamp of file before merge. This is an extra check to verify if merge was successful
                    DateTime lastWriteTimeBeforeMerge = DateTime.Now;
                    if (File.Exists(Path.Combine(Module.WorkingDir, item.Filename)))
                        lastWriteTimeBeforeMerge = File.GetLastWriteTime(Path.Combine(Module.WorkingDir, item.Filename));

                    var res = Module.RunCmdResult(_mergetoolPath, "" + arguments + "");

                    DateTime lastWriteTimeAfterMerge = lastWriteTimeBeforeMerge;
                    if (File.Exists(Path.Combine(Module.WorkingDir, item.Filename)))
                        lastWriteTimeAfterMerge = File.GetLastWriteTime(Path.Combine(Module.WorkingDir, item.Filename));

                    //Check exitcode AND timestamp of the file. If exitcode is success and
                    //time timestamp is changed, we are pretty sure the merge was done.
                    if (res.ExitCode == 0 && lastWriteTimeBeforeMerge != lastWriteTimeAfterMerge)
                    {
                        StageFile(item.Filename);
                    }

                    //If the exitcode is 1, but the file is changed, ask if the merge conflict is solved.
                    //If the exitcode is 0, but the file is not changed, ask if the merge conflict is solved.
                    if ((res.ExitCode == 1 && lastWriteTimeBeforeMerge != lastWriteTimeAfterMerge) ||
                        (res.ExitCode == 0 && lastWriteTimeBeforeMerge == lastWriteTimeAfterMerge))
                    {
                        if (MessageBox.Show(this, askMergeConflictSolved.Text, askMergeConflictSolvedCaption.Text,
                            MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            StageFile(item.Filename);
                        }
                    }
                }
            }
            finally
            {
                DeleteTemporaryFiles(filenames);
            }
        }
        private void BinairyFilesChooseLocalBaseRemote(ConflictData item)
        {
            string caption = string.Format(fileBinairyChooseLocalBaseRemote.Text,
                                            item.Local.Filename,
                                            GetLocalSideString(),
                                            GetRemoteSideString());

            using (var frm = new FormModifiedDeletedCreated(string.Format(chooseLocalButtonText.Text + " ({0})", GetLocalSideString()),
                                                                            string.Format(chooseRemoteButtonText.Text + " ({0})", GetRemoteSideString()),
                                                                            keepBaseButtonText.Text,
                                                                            caption))
            {
                frm.ShowDialog(this);
                if (frm.KeepBase) //base
                    ChooseBaseOnConflict(item.Filename);
                if (frm.KeepLocal) //local
                    ChooseLocalOnConflict(item.Filename);
                if (frm.KeepRemote) //remote
                    ChooseRemoteOnConflict(item.Filename);
            }
        }
Exemple #4
0
        public string[] CheckoutConflictedFiles(ConflictData unmergedData)
        {
            Directory.SetCurrentDirectory(_workingDir);

            var filename = unmergedData.Filename;

            string[] fileNames =
                {
                    filename + ".BASE",
                    filename + ".LOCAL",
                    filename + ".REMOTE"
                };

            var unmerged = new[] { unmergedData.Base.Filename, unmergedData.Local.Filename, unmergedData.Remote.Filename };

            for (int i = 0; i < unmerged.Length; i++)
            {
                if (unmerged[i] == null)
                    continue;
                var tempFile =
                    RunGitCmd("checkout-index --temp --stage=" + (i + 1) + " -- \"" + filename + "\"");
                tempFile = tempFile.Split('\t')[0];
                tempFile = Path.Combine(_workingDir, tempFile);

                var newFileName = Path.Combine(_workingDir, fileNames[i]);
                try
                {
                    fileNames[i] = newFileName;
                    var index = 1;
                    while (File.Exists(fileNames[i]) && index < 50)
                    {
                        fileNames[i] = newFileName + index;
                        index++;
                    }
                    File.Move(tempFile, fileNames[i]);
                }
                catch (Exception ex)
                {
                    Trace.WriteLine(ex);
                }
            }

            if (!File.Exists(fileNames[0])) fileNames[0] = null;
            if (!File.Exists(fileNames[1])) fileNames[1] = null;
            if (!File.Exists(fileNames[2])) fileNames[2] = null;

            return fileNames;
        }