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); } }
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; }