• R/O
  • SSH
  • HTTPS

tortoisesvn: Commit


Commit MetaInfo

Révision29412 (tree)
l'heure2022-06-08 00:38:11
Auteurstefankueng

Message de Log

patch from Denis Kovalchuk:
Automatically resolve tree conflicts using the recommended resolution option
when it's available. The change applies to the TortoiseSVN Merge, Switch,
Update and Resolve commands.

Subversion behaves this way starting from version 1.10.

The relevant links are:
https://svn.apache.org/r1783500
https://svn.apache.org/viewvc/subversion/trunk/subversion/svn/conflict-callbacks.c?view=markup#l1801

src/SVN/SVN.cpp:
src/SVN/SVN.h:

Implement SVN::ResolveTreeConflictById() method.

src/TortoiseProc/Commands/ConflictEditorCommand.cpp:
src/TortoiseProc/Commands/ConflictEditorCommand.h:

First try to automatically resolve a tree conflict. If it fails, fall back to
manual resolution.

src/TortoiseProc/SVNProgressDlg.cpp:
src/TortoiseProc/SVNProgressDlg.h:

For the Merge command, try to automatically resolve tree conflicts. If it
fails, fall back to manual resolution. For the Switch and Update commands, only
try the auto resolution.

Change Summary

Modification

