// 点击“提交”按钮 private void btnCommit_Click(object sender, EventArgs e) { // 判断是否填写了提交所需的LogMessage信息 string logMessage = txtCommitLogMessage.Text.Trim(); if (string.IsNullOrEmpty(logMessage)) { MessageBox.Show("执行SVN提交操作时必须填写说明信息", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 记录用户是否选择了至少一处需要合并到SVN中的差异内容 bool isChooseCommitChange = false; // 记录未对主语言译文不同的差异条目进行处理方式选择的编号 List <int> unresolvedDiffInfoNum = new List <int>(); // 记录未对本地表新增Key条目进行处理方式选择的编号 List <int> unresolvedLocalAddKeyNum = new List <int>(); // 记录未对SVN表新增Key条目进行处理方式选择的编号 List <int> unresolvedSvnAddKeyNum = new List <int>(); // 记录要进行提交的差异项 CommitCompareResult commitCompareResult = new CommitCompareResult(); // 检查用户是否对每一条差异都选择了处理方式 // 主语言译文不同 const string PART_DIFF_INFO_RESOLVE_CONFLICT_WAY_COLUMN_NAME = _PART_NAME_DIFF_INFO + _RESOLVE_CONFLICT_WAY_COLUMN_NAME; int diffInfoCount = _compareResult.DiffInfo.Count; for (int i = 0; i < diffInfoCount; ++i) { CommitDifferentDefaultLanguageInfo oneDiffInfo = _compareResult.DiffInfo[i]; string selectedValue = _partControls[_PART_NAME_DIFF_INFO].DataGridView.Rows[i].Cells[PART_DIFF_INFO_RESOLVE_CONFLICT_WAY_COLUMN_NAME].Value as string; if (AppValues.RESOLVE_COMMIT_DIFF_WAYS[0].Equals(selectedValue)) { oneDiffInfo.ResolveConflictWay = ResolveConflictWays.UseLocal; commitCompareResult.DiffInfo.Add(oneDiffInfo); isChooseCommitChange = true; } else if (AppValues.RESOLVE_COMMIT_DIFF_WAYS[1].Equals(selectedValue)) { oneDiffInfo.ResolveConflictWay = ResolveConflictWays.UseSvn; } else { oneDiffInfo.ResolveConflictWay = ResolveConflictWays.NotChoose; int num = i + 1; unresolvedDiffInfoNum.Add(num); } } // 本地表新增Key const string PART_LOCAL_ADD_KEY_RESOLVE_CONFLICT_WAY_COLUMN_NAME = _PART_NAME_LOCAL_ADD_KEY + _RESOLVE_CONFLICT_WAY_COLUMN_NAME; int localAddKeyCount = _compareResult.LocalAddKeyInfo.Count; for (int i = 0; i < localAddKeyCount; ++i) { CommitDifferentKeyInfo oneLocalAddKey = _compareResult.LocalAddKeyInfo[i]; string selectedValue = _partControls[_PART_NAME_LOCAL_ADD_KEY].DataGridView.Rows[i].Cells[PART_LOCAL_ADD_KEY_RESOLVE_CONFLICT_WAY_COLUMN_NAME].Value as string; if (AppValues.RESOLVE_COMMIT_DIFF_WAYS[0].Equals(selectedValue)) { oneLocalAddKey.ResolveConflictWay = ResolveConflictWays.UseLocal; commitCompareResult.LocalAddKeyInfo.Add(oneLocalAddKey); isChooseCommitChange = true; } else if (AppValues.RESOLVE_COMMIT_DIFF_WAYS[1].Equals(selectedValue)) { oneLocalAddKey.ResolveConflictWay = ResolveConflictWays.UseSvn; } else { oneLocalAddKey.ResolveConflictWay = ResolveConflictWays.NotChoose; int num = i + 1; unresolvedLocalAddKeyNum.Add(num); } } // SVN表新增Key const string PART_SVN_ADD_KEY_RESOLVE_CONFLICT_WAY_COLUMN_NAME = _PART_NAME_SVN_ADD_KEY + _RESOLVE_CONFLICT_WAY_COLUMN_NAME; int svnAddKeyCount = _compareResult.SvnAddKeyInfo.Count; for (int i = 0; i < svnAddKeyCount; ++i) { CommitDifferentKeyInfo oneSvnAddKey = _compareResult.SvnAddKeyInfo[i]; string selectedValue = _partControls[_PART_NAME_SVN_ADD_KEY].DataGridView.Rows[i].Cells[PART_SVN_ADD_KEY_RESOLVE_CONFLICT_WAY_COLUMN_NAME].Value as string; if (AppValues.RESOLVE_COMMIT_DIFF_WAYS[0].Equals(selectedValue)) { oneSvnAddKey.ResolveConflictWay = ResolveConflictWays.UseLocal; commitCompareResult.SvnAddKeyInfo.Add(oneSvnAddKey); isChooseCommitChange = true; } else if (AppValues.RESOLVE_COMMIT_DIFF_WAYS[1].Equals(selectedValue)) { oneSvnAddKey.ResolveConflictWay = ResolveConflictWays.UseSvn; } else { oneSvnAddKey.ResolveConflictWay = ResolveConflictWays.NotChoose; int num = i + 1; unresolvedSvnAddKeyNum.Add(num); } } StringBuilder unresolvedConflictStringBuilder = new StringBuilder(); if (unresolvedDiffInfoNum.Count > 0) { unresolvedConflictStringBuilder.Append("主语言译文不同的差异条目中,以下编号的行未选择处理方式:"); unresolvedConflictStringBuilder.AppendLine(Utils.CombineString <int>(unresolvedDiffInfoNum, ",")); } if (unresolvedLocalAddKeyNum.Count > 0) { unresolvedConflictStringBuilder.Append("本地表新增Key的差异条目中,以下编号的行未选择处理方式:"); unresolvedConflictStringBuilder.AppendLine(Utils.CombineString <int>(unresolvedLocalAddKeyNum, ",")); } if (unresolvedSvnAddKeyNum.Count > 0) { unresolvedConflictStringBuilder.Append("SVN表新增Key的差异条目中,以下编号的行未选择处理方式:"); unresolvedConflictStringBuilder.AppendLine(Utils.CombineString <int>(unresolvedSvnAddKeyNum, ",")); } string unresolvedConflictString = unresolvedConflictStringBuilder.ToString(); if (!string.IsNullOrEmpty(unresolvedConflictString)) { MessageBox.Show(string.Concat("存在以下未选择处理方式的差异条目,请全部选择处理方式后重试\n\n", unresolvedConflictString), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 判断用户是否选择了至少一处需要合并到SVN中的差异内容 if (isChooseCommitChange == false) { MessageBox.Show("未选择将任一差异提交到SVN表,无需进行提交操作", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // 即将提交时判断此时SVN中最新版本号是否还是进入此界面时与本地表对比的版本号,如果不是需要重新对比 SvnException svnException = null; SvnInfoEventArgs svnFileInfo = OperateSvnHelper.GetSvnFileInfo(AppValues.SvnExcelFilePath, out svnException); if (svnException == null) { // 若此时SVN最新版本仍旧为之前与之对比的版本,则根据用户选择将结果合并到最新SVN母表副本中然后上传 if (svnFileInfo.LastChangeRevision == _compareResult.SvnFileRevision) { string errorString = null; string mergedExcelFilePath = CommitExcelFileHelper.GenerateCommitExcelFile(_compareResult, _localExcelInfo, _newestSvnExcelInfo, out errorString); if (errorString != null) { MessageBox.Show(string.Format("生成合并之后的Excel母表文件失败,错误原因为:{0}\n\n提交操作被迫中止", errorString), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 进行SVN提交操作(将本地Working Copy文件备份至本工具所在路径,然后用合并后的Excel母表替换Working Copy文件后执行SVN提交操作) string backupFilePath = Utils.CombinePath(AppValues.PROGRAM_FOLDER_PATH, string.Format("备份自己修改的本地表 {0:yyyy年MM月dd日 HH时mm分ss秒} 对应SVN版本号{1}.xlsx", DateTime.Now, _localExcelInfo.Revision)); try { File.Copy(AppValues.LocalExcelFilePath, backupFilePath, true); } catch (Exception exception) { MessageBox.Show(string.Format("自动备份本地表至本工具所在路径失败,错误原因为:{0}\n\n为了防止因不备份导致自己编辑的原始本地表丢失,提交SVN操作被迫中止", exception.ToString()), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 因为SVN提交文件需要在同一版本号下进行且SVN无法在Update时对Excel进行Merge操作,则如果本地表的版本号低于SVN最新版本,必须将本地表执行Revert和Update操作后才可以提交 if (_compareResult.LocalFileRevision != _compareResult.SvnFileRevision) { // Revert操作 bool revertResult = OperateSvnHelper.Revert(AppValues.LocalExcelFilePath, out svnException); if (svnException == null) { if (revertResult == false) { MessageBox.Show("因本地表版本不是SVN中最新的,必须执行Revert以及Update操作后才可以提交\n但因为Revert失败,提交SVN操作被迫中止", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else { MessageBox.Show(string.Format("因本地表版本不是SVN中最新的,必须执行Revert以及Update操作后才可以提交\n但因为Revert失败,错误原因为:{0}\n提交SVN操作被迫中止", svnException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // Update操作 bool updateResult = OperateSvnHelper.Update(AppValues.LocalExcelFilePath, out svnException); if (svnException == null) { if (updateResult == false) { MessageBox.Show("因本地表版本不是SVN中最新的,必须执行Revert以及Update操作后才可以提交\n但因为Update失败,提交SVN操作被迫中止", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else { if (svnException is SvnAuthorizationException || svnException is SvnOperationCanceledException) { MessageBox.Show("因本地表版本不是SVN中最新的,必须执行Revert以及Update操作后才可以提交\n但因为没有权限进行Update操作,提交SVN操作被迫中止,请输入合法的SVN账户信息后重试", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else { MessageBox.Show(string.Format("因本地表版本不是SVN中最新的,必须执行Revert以及Update操作后才可以提交\n但因为Update失败,错误原因为:{0}\n提交SVN操作被迫中止", svnException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } } // 用合并后的Excel文件覆盖掉原有的本地表 try { File.Copy(mergedExcelFilePath, AppValues.LocalExcelFilePath, true); } catch (Exception exception) { MessageBox.Show(string.Format("将合并后的Excel母表覆盖到本地表所在路径失败,错误原因为:{0}\n\n提交SVN操作被迫中止", exception), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 执行提交操作 bool commitResult = OperateSvnHelper.Commit(AppValues.LocalExcelFilePath, logMessage, out svnException); if (svnException == null) { if (commitResult == false) { MessageBox.Show("执行提交操作失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else { MessageBox.Show(string.Concat("执行提交操作成功\n\n自己修改的原始本地表备份至:", backupFilePath), "恭喜", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } } else { MessageBox.Show(string.Format("执行提交操作失败,错误原因为:{0}\n\n请修正错误后重试", svnException.RootCause.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else { MessageBox.Show(string.Format("很遗憾,在提交时发现了更新的SVN表的版本({0}),需要重新对比与新表的差异(本次新发现的差异项会将“编号”列的单元格背景调为橙色突出显示)然后选择处理方式后再提交\n\n但之前已选择的差异项的处理方式将被保留,直接在下拉列表中默认选中刚才你选择的处理方式\n\n注意:在展示主语言不同(第1个表格)以及SVN表新增Key(第2个表格)的表格中,若两次SVN表主语言译文发生变动,会将“SVN表主语言译文”列的单元格背景调为橙色突出显示", svnFileInfo.LastChangeRevision), "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); // 需要下载SVN最新版本表与本地表进行对比 string svnNewRevisionCopySavePath = Utils.CombinePath(AppValues.PROGRAM_FOLDER_PATH, string.Format("SVN最新母表副本 {0:yyyy年MM月dd日 HH时mm分ss秒} 对应SVN版本号{1}.xlsx", DateTime.Now, svnFileInfo.LastChangeRevision)); Exception exportException; bool result = OperateSvnHelper.ExportSvnFileToLocal(AppValues.SvnExcelFilePath, svnNewRevisionCopySavePath, svnFileInfo.LastChangeRevision, out exportException); if (exportException != null) { MessageBox.Show(string.Format("下载SVN中最新版本号({0})的母表文件存到本地失败,错误原因为:{1}", svnFileInfo.LastChangeRevision, exportException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); this.Close(); return; } else if (result == false) { MessageBox.Show(string.Format("下载SVN中最新版本号({0})的母表文件存到本地失败", svnFileInfo.LastChangeRevision), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); this.Close(); return; } // 解析SVN中最新的母表文件 string errorString; CommitExcelInfo newRevisionExcelInfo = CommitExcelFileHelper.AnalyzeCommitExcelFile(svnNewRevisionCopySavePath, AppValues.CommentLineStartChar, svnFileInfo.LastChangeRevision, out errorString); if (errorString != null) { MessageBox.Show(string.Format("下载的SVN中最新版本号({0})的母表文件存在以下错误,请修正后重试\n\n{1}", svnFileInfo.LastChangeRevision, errorString), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); this.Close(); return; } _newestSvnExcelInfo = newRevisionExcelInfo; // 对比本地表与SVN中最新母表文件 CommitCompareResult newCompareResult = CommitExcelFileHelper.CompareCommitExcelFile(_localExcelInfo, newRevisionExcelInfo); // 如果最新的SVN中母表与本地表反而没有任何差异,则无需提交 if (newCompareResult.IsHasDiff() == false) { _compareResult = newCompareResult; // 清空DataGridView中的内容 _CleanDataGridView(); // 更新SVN版本号显示 txtSvnFileRevision.Text = svnFileInfo.LastChangeRevision.ToString(); txtSvnFileRevision.BackColor = Color.Orange; MessageBox.Show("经对比发现本地母表与SVN中最新版本内容完全相同,无需进行提交操作", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } _RefreshDataGridView(newCompareResult); } } else { MessageBox.Show(string.Format("无法获取SVN中最新母表信息,错误原因为:{0}\n\n提交操作被迫中止", svnException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } }
// 点击“Revert并Update本地表”按钮 private void btnRevertAndUpdateLocalExcelFile_Click(object sender, EventArgs e) { FileState fileState = Utils.GetFileState(AppValues.LocalExcelFilePath); if (fileState == FileState.Inexist) { MessageBox.Show("本地表已不存在,请勿在使用本工具时对母表进行操作", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (fileState == FileState.IsOpen) { MessageBox.Show("本地表正被其他软件使用,请关闭后再重试", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 判断本地文件是否相较SVN中发生变动,若有变动提示进行备份后执行Revert SvnException svnException = null; SvnStatusEventArgs localFileState = OperateSvnHelper.GetLocalFileState(AppValues.LocalExcelFilePath, out svnException); if (svnException == null) { if (localFileState.LocalContentStatus == SvnStatus.Modified) { DialogResult dialogResult = MessageBox.Show("检测到本地文件相较于线上已发生变动,是否要进行备份?\n\n点击“是”选择存放本地表备份路径后进行备份\n点击“否”不进行备份,直接Revert后Update", "选择是否对本地表进行备份", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dialogResult == DialogResult.Yes) { SaveFileDialog dialog = new SaveFileDialog(); dialog.ValidateNames = true; dialog.Title = "请选择本地表备份路径"; dialog.Filter = "Excel files (*.xlsx)|*.xlsx"; dialog.FileName = string.Format("Revert前本地母表备份 {0:yyyy年MM月dd日 HH时mm分ss秒} 对应SVN版本号{1}.xlsx", DateTime.Now, localFileState.LastChangeRevision); if (dialog.ShowDialog() == DialogResult.OK) { string backupPath = dialog.FileName; // 检查要覆盖备份的Excel文件是否已存在且正被其他程序使用 if (Utils.GetFileState(backupPath) == FileState.IsOpen) { MessageBox.Show("要覆盖的Excel文件正被其他程序打开,请关闭后重试\n\nRevert并Update功能被迫中止", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } try { File.Copy(AppValues.LocalExcelFilePath, backupPath, true); MessageBox.Show("备份本地母表成功,点击“确定”后开始执行Revert并Update操作", "恭喜", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception exception) { string errorString = string.Format("备份本地母表({0})至指定路径({1})失败:{2}\n\nRevert并Update功能被迫中止", AppValues.LocalExcelFilePath, backupPath, exception.Message); MessageBox.Show(errorString, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else { MessageBox.Show("未选择备份路径,无法进行本地母表备份\n\nRevert并Update功能被迫中止", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } bool result = OperateSvnHelper.Revert(AppValues.LocalExcelFilePath, out svnException); if (svnException == null) { if (result == false) { MessageBox.Show("Revert失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else { MessageBox.Show(string.Concat("Revert失败,错误原因为:", svnException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else if (localFileState.LocalContentStatus != SvnStatus.Normal) { MessageBox.Show(string.Format("本地表状态为{0},本工具仅支持Normal或Modified状态", localFileState.LocalContentStatus), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 判断是否需要进行Update SvnInfoEventArgs svnFileInfo = OperateSvnHelper.GetSvnFileInfo(AppValues.SvnExcelFilePath, out svnException); if (svnException == null) { // 本地表的版本号 long localFileRevision = localFileState.LastChangeRevision; // SVN中的母表的版本号 long svnFileRevision = svnFileInfo.LastChangeRevision; if (localFileRevision == svnFileRevision) { if (localFileState.LocalContentStatus == SvnStatus.Modified) { MessageBox.Show("成功进行Revert操作,本地表已是SVN最新版本无需Update\n\nRevert并Update功能完成", "恭喜", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } else { MessageBox.Show("本地表已是SVN最新版本且与SVN中内容一致,无需进行此操作", "恭喜", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } } else { bool result = OperateSvnHelper.Update(AppValues.LocalExcelFilePath, out svnException); if (svnException == null) { if (result == false) { MessageBox.Show("Update失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else { MessageBox.Show("执行Revert并Update功能成功", "恭喜", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } } else { if (svnException is SvnAuthorizationException || svnException is SvnOperationCanceledException) { MessageBox.Show("没有权限进行Update操作,请输入合法的SVN账户信息后重试", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else { MessageBox.Show(string.Concat("Update失败,错误原因为:", svnException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } } } else { MessageBox.Show(string.Concat("无法获取SVN中母表信息,错误原因为:", svnException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else { MessageBox.Show(string.Concat("无法获取本地表状态,错误原因为:", svnException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } }