Strip also single quotes from Git commands from clipboard
[TortoiseGit.git] / src / TortoiseProc / PushDlg.cpp
blobc2e1c8e50ae0e7e797718e525ad8f5cfec393b08
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2021 - TortoiseGit
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 // PushDlg.cpp : implementation file
23 #include "stdafx.h"
24 #include "TortoiseProc.h"
25 #include "PushDlg.h"
26 #include "StringUtils.h"
27 #include "Git.h"
28 #include "registry.h"
29 #include "AppUtils.h"
30 #include "LogDlg.h"
31 #include "BrowseRefsDlg.h"
32 #include "RefLogDlg.h"
33 #include "MessageBox.h"
35 // CPushDlg dialog
37 IMPLEMENT_DYNAMIC(CPushDlg, CHorizontalResizableStandAloneDialog)
39 CPushDlg::CPushDlg(CWnd* pParent /*=nullptr*/)
40 : CHorizontalResizableStandAloneDialog(CPushDlg::IDD, pParent)
41 , m_bPushAllBranches(FALSE)
42 , m_bForce(FALSE)
43 , m_bForceWithLease(FALSE)
44 , m_bTags(FALSE)
45 , m_bPushAllRemotes(FALSE)
46 , m_bSetPushBranch(FALSE)
47 , m_bSetPushRemote(FALSE)
48 , m_bSetUpstream(FALSE)
49 , m_RecurseSubmodules(0)
50 , m_bAutoLoad(CAppUtils::IsSSHPutty())
54 CPushDlg::~CPushDlg()
58 void CPushDlg::DoDataExchange(CDataExchange* pDX)
60 CHorizontalResizableStandAloneDialog::DoDataExchange(pDX);
61 DDX_Control(pDX, IDC_BRANCH_REMOTE, this->m_BranchRemote);
62 DDX_Control(pDX, IDC_BRANCH_SOURCE, this->m_BranchSource);
63 DDX_Control(pDX, IDC_REMOTE, this->m_Remote);
64 DDX_Control(pDX, IDC_URL, this->m_RemoteURL);
65 DDX_Control(pDX, IDC_BUTTON_BROWSE_SOURCE_BRANCH, m_BrowseLocalRef);
66 DDX_Control(pDX, IDC_COMBOBOX_RECURSE_SUBMODULES, m_RecurseSubmodulesCombo);
67 DDX_Control(pDX, IDC_PUSHOPTION, m_PushOption);
68 DDX_Check(pDX,IDC_FORCE,this->m_bForce);
69 DDX_Check(pDX, IDC_FORCE_WITH_LEASE, m_bForceWithLease);
70 DDX_Check(pDX,IDC_PUSHALL,this->m_bPushAllBranches);
71 DDX_Check(pDX,IDC_TAGS,this->m_bTags);
72 DDX_Check(pDX,IDC_PUTTYKEY_AUTOLOAD,this->m_bAutoLoad);
73 DDX_Check(pDX, IDC_PROC_PUSH_SET_PUSHREMOTE, m_bSetPushRemote);
74 DDX_Check(pDX, IDC_PROC_PUSH_SET_PUSHBRANCH, m_bSetPushBranch);
75 DDX_Check(pDX, IDC_PROC_PUSH_SET_UPSTREAM, m_bSetUpstream);
78 BEGIN_MESSAGE_MAP(CPushDlg, CHorizontalResizableStandAloneDialog)
79 ON_BN_CLICKED(IDC_RD_REMOTE, &CPushDlg::OnBnClickedRd)
80 ON_BN_CLICKED(IDC_RD_URL, &CPushDlg::OnBnClickedRd)
81 ON_CBN_SELCHANGE(IDC_BRANCH_SOURCE, &CPushDlg::OnCbnSelchangeBranchSource)
82 ON_CBN_SELCHANGE(IDC_REMOTE, &CPushDlg::EnDisablePushRemoteArchiveBranch)
83 ON_BN_CLICKED(IDOK, &CPushDlg::OnBnClickedOk)
84 ON_BN_CLICKED(IDC_REMOTE_MANAGE, &CPushDlg::OnBnClickedRemoteManage)
85 ON_BN_CLICKED(IDC_BUTTON_BROWSE_SOURCE_BRANCH, &CPushDlg::OnBnClickedButtonBrowseSourceBranch)
86 ON_BN_CLICKED(IDC_BUTTON_BROWSE_DEST_BRANCH, &CPushDlg::OnBnClickedButtonBrowseDestBranch)
87 ON_BN_CLICKED(IDC_PUSHALL, &CPushDlg::OnBnClickedPushall)
88 ON_BN_CLICKED(IDC_FORCE, &CPushDlg::OnBnClickedForce)
89 ON_BN_CLICKED(IDC_FORCE_WITH_LEASE, &CPushDlg::OnBnClickedForceWithLease)
90 ON_BN_CLICKED(IDC_TAGS, &CPushDlg::OnBnClickedTags)
91 ON_BN_CLICKED(IDC_PROC_PUSH_SET_UPSTREAM, &CPushDlg::OnBnClickedProcPushSetUpstream)
92 ON_BN_CLICKED(IDC_PROC_PUSH_SET_PUSHREMOTE, &CPushDlg::OnBnClickedProcPushSetPushremote)
93 ON_BN_CLICKED(IDC_PROC_PUSH_SET_PUSHBRANCH, &CPushDlg::OnBnClickedProcPushSetPushremote)
94 END_MESSAGE_MAP()
96 BOOL CPushDlg::OnInitDialog()
98 CHorizontalResizableStandAloneDialog::OnInitDialog();
99 CAppUtils::MarkWindowAsUnpinnable(m_hWnd);
101 AdjustControlSize(IDC_RD_REMOTE);
102 AdjustControlSize(IDC_RD_URL);
103 AdjustControlSize(IDC_PUSHALL);
104 AdjustControlSize(IDC_FORCE);
105 AdjustControlSize(IDC_FORCE_WITH_LEASE);
106 AdjustControlSize(IDC_TAGS);
107 AdjustControlSize(IDC_PUTTYKEY_AUTOLOAD);
108 AdjustControlSize(IDC_PROC_PUSH_SET_PUSHBRANCH);
109 AdjustControlSize(IDC_PROC_PUSH_SET_PUSHREMOTE);
110 AdjustControlSize(IDC_PROC_PUSH_SET_UPSTREAM);
111 AdjustControlSize(IDC_STATIC_RECURSE_SUBMODULES);
113 AddAnchor(IDOK,BOTTOM_RIGHT);
114 AddAnchor(IDCANCEL,BOTTOM_RIGHT);
115 AddAnchor(IDC_BRANCH_GROUP, TOP_LEFT,TOP_RIGHT);
116 AddAnchor(IDC_STATIC_REMOTE, TOP_LEFT);
117 AddAnchor(IDC_STATIC_SOURCE, TOP_LEFT);
119 AddAnchor(IDC_PUSHALL, TOP_LEFT);
120 AddAnchor(IDC_BRANCH_REMOTE, TOP_LEFT, TOP_RIGHT);
121 AddAnchor(IDC_BUTTON_BROWSE_DEST_BRANCH, TOP_RIGHT);
122 AddAnchor(IDC_BRANCH_SOURCE, TOP_LEFT, TOP_RIGHT);
123 AddAnchor(IDC_BUTTON_BROWSE_SOURCE_BRANCH, TOP_RIGHT);
125 AddAnchor(IDC_URL_GROUP, TOP_LEFT,TOP_RIGHT);
126 AddAnchor(IDC_RD_REMOTE, TOP_LEFT);
127 AddAnchor(IDC_RD_URL, TOP_LEFT);
129 AddAnchor(IDC_REMOTE, TOP_LEFT, TOP_RIGHT);
131 AddAnchor(IDC_URL, TOP_LEFT,TOP_RIGHT);
133 AddAnchor(IDC_OPTION_GROUP, TOP_LEFT,TOP_RIGHT);
135 AddAnchor(IDC_FORCE, TOP_LEFT);
136 AddAnchor(IDC_FORCE_WITH_LEASE, TOP_LEFT);
137 AddAnchor(IDC_TAGS, TOP_LEFT);
138 AddAnchor(IDC_PUTTYKEY_AUTOLOAD,TOP_LEFT);
139 AddAnchor(IDC_PROC_PUSH_SET_PUSHBRANCH, TOP_LEFT);
140 AddAnchor(IDC_PROC_PUSH_SET_PUSHREMOTE, TOP_LEFT);
141 AddAnchor(IDC_PROC_PUSH_SET_UPSTREAM, TOP_LEFT);
142 AddAnchor(IDC_STATIC_RECURSE_SUBMODULES, TOP_LEFT);
143 AddAnchor(IDC_COMBOBOX_RECURSE_SUBMODULES, TOP_LEFT);
145 AddAnchor(IDC_STATIC_PUSHOPTION, TOP_LEFT);
146 AddAnchor(IDC_PUSHOPTION, TOP_LEFT, TOP_RIGHT);
148 AddAnchor(IDC_REMOTE_MANAGE,TOP_RIGHT);
149 AddAnchor(IDHELP, BOTTOM_RIGHT);
151 AddOthersToAnchor();
153 CString sWindowTitle;
154 GetWindowText(sWindowTitle);
155 CAppUtils::SetWindowTitle(m_hWnd, g_Git.m_CurrentDir, sWindowTitle);
157 this->GetDlgItem(IDC_PUTTYKEY_AUTOLOAD)->EnableWindow(CAppUtils::IsSSHPutty());
159 EnableSaveRestore(L"PushDlg");
161 m_Remote.SetMaxHistoryItems(0x7FFFFFFF);
162 m_RemoteURL.SetCaseSensitive(TRUE);
163 m_RemoteURL.SetURLHistory(TRUE);
164 m_PushOption.SetCaseSensitive(TRUE);
166 CString WorkingDir=g_Git.m_CurrentDir;
167 WorkingDir.Replace(L':', L'_');
168 m_regPushAllRemotes = CRegDWORD(L"Software\\TortoiseGit\\TortoiseProc\\Push\\" + WorkingDir + L"\\AllRemotes", FALSE);
169 m_bPushAllRemotes = m_regPushAllRemotes;
170 m_regPushAllBranches = CRegDWORD(L"Software\\TortoiseGit\\TortoiseProc\\Push\\" + WorkingDir + L"\\AllBranches", FALSE);
171 m_bPushAllBranches = m_regPushAllBranches;
172 m_RemoteURL.LoadHistory(L"Software\\TortoiseGit\\History\\PushURLS\\" + WorkingDir, L"url");
173 m_RemoteURL.EnableWindow(FALSE);
174 m_PushOption.LoadHistory(L"Software\\TortoiseGit\\History\\PushOption\\" + WorkingDir, L"option");
175 CheckRadioButton(IDC_RD_REMOTE,IDC_RD_URL,IDC_RD_REMOTE);
177 this->m_regAutoLoad = CRegDWORD(L"Software\\TortoiseGit\\History\\PushDlgAutoLoad\\" + WorkingDir,
178 m_bAutoLoad);
179 m_bAutoLoad = this->m_regAutoLoad;
180 if(!CAppUtils::IsSSHPutty())
181 m_bAutoLoad = false;
183 m_BrowseLocalRef.m_bRightArrow = TRUE;
184 m_BrowseLocalRef.m_bDefaultClick = FALSE;
185 m_BrowseLocalRef.m_bMarkDefault = FALSE;
186 m_BrowseLocalRef.m_bShowCurrentItem = FALSE;
187 m_BrowseLocalRef.AddEntry(CString(MAKEINTRESOURCE(IDS_REFBROWSE)));
188 m_BrowseLocalRef.AddEntry(CString(MAKEINTRESOURCE(IDS_LOG)));
189 m_BrowseLocalRef.AddEntry(CString(MAKEINTRESOURCE(IDS_REFLOG)));
191 m_tooltips.AddTool(IDC_PROC_PUSH_SET_PUSHBRANCH, IDS_PUSHDLG_PUSHBRANCH_TT);
192 m_tooltips.AddTool(IDC_PROC_PUSH_SET_PUSHREMOTE, IDS_PUSHDLG_PUSHREMOTE_TT);
193 m_tooltips.AddTool(IDC_FORCE, IDS_FORCE_TT);
194 m_tooltips.AddTool(IDC_FORCE_WITH_LEASE, IDS_FORCE_WITH_LEASE_TT);
196 CString recurseSubmodules = g_Git.GetConfigValue(L"push.recurseSubmodules");
197 if (recurseSubmodules == L"check")
198 m_RecurseSubmodules = 1;
199 else if (recurseSubmodules == L"on-demand")
200 m_RecurseSubmodules = 2;
201 else
202 m_RecurseSubmodules = 0;
203 m_regRecurseSubmodules = CRegDWORD(L"Software\\TortoiseGit\\History\\PushRecurseSubmodules\\" + WorkingDir, m_RecurseSubmodules);
204 m_RecurseSubmodules = m_regRecurseSubmodules;
205 m_RecurseSubmodulesCombo.AddString(CString(MAKEINTRESOURCE(IDS_NONE)));
206 m_RecurseSubmodulesCombo.AddString(CString(MAKEINTRESOURCE(IDS_RECURSE_SUBMODULES_CHECK)));
207 m_RecurseSubmodulesCombo.AddString(CString(MAKEINTRESOURCE(IDS_RECURSE_SUBMODULES_ONDEMAND)));
208 m_RecurseSubmodulesCombo.SetCurSel(m_RecurseSubmodules);
210 Refresh();
212 this->UpdateData(false);
214 OnBnClickedPushall();
215 SetTheme(CTheme::Instance().IsDarkTheme());
216 return TRUE;
219 void CPushDlg::Refresh()
221 CString WorkingDir=g_Git.m_CurrentDir;
222 WorkingDir.Replace(L':', L'_');
224 CRegString remote(L"Software\\TortoiseGit\\History\\PushRemote\\" + WorkingDir);
225 m_RemoteReg = remote;
226 int sel = -1;
228 STRING_VECTOR list;
229 m_Remote.Reset();
231 if(!g_Git.GetRemoteList(list))
233 if (list.size() > 1)
234 m_Remote.AddString(CString(MAKEINTRESOURCE(IDS_PROC_PUSHFETCH_ALLREMOTES)));
235 for (unsigned int i = 0; i < list.size(); ++i)
237 m_Remote.AddString(list[i]);
238 if(list[i] == remote)
239 sel = i + (list.size() > 1 ? 1 : 0);
242 else
243 MessageBox(g_Git.GetGitLastErr(L"Could not get list of remotes."), L"TortoiseGit", MB_ICONERROR);
244 // if the last selected remote was "- All -" and "- All -" is still in the list -> select it
245 if (list.size() > 1 && remote == CString(MAKEINTRESOURCE(IDS_PROC_PUSHFETCH_ALLREMOTES)))
246 sel = 0;
247 m_Remote.SetCurSel(sel);
249 int current = -1;
250 list.clear();
251 m_BranchSource.Reset();
252 m_BranchSource.SetMaxHistoryItems(0x7FFFFFFF);
253 if(!g_Git.GetBranchList(list,&current))
254 m_BranchSource.SetList(list);
255 else
256 MessageBox(g_Git.GetGitLastErr(L"Could not get list of local branches."), L"TortoiseGit", MB_ICONERROR);
257 if (CStringUtils::StartsWith(m_BranchSourceName, L"refs/heads/"))
259 m_BranchSourceName = m_BranchSourceName.Mid(static_cast<int>(wcslen(L"refs/heads/")));
260 m_BranchSource.SetCurSel(m_BranchSource.FindStringExact(-1, m_BranchSourceName));
262 else if (CStringUtils::StartsWith(m_BranchSourceName, L"refs/remotes/") || CStringUtils::StartsWith(m_BranchSourceName, L"remotes/"))
264 if (CStringUtils::StartsWith(m_BranchSourceName, L"refs/"))
265 m_BranchSourceName = m_BranchSourceName.Mid(static_cast<int>(wcslen(L"refs/")));
266 m_BranchSource.SetCurSel(m_BranchSource.FindStringExact(-1, m_BranchSourceName));
268 else if (m_BranchSourceName.IsEmpty() && current == -1 && !g_Git.IsInitRepos())
269 m_BranchSource.SetWindowText(L"HEAD");
270 else if (m_BranchSourceName.IsEmpty())
271 m_BranchSource.SetCurSel(current);
272 else
273 m_BranchSource.SetWindowText(m_BranchSourceName);
275 GetRemoteBranch(m_BranchSource.GetString());
276 CString trackRemote, trackBranch;
277 g_Git.GetRemoteTrackedBranchForHEAD(trackRemote, trackBranch);
278 if (trackRemote.IsEmpty() && trackBranch.IsEmpty())
280 // if the local branch is not yet tracked, make that the default
281 m_bSetUpstream = TRUE;
282 UpdateData(FALSE);
285 if (list.size() > 1 && m_bPushAllRemotes)
286 m_Remote.SetCurSel(0);
287 m_bPushAllRemotes = FALSE; // reset to FALSE, so that a refresh does not reselect all even if it was already deselected by user; correct value will be set in OnBnClickedOk method
290 void CPushDlg::GetRemoteBranch(CString currentBranch)
292 CString WorkingDir=g_Git.m_CurrentDir;
293 WorkingDir.Replace(L':', L'_');
295 if (currentBranch.IsEmpty())
297 EnDisablePushRemoteArchiveBranch();
298 return;
301 CString pushRemote;
302 CString pushBranch;
303 g_Git.GetRemotePushBranch(currentBranch, pushRemote, pushBranch);
305 CRegString remote(L"Software\\TortoiseGit\\History\\PushRemote\\" + WorkingDir);
307 if (!pushRemote.IsEmpty())
309 remote = pushRemote;
310 // if a pushRemote exists, select it
311 for (int i = 0; i < m_Remote.GetCount(); ++i)
313 CString str;
314 int n = m_Remote.GetLBTextLen(i);
315 m_Remote.GetLBText(i, CStrBuf(str, n));
316 if (str == pushRemote)
318 m_Remote.SetCurSel(i);
319 break;
323 // select the only remote if only one exists
324 else if (m_Remote.GetCount() == 1)
325 m_Remote.SetCurSel(0);
326 // select no remote if no push-remote is specified AND push to all remotes is not selected
327 else if (!(m_Remote.GetCount() > 1 && m_Remote.GetCurSel() == 0))
328 m_Remote.SetCurSel(-1);
330 m_BranchRemote.LoadHistory(L"Software\\TortoiseGit\\History\\RemoteBranch\\" + WorkingDir, L"branch");
331 if( !pushBranch.IsEmpty() )
332 m_BranchRemote.AddString(pushBranch);
334 EnDisablePushRemoteArchiveBranch();
337 void CPushDlg::EnDisablePushRemoteArchiveBranch()
339 if ((m_Remote.GetCount() > 1 && m_Remote.GetCurSel() == 0) || m_bPushAllBranches || GetCheckedRadioButton(IDC_RD_REMOTE,IDC_RD_URL) == IDC_RD_URL || m_BranchSource.GetString().Trim().IsEmpty())
341 DialogEnableWindow(IDC_PROC_PUSH_SET_PUSHBRANCH, FALSE);
342 DialogEnableWindow(IDC_PROC_PUSH_SET_PUSHREMOTE, FALSE);
343 bool enableUpstream = (GetCheckedRadioButton(IDC_RD_REMOTE, IDC_RD_URL) != IDC_RD_URL && (!m_BranchSource.GetString().Trim().IsEmpty() || m_bPushAllBranches));
344 DialogEnableWindow(IDC_PROC_PUSH_SET_UPSTREAM, enableUpstream);
345 if (m_bSetUpstream && !enableUpstream)
346 m_bSetUpstream = FALSE;
347 m_bSetPushRemote = FALSE;
348 m_bSetPushBranch = FALSE;
349 UpdateData(FALSE);
351 else
353 DialogEnableWindow(IDC_PROC_PUSH_SET_UPSTREAM, TRUE);
354 DialogEnableWindow(IDC_PROC_PUSH_SET_PUSHBRANCH, !m_bSetUpstream);
355 DialogEnableWindow(IDC_PROC_PUSH_SET_PUSHREMOTE, !m_bSetUpstream);
359 // CPushDlg message handlers
361 void CPushDlg::OnBnClickedRd()
363 if( GetCheckedRadioButton(IDC_RD_REMOTE,IDC_RD_URL) == IDC_RD_REMOTE)
365 m_Remote.EnableWindow(TRUE);
366 GetDlgItem(IDC_REMOTE_MANAGE)->EnableWindow(TRUE);
367 m_RemoteURL.EnableWindow(FALSE);
369 if( GetCheckedRadioButton(IDC_RD_REMOTE,IDC_RD_URL) == IDC_RD_URL)
371 // similar code in PullFetchDlg::OnBnClickedRd
372 CString clippath = CAppUtils::GetClipboardLink(L"git pull", 1);
373 if (clippath.IsEmpty())
374 clippath = CAppUtils::GetClipboardLink(L"git fetch", 1);
375 if (clippath.IsEmpty())
376 m_RemoteURL.SetCurSel(0);
377 else
379 int argSeparator = clippath.Find(' ');
380 if (argSeparator > 1 && clippath.GetLength() > argSeparator + 2)
382 CString url = clippath.Left(argSeparator);
383 if (url.GetLength() > 2 && (url[0] == L'"' && url[url.GetLength() - 1] == L'"' || url[0] == L'\'' && url[url.GetLength() - 1] == L'\''))
384 url = url.Mid(1, url.GetLength() - 2);
385 m_RemoteURL.SetWindowText(url);
386 CString branch = clippath.Mid(argSeparator + 1);
387 if (branch.GetLength() > 2 && (branch[0] == L'"' && branch[branch.GetLength() - 1] == L'"' || branch[0] == L'\'' && branch[branch.GetLength() - 1] == L'\''))
388 branch = branch.Mid(1, branch.GetLength() - 2);
389 m_BranchRemote.SetWindowText(branch);
391 else
392 m_RemoteURL.SetWindowText(clippath);
394 m_Remote.EnableWindow(FALSE);
395 GetDlgItem(IDC_REMOTE_MANAGE)->EnableWindow(FALSE);
396 m_RemoteURL.EnableWindow(TRUE);
398 EnDisablePushRemoteArchiveBranch();
402 void CPushDlg::OnCbnSelchangeBranchSource()
404 GetRemoteBranch(m_BranchSource.GetString());
407 void CPushDlg::OnBnClickedOk()
409 CHorizontalResizableStandAloneDialog::UpdateData(TRUE);
411 if( GetCheckedRadioButton(IDC_RD_REMOTE,IDC_RD_URL) == IDC_RD_REMOTE)
413 m_URL=m_Remote.GetString();
414 if (m_URL.IsEmpty())
416 CMessageBox::Show(GetSafeHwnd(), IDS_PROC_GITCONFIG_REMOTEEMPTY, IDS_APPNAME, MB_OK | MB_ICONEXCLAMATION);
417 return;
419 m_bPushAllRemotes = (m_Remote.GetCurSel() == 0 && m_Remote.GetCount() > 1);
421 if( GetCheckedRadioButton(IDC_RD_REMOTE,IDC_RD_URL) == IDC_RD_URL)
422 m_URL=m_RemoteURL.GetString();
424 if (m_bPushAllBranches)
426 BOOL dontaskagainchecked = FALSE;
427 if (CMessageBox::ShowCheck(GetSafeHwnd(), IDS_PROC_PUSH_ALLBRANCHES, IDS_APPNAME, MB_ICONQUESTION | MB_DEFBUTTON2 | MB_YESNO, L"PushAllBranches", IDS_MSGBOX_DONOTSHOWAGAIN, &dontaskagainchecked) == IDNO)
429 if (dontaskagainchecked)
430 CMessageBox::SetRegistryValue(L"PushAllBranches", IDYES);
431 return;
434 else
436 this->m_BranchRemoteName=m_BranchRemote.GetString().Trim();
437 this->m_BranchSourceName=m_BranchSource.GetString().Trim();
439 if (m_BranchSourceName.IsEmpty() && m_BranchRemoteName.IsEmpty())
441 if (CMessageBox::Show(GetSafeHwnd(), IDS_B_T_BOTHEMPTY, IDS_APPNAME, MB_ICONQUESTION | MB_YESNO) != IDYES)
442 return;
444 if (m_BranchSourceName.IsEmpty() && !m_BranchRemoteName.IsEmpty())
446 if (CMessageBox::Show(GetSafeHwnd(), IDS_B_T_LOCALEMPTY, IDS_APPNAME, MB_ICONEXCLAMATION | MB_YESNO) != IDYES)
447 return;
449 else if (!m_BranchRemoteName.IsEmpty() && !g_Git.IsBranchNameValid(this->m_BranchRemoteName))
451 CMessageBox::Show(GetSafeHwnd(), IDS_B_T_INVALID, IDS_APPNAME, MB_OK | MB_ICONEXCLAMATION);
452 return;
454 else if (!m_BranchSourceName.IsEmpty() && !g_Git.IsBranchTagNameUnique(m_BranchSourceName))
456 CMessageBox::Show(GetSafeHwnd(), IDS_B_T_NOT_UNIQUE, IDS_APPNAME, MB_OK | MB_ICONEXCLAMATION);
457 return;
459 else
461 // do not store branch names on removal
462 if (m_RemoteURL.IsWindowEnabled())
463 m_RemoteURL.SaveHistory(); // do not store Remote URLs if not used
464 this->m_BranchRemote.SaveHistory();
465 m_RemoteReg = m_Remote.GetString();
467 if (!m_BranchSourceName.IsEmpty() && g_Git.IsLocalBranch(m_BranchSourceName))
469 CString configName;
470 if (m_bSetPushBranch)
472 configName.Format(L"branch.%s.pushbranch", static_cast<LPCWSTR>(m_BranchSourceName));
473 if (!m_BranchRemoteName.IsEmpty())
474 g_Git.SetConfigValue(configName, m_BranchRemoteName);
475 else
476 g_Git.UnsetConfigValue(configName);
478 if (m_bSetPushRemote)
480 configName.Format(L"branch.%s.pushremote", static_cast<LPCWSTR>(m_BranchSourceName));
481 if (!m_URL.IsEmpty())
482 g_Git.SetConfigValue(configName, m_URL);
483 else
484 g_Git.UnsetConfigValue(configName);
490 m_sPushOption = m_PushOption.GetString();
491 m_PushOption.SaveHistory();
493 m_regPushAllBranches = m_bPushAllBranches;
494 m_regPushAllRemotes = m_bPushAllRemotes;
495 this->m_regAutoLoad = m_bAutoLoad ;
496 m_RecurseSubmodules = m_RecurseSubmodulesCombo.GetCurSel();
497 m_regRecurseSubmodules = m_RecurseSubmodules;
499 CHorizontalResizableStandAloneDialog::OnOK();
502 void CPushDlg::OnBnClickedRemoteManage()
504 CAppUtils::LaunchRemoteSetting();
505 Refresh();
508 void CPushDlg::OnBnClickedButtonBrowseSourceBranch()
510 switch (m_BrowseLocalRef.GetCurrentEntry())
512 case 0: /* Browse Refence*/
514 if (CBrowseRefsDlg::PickRefForCombo(m_BranchSource, gPickRef_Head | gPickRef_Tag))
515 OnCbnSelchangeBranchSource();
517 break;
519 case 1: /* Log */
521 CLogDlg dlg;
522 if (dlg.IsThreadRunning())
524 CMessageBox::Show(GetSafeHwnd(), IDS_PROC_LOG_ONLYONCE, IDS_APPNAME, MB_ICONEXCLAMATION);
525 return;
527 CString revision;
528 m_BranchSource.GetWindowText(revision);
529 dlg.SetParams(CTGitPath(), CTGitPath(), revision, revision, 0);
530 dlg.SetSelect(true);
531 dlg.ShowWorkingTreeChanges(false);
532 if (dlg.DoModal() == IDOK && !dlg.GetSelectedHash().empty())
534 m_BranchSource.SetWindowText(dlg.GetSelectedHash().at(0).ToString());
535 OnCbnSelchangeBranchSource();
537 BringWindowToTop(); /* cf. issue #3493 */
539 break;
541 case 2: /*RefLog*/
543 CRefLogDlg dlg;
544 if(dlg.DoModal() == IDOK)
546 m_BranchSource.SetWindowText(dlg.m_SelectedHash.ToString());
547 OnCbnSelchangeBranchSource();
550 break;
554 void CPushDlg::OnBnClickedButtonBrowseDestBranch()
556 CString remoteBranchName;
557 CString remoteName;
558 m_BranchRemote.GetWindowText(remoteBranchName);
559 remoteName = m_Remote.GetString();
560 remoteBranchName = remoteName + '/' + remoteBranchName;
561 remoteBranchName = CBrowseRefsDlg::PickRef(false, remoteBranchName, gPickRef_Remote);
562 if(remoteBranchName.IsEmpty())
563 return; //Canceled
564 remoteBranchName = remoteBranchName.Mid(static_cast<int>(wcslen(L"refs/remotes/"))); //Strip 'refs/remotes/'
565 int slashPlace = remoteBranchName.Find('/');
566 remoteName = remoteBranchName.Left(slashPlace);
567 remoteBranchName = remoteBranchName.Mid(slashPlace + 1); //Strip remote name (for example 'origin/')
569 //Select remote
570 int remoteSel = m_Remote.FindStringExact(0,remoteName);
571 if(remoteSel >= 0)
572 m_Remote.SetCurSel(remoteSel);
574 //Select branch
575 m_BranchRemote.AddString(remoteBranchName, 0);
578 BOOL CPushDlg::PreTranslateMessage(MSG* pMsg)
580 if (pMsg->message == WM_KEYDOWN)
582 switch (pMsg->wParam)
584 case VK_F5:
586 Refresh();
588 break;
592 return CHorizontalResizableStandAloneDialog::PreTranslateMessage(pMsg);
595 void CPushDlg::OnBnClickedPushall()
597 this->UpdateData();
598 this->GetDlgItem(IDC_BRANCH_REMOTE)->EnableWindow(!m_bPushAllBranches);
599 this->GetDlgItem(IDC_BRANCH_SOURCE)->EnableWindow(!m_bPushAllBranches);
600 this->GetDlgItem(IDC_BUTTON_BROWSE_SOURCE_BRANCH)->EnableWindow(!m_bPushAllBranches);
601 this->GetDlgItem(IDC_BUTTON_BROWSE_DEST_BRANCH)->EnableWindow(!m_bPushAllBranches);
602 EnDisablePushRemoteArchiveBranch();
605 void CPushDlg::OnBnClickedForce()
607 UpdateData();
608 GetDlgItem(IDC_FORCE_WITH_LEASE)->EnableWindow(m_bTags || m_bForce ? FALSE : TRUE);
611 void CPushDlg::OnBnClickedForceWithLease()
613 UpdateData();
614 GetDlgItem(IDC_FORCE)->EnableWindow(m_bForceWithLease ? FALSE : TRUE);
615 GetDlgItem(IDC_TAGS)->EnableWindow(m_bForceWithLease ? FALSE : TRUE);
618 void CPushDlg::OnBnClickedTags()
620 UpdateData();
621 GetDlgItem(IDC_FORCE_WITH_LEASE)->EnableWindow(m_bTags || m_bForce ? FALSE : TRUE);
624 void CPushDlg::OnBnClickedProcPushSetUpstream()
626 UpdateData();
627 this->GetDlgItem(IDC_PROC_PUSH_SET_PUSHREMOTE)->EnableWindow(!m_bSetUpstream);
628 this->GetDlgItem(IDC_PROC_PUSH_SET_PUSHBRANCH)->EnableWindow(!m_bSetUpstream);
629 m_bSetPushBranch = FALSE;
630 m_bSetPushRemote = FALSE;
631 UpdateData(FALSE);
634 void CPushDlg::OnBnClickedProcPushSetPushremote()
636 UpdateData();
637 this->GetDlgItem(IDC_PROC_PUSH_SET_UPSTREAM)->EnableWindow(!(m_bSetPushBranch || m_bSetPushRemote));
638 m_bSetUpstream = FALSE;
639 UpdateData(FALSE);