--- trunk/src/SVN/SVN.cpp (revision 29411)
+++ trunk/src/SVN/SVN.cpp (revision 29412)
@@ -1,6 +1,6 @@
11 // TortoiseSVN - a Windows shell extension for easy version control
22
3-// Copyright (C) 2003-2021 - TortoiseSVN
3+// Copyright (C) 2003-2022 - TortoiseSVN
44
55 // This program is free software; you can redistribute it and/or
66 // modify it under the terms of the GNU General Public License
@@ -1201,6 +1201,20 @@
12011201 return (m_err == nullptr);
12021202 }
12031203
1204+bool SVN::ResolveTreeConflictById(svn_client_conflict_t* conflict, svn_client_conflict_option_id_t optionId)
1205+{
1206+ SVNPool scratchPool(m_pool);
1207+ Prepare();
1208+
1209+ const char* svnPath = svn_client_conflict_get_local_abspath(conflict);
1210+
1211+ SVNTRACE(
1212+ m_err = svn_client_conflict_tree_resolve_by_id(conflict, optionId, m_pCtx, scratchPool),
1213+ svnPath);
1214+
1215+ return (m_err == nullptr);
1216+}
1217+
12041218 bool SVN::ResolveTextConflict(svn_client_conflict_t* conflict, svn_client_conflict_option_t* option)
12051219 {
12061220 SVNPool scratchPool(m_pool);
--- trunk/src/SVN/SVN.h (revision 29411)
+++ trunk/src/SVN/SVN.h (revision 29412)
@@ -1,6 +1,6 @@
11 // TortoiseSVN - a Windows shell extension for easy version control
22
3-// Copyright (C) 2003-2021 - TortoiseSVN
3+// Copyright (C) 2003-2022 - TortoiseSVN
44
55 // This program is free software; you can redistribute it and/or
66 // modify it under the terms of the GNU General Public License
@@ -1005,6 +1005,7 @@
10051005 * In case there's no preferred move target, set those values to -1
10061006 */
10071007 bool ResolveTreeConflict(svn_client_conflict_t* conflict, svn_client_conflict_option_t* option, int preferredMovedTargetIdx, int preferredMovedReltargetIdx);
1008+ bool ResolveTreeConflictById(svn_client_conflict_t* conflict, svn_client_conflict_option_id_t optionId);
10081009 /**
10091010 * Resolves text conflict.
10101011 */
--- trunk/src/TortoiseProc/Commands/ConflictEditorCommand.cpp (revision 29411)
+++ trunk/src/TortoiseProc/Commands/ConflictEditorCommand.cpp (revision 29412)
@@ -1,6 +1,6 @@
11 // TortoiseSVN - a Windows shell extension for easy version control
22
3-// Copyright (C) 2008-2014, 2017-2018, 2021 - TortoiseSVN
3+// Copyright (C) 2008-2014, 2017-2018, 2021-2022 - TortoiseSVN
44
55 // This program is free software; you can redistribute it and/or
66 // modify it under the terms of the GNU General Public License
@@ -30,6 +30,7 @@
3030 CTSVNPath directory = merge.GetDirectory();
3131 bool bRet = false;
3232 bool bAlternativeTool = !!parser.HasKey(L"alternative");
33+ SVN svn;
3334
3435 // Use Subversion 1.10 API to resolve possible tree conlifcts.
3536 SVNConflictInfo conflict;
@@ -58,16 +59,46 @@
5859 progressDlg.Stop();
5960 conflict.SetProgressDlg(nullptr);
6061
61- CTreeConflictEditorDlg dlg;
62- dlg.SetConflictInfo(&conflict);
62+ svn_client_conflict_option_id_t recommendedOptionId = conflict.GetRecommendedOptionId();
63+ bool bAutoResolved = false;
6364
64- dlg.DoModal(GetExplorerHWND());
65- if (dlg.IsCancelled())
66- return false;
65+ if (recommendedOptionId != svn_client_conflict_option_unspecified)
66+ {
67+ if (svn.ResolveTreeConflictById(conflict, recommendedOptionId))
68+ {
69+ bAutoResolved = true;
70+ }
71+ else
72+ {
73+ apr_status_t rootCause = svn_error_root_cause(const_cast<svn_error_t*>(svn.GetSVNError()))->apr_err;
74+ if (rootCause == SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE ||
75+ rootCause == SVN_ERR_WC_OBSTRUCTED_UPDATE ||
76+ rootCause == SVN_ERR_WC_FOUND_CONFLICT)
77+ {
78+ svn.ClearSVNError();
79+ }
80+ else
81+ {
82+ svn.ShowErrorDialog(GetExplorerHWND());
83+ return false;
84+ }
85+ }
86+ }
6787
68- if (dlg.GetResult() == svn_client_conflict_option_postpone)
69- return false;
88+ // If auto resolution is not available, try to resolve manually.
89+ if (!bAutoResolved)
90+ {
91+ CTreeConflictEditorDlg dlg;
92+ dlg.SetConflictInfo(&conflict);
93+ dlg.SetSVNContext(&svn);
94+ dlg.DoModal(GetExplorerHWND());
95+ if (dlg.IsCancelled())
96+ return false;
7097
98+ if (dlg.GetResult() == svn_client_conflict_option_postpone)
99+ return false;
100+ }
101+
71102 // Send notififcation that status may be changed. We cannot use
72103 // '/resolvemsghwnd' here because satus of multiple files may be changed
73104 // during tree conflict resolution.
@@ -107,7 +138,7 @@
107138 {
108139 CPropConflictEditorDlg dlg;
109140 dlg.SetConflictInfo(&conflict);
110-
141+ dlg.SetSVNContext(&svn);
111142 dlg.DoModal(GetExplorerHWND(), i);
112143 if (dlg.IsCancelled())
113144 return false;
--- trunk/src/TortoiseProc/SVNProgressDlg.cpp (revision 29411)
+++ trunk/src/TortoiseProc/SVNProgressDlg.cpp (revision 29412)
@@ -4493,18 +4493,48 @@
44934493 progressDlg.Stop();
44944494 conflict.SetProgressDlg(nullptr);
44954495
4496- CTreeConflictEditorDlg dlg;
4497- dlg.SetConflictInfo(&conflict);
4498- dlg.SetSVNContext(this);
4499- dlg.DoModal(m_hWnd);
4500- if (dlg.IsCancelled())
4496+ svn_client_conflict_option_id_t recommendedOptionId = conflict.GetRecommendedOptionId();
4497+ bool bAutoResolved = false;
4498+
4499+ if (recommendedOptionId != svn_client_conflict_option_unspecified)
45014500 {
4502- return;
4501+ if (ResolveTreeConflictById(conflict, recommendedOptionId))
4502+ {
4503+ bAutoResolved = true;
4504+ }
4505+ else
4506+ {
4507+ apr_status_t rootCause = svn_error_root_cause(const_cast<svn_error_t*>(GetSVNError()))->apr_err;
4508+ if (rootCause == SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE ||
4509+ rootCause == SVN_ERR_WC_OBSTRUCTED_UPDATE ||
4510+ rootCause == SVN_ERR_WC_FOUND_CONFLICT)
4511+ {
4512+ ClearSVNError();
4513+ }
4514+ else
4515+ {
4516+ ShowErrorDialog(m_hWnd);
4517+ continue;
4518+ }
4519+ }
45034520 }
45044521
4505- if (dlg.GetResult() == svn_client_conflict_option_postpone)
4506- continue;
4522+ // If auto resolution is not available, try to resolve manually.
4523+ if (!bAutoResolved)
4524+ {
4525+ CTreeConflictEditorDlg dlg;
4526+ dlg.SetConflictInfo(&conflict);
4527+ dlg.SetSVNContext(this);
4528+ dlg.DoModal(m_hWnd);
4529+ if (dlg.IsCancelled())
4530+ {
4531+ return;
4532+ }
45074533
4534+ if (dlg.GetResult() == svn_client_conflict_option_postpone)
4535+ continue;
4536+ }
4537+
45084538 // Update conflict information.
45094539 if (!conflict.Get(path))
45104540 {
@@ -4571,6 +4601,79 @@
45714601 GetDlgItem(IDC_RETRYMERGE)->ShowWindow(SW_HIDE);
45724602 }
45734603 }
4604+ // Try to automatically resolve tree conflicts for Switch and Update commands.
4605+ else if ((m_command == SVNProgress_Switch) || (m_command == SVNProgress_SwitchBackToParent) ||
4606+ (m_command == SVNProgress_Update))
4607+ {
4608+ for (int i = 0; i < static_cast<int>(m_arData.size()); ++i)
4609+ {
4610+ CString info = BuildInfoString();
4611+ SetDlgItemText(IDC_INFOTEXT, info);
4612+
4613+ NotificationData* data = m_arData[i];
4614+ if (data->bConflictedActionItem)
4615+ {
4616+ // Make a copy of NotificationData::path because it data pointer
4617+ // may become invalid during processing conflict resolution callbacks.
4618+ CTSVNPath path = data->path;
4619+
4620+ SVNConflictInfo conflict;
4621+ if (!conflict.Get(path))
4622+ {
4623+ conflict.ShowErrorDialog(m_hWnd);
4624+ return;
4625+ }
4626+
4627+ if (conflict.HasTreeConflict())
4628+ {
4629+ m_progList.SetItemState(-1, 0, LVIS_SELECTED);
4630+ m_progList.SetItemState(i, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
4631+ m_progList.EnsureVisible(i, FALSE);
4632+ m_progList.SetFocus();
4633+ m_progList.SetSelectionMark(i);
4634+
4635+ CProgressDlg progressDlg;
4636+ progressDlg.SetTitle(IDS_PROC_EDIT_TREE_CONFLICTS);
4637+ CString sProgressLine;
4638+ sProgressLine.LoadString(IDS_PROGRS_FETCHING_TREE_CONFLICT_INFO);
4639+ progressDlg.SetLine(1, sProgressLine);
4640+ progressDlg.SetShowProgressBar(false);
4641+ progressDlg.ShowModal(m_hWnd, FALSE);
4642+ conflict.SetProgressDlg(&progressDlg);
4643+ if (!conflict.FetchTreeDetails())
4644+ {
4645+ conflict.ShowErrorDialog(m_hWnd);
4646+ progressDlg.Stop();
4647+ continue;
4648+ }
4649+ progressDlg.Stop();
4650+ conflict.SetProgressDlg(nullptr);
4651+
4652+ svn_client_conflict_option_id_t recommendedOptionId = conflict.GetRecommendedOptionId();
4653+
4654+ if (recommendedOptionId != svn_client_conflict_option_unspecified)
4655+ {
4656+ if (!ResolveTreeConflictById(conflict, recommendedOptionId))
4657+ {
4658+ apr_status_t rootCause = svn_error_root_cause(const_cast<svn_error_t*>(GetSVNError()))->apr_err;
4659+ if (rootCause == SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE ||
4660+ rootCause == SVN_ERR_WC_OBSTRUCTED_UPDATE ||
4661+ rootCause == SVN_ERR_WC_FOUND_CONFLICT)
4662+ {
4663+ ClearSVNError();
4664+ }
4665+ else
4666+ {
4667+ ShowErrorDialog(m_hWnd);
4668+ continue;
4669+ }
4670+ }
4671+ }
4672+ }
4673+ }
4674+ }
4675+ }
4676+
45744677 CString info = BuildInfoString();
45754678 SetDlgItemText(IDC_INFOTEXT, info);
45764679 }
Afficher sur ancien navigateur de dépôt.