1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2015 - 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 // PullFetchDlg.cpp : implementation file
24 #include "TortoiseProc.h"
25 #include "PullFetchDlg.h"
28 #include "BrowseRefsDlg.h"
29 // CPullFetchDlg dialog
31 IMPLEMENT_DYNAMIC(CPullFetchDlg
, CHorizontalResizableStandAloneDialog
)
33 CPullFetchDlg::CPullFetchDlg(CWnd
* pParent
/*=NULL*/)
34 : CHorizontalResizableStandAloneDialog(CPullFetchDlg::IDD
, pParent
)
37 m_bRebaseActivatedInConfigForPull
= false;
38 m_bAutoLoad
= CAppUtils::IsSSHPutty();
39 m_bAutoLoadEnable
=CAppUtils::IsSSHPutty();;
49 m_bAllRemotes
= FALSE
;
50 m_bPrune
= CAppUtils::GetMsysgitVersion() >= 0x01080500 ? 2 : FALSE
;
53 CPullFetchDlg::~CPullFetchDlg()
57 void CPullFetchDlg::DoDataExchange(CDataExchange
* pDX
)
59 CDialog::DoDataExchange(pDX
);
60 DDX_Control(pDX
, IDC_REMOTE_COMBO
, this->m_Remote
);
61 DDX_Control(pDX
, IDC_OTHER
, this->m_Other
);
62 DDX_Control(pDX
, IDC_REMOTE_BRANCH
, this->m_RemoteBranch
);
63 DDX_Control(pDX
,IDC_REMOTE_MANAGE
, this->m_RemoteManage
);
64 DDX_Check(pDX
,IDC_CHECK_NOFF
, this->m_bNoFF
);
65 DDX_Check(pDX
,IDC_CHECK_SQUASH
, this->m_bSquash
);
66 DDX_Check(pDX
,IDC_CHECK_NOCOMMIT
, this->m_bNoCommit
);
67 DDX_Check(pDX
,IDC_PUTTYKEY_AUTOLOAD
,m_bAutoLoad
);
68 DDX_Check(pDX
,IDC_CHECK_REBASE
,m_bRebase
);
69 DDX_Check(pDX
,IDC_CHECK_PRUNE
,m_bPrune
);
70 DDX_Check(pDX
, IDC_CHECK_DEPTH
, m_bDepth
);
71 DDX_Text(pDX
, IDC_EDIT_DEPTH
, m_nDepth
);
72 DDX_Check(pDX
, IDC_CHECK_FFONLY
, m_bFFonly
);
73 DDX_Check(pDX
, IDC_CHECK_FETCHTAGS
, m_bFetchTags
);
77 BEGIN_MESSAGE_MAP(CPullFetchDlg
, CHorizontalResizableStandAloneDialog
)
78 ON_CBN_SELCHANGE(IDC_REMOTE_COMBO
, &CPullFetchDlg::OnCbnSelchangeRemote
)
79 ON_BN_CLICKED(IDC_REMOTE_RD
, &CPullFetchDlg::OnBnClickedRd
)
80 ON_BN_CLICKED(IDC_OTHER_RD
, &CPullFetchDlg::OnBnClickedRd
)
81 ON_BN_CLICKED(IDOK
, &CPullFetchDlg::OnBnClickedOk
)
82 ON_STN_CLICKED(IDC_REMOTE_MANAGE
, &CPullFetchDlg::OnStnClickedRemoteManage
)
83 ON_BN_CLICKED(IDC_BUTTON_BROWSE_REF
, &CPullFetchDlg::OnBnClickedButtonBrowseRef
)
84 ON_BN_CLICKED(IDC_CHECK_DEPTH
, OnBnClickedCheckDepth
)
85 ON_BN_CLICKED(IDC_CHECK_FETCHTAGS
, OnBnClickedCheckFetchtags
)
86 ON_BN_CLICKED(IDC_CHECK_FFONLY
, OnBnClickedCheckFfonly
)
87 ON_BN_CLICKED(IDC_CHECK_NOFF
, OnBnClickedCheckFfonly
)
90 BOOL
CPullFetchDlg::OnInitDialog()
92 CHorizontalResizableStandAloneDialog::OnInitDialog();
93 CAppUtils::MarkWindowAsUnpinnable(m_hWnd
);
95 AddAnchor(IDC_REMOTE_COMBO
, TOP_LEFT
, TOP_RIGHT
);
96 AddAnchor(IDC_OTHER
, TOP_LEFT
,TOP_RIGHT
);
98 AddAnchor(IDC_REMOTE_BRANCH
, TOP_LEFT
,TOP_RIGHT
);
99 AddAnchor(IDC_BUTTON_BROWSE_REF
,TOP_RIGHT
);
101 AddAnchor(IDOK
,BOTTOM_RIGHT
);
102 AddAnchor(IDCANCEL
,BOTTOM_RIGHT
);
103 AddAnchor(IDC_GROUPT_REMOTE
,TOP_LEFT
,TOP_RIGHT
);
104 AddAnchor(IDC_GROUP_OPTION
,TOP_LEFT
,TOP_RIGHT
);
105 AddAnchor(IDC_PUTTYKEY_AUTOLOAD
,BOTTOM_LEFT
);
106 AddAnchor(IDC_CHECK_PRUNE
,BOTTOM_LEFT
);
107 AddAnchor(IDC_CHECK_REBASE
,BOTTOM_LEFT
);
108 AddAnchor(IDC_REMOTE_MANAGE
,BOTTOM_LEFT
);
109 AddAnchor(IDHELP
, BOTTOM_RIGHT
);
111 AdjustControlSize(IDC_REMOTE_RD
);
112 AdjustControlSize(IDC_OTHER_RD
);
113 AdjustControlSize(IDC_CHECK_SQUASH
);
114 AdjustControlSize(IDC_CHECK_NOCOMMIT
);
115 AdjustControlSize(IDC_CHECK_DEPTH
);
116 AdjustControlSize(IDC_CHECK_NOFF
);
117 AdjustControlSize(IDC_CHECK_FFONLY
);
118 AdjustControlSize(IDC_CHECK_FETCHTAGS
);
119 AdjustControlSize(IDC_PUTTYKEY_AUTOLOAD
);
120 AdjustControlSize(IDC_CHECK_REBASE
);
121 AdjustControlSize(IDC_CHECK_PRUNE
);
123 CString WorkingDir
=g_Git
.m_CurrentDir
;
124 WorkingDir
.Replace(_T(':'),_T('_'));
126 m_RemoteReg
= CRegString(CString(_T("Software\\TortoiseGit\\History\\PullRemote\\")+WorkingDir
));
128 regkey
.Format(_T("Software\\TortoiseGit\\TortoiseProc\\PullFetch\\%s_%d\\rebase"),WorkingDir
,this->m_IsPull
);
129 m_regRebase
=CRegDWORD(regkey
,false);
130 regkey
.Format(_T("Software\\TortoiseGit\\TortoiseProc\\PullFetch\\%s_%d\\ffonly"), WorkingDir
, m_IsPull
);
131 m_regFFonly
= CRegDWORD(regkey
, false);
132 regkey
.Format(_T("Software\\TortoiseGit\\TortoiseProc\\PullFetch\\%s_%d\\autoload"),WorkingDir
,this->m_IsPull
);
134 m_regAutoLoadPutty
= CRegDWORD(regkey
,this->m_bAutoLoad
);
135 m_bAutoLoad
= m_regAutoLoadPutty
;
137 if(!CAppUtils::IsSSHPutty())
140 m_bRebase
= m_regRebase
;
142 CAutoRepository
repo(g_Git
.GetGitRepository());
144 MessageBox(CGit::GetLibGit2LastErr(_T("Could not open repository.")), _T("TortoiseGit"), MB_OK
| MB_ICONERROR
);
146 // Check config branch.<name>.rebase and pull.reabse
154 if (git_repository_head_detached(repo
) == 1)
157 CAutoConfig
config(true);
158 if (git_repository_config(config
.GetPointer(), repo
))
162 // branch.<name>.rebase overrides pull.rebase
163 if (config
.GetBOOL(_T("branch.") + g_Git
.GetCurrentBranch() + _T(".rebase"), rebase
) == GIT_ENOTFOUND
)
165 if (config
.GetBOOL(_T("pull.rebase"), rebase
) == GIT_ENOTFOUND
)
171 // Since rebase = true in config, means that "git.exe pull" will ALWAYS rebase without "--rebase".
172 // So, lock it, then let Fetch Rebase do the rest things.
174 m_bRebaseActivatedInConfigForPull
= true;
177 this->UpdateData(FALSE
);
179 this->AddOthersToAnchor();
181 this->GetDlgItem(IDC_PUTTYKEY_AUTOLOAD
)->EnableWindow(m_bAutoLoadEnable
);
183 CheckRadioButton(IDC_REMOTE_RD
,IDC_OTHER_RD
,IDC_REMOTE_RD
);
184 m_Remote
.EnableWindow(TRUE
);
185 m_Remote
.SetMaxHistoryItems(0x7FFFFFFF);
186 m_Other
.EnableWindow(FALSE
);
189 m_RemoteBranch
.EnableWindow(FALSE
);
190 GetDlgItem(IDC_BUTTON_BROWSE_REF
)->EnableWindow(FALSE
);
195 m_bFFonly
= m_regFFonly
;
197 OnBnClickedCheckFfonly();
201 this->GetDlgItem(IDC_GROUP_OPTION
)->EnableWindow(FALSE
);
202 this->GetDlgItem(IDC_CHECK_SQUASH
)->EnableWindow(FALSE
);
203 this->GetDlgItem(IDC_CHECK_NOFF
)->EnableWindow(FALSE
);
204 this->GetDlgItem(IDC_CHECK_FFONLY
)->EnableWindow(FALSE
);
205 this->GetDlgItem(IDC_CHECK_NOCOMMIT
)->EnableWindow(FALSE
);
208 if (GitAdminDir::IsBareRepo(g_Git
.m_CurrentDir
))
209 this->GetDlgItem(IDC_CHECK_REBASE
)->EnableWindow(FALSE
);
211 if (repo
&& git_repository_is_shallow(repo
))
218 GetDlgItem(IDC_CHECK_DEPTH
)->ShowWindow(SW_HIDE
);
219 GetDlgItem(IDC_EDIT_DEPTH
)->ShowWindow(SW_HIDE
);
221 OnBnClickedCheckDepth();
223 m_Other
.SetCaseSensitive(TRUE
);
224 m_Other
.SetURLHistory(TRUE
);
225 m_Other
.LoadHistory(_T("Software\\TortoiseGit\\History\\PullURLS"), _T("url"));
227 m_RemoteBranch
.LoadHistory(_T("Software\\TortoiseGit\\History\\PullRemoteBranch"), _T("br"));
228 m_RemoteBranch
.SetCurSel(0);
230 CString sWindowTitle
;
232 sWindowTitle
= CString(MAKEINTRESOURCE(IDS_PROGRS_TITLE_PULL
));
234 sWindowTitle
= CString(MAKEINTRESOURCE(IDS_PROGRS_TITLE_FETCH
));
236 CAppUtils::SetWindowTitle(m_hWnd
, g_Git
.m_CurrentDir
, sWindowTitle
);
240 EnableSaveRestore(_T("PullFetchDlg"));
241 this->m_RemoteManage
.SetURL(CString());
245 void CPullFetchDlg::Refresh()
247 //Select pull-remote from current branch
248 CString currentBranch
;
249 if (g_Git
.GetCurrentBranchFromFile(g_Git
.m_CurrentDir
, currentBranch
))
250 currentBranch
.Empty();
252 CString pullRemote
, pullBranch
;
253 g_Git
.GetRemoteTrackedBranch(currentBranch
, pullRemote
, pullBranch
);
254 m_configPullRemote
= pullRemote
;
255 m_configPullBranch
= pullBranch
;
257 if (pullBranch
.IsEmpty())
258 m_RemoteBranch
.AddString(currentBranch
);
260 m_RemoteBranch
.AddString(pullBranch
);
262 if(pullRemote
.IsEmpty())
263 pullRemote
= m_RemoteReg
;
265 if (!m_PreSelectRemote
.IsEmpty())
266 pullRemote
= m_PreSelectRemote
;
271 if(!g_Git
.GetRemoteList(list
))
273 if (!m_IsPull
&& list
.size() > 1)
274 m_Remote
.AddString(CString(MAKEINTRESOURCE(IDS_PROC_PUSHFETCH_ALLREMOTES
)));
276 for (unsigned int i
= 0; i
< list
.size(); ++i
)
278 m_Remote
.AddString(list
[i
]);
279 if (!m_bAllRemotes
&& list
[i
] == pullRemote
)
280 sel
= i
+ (!m_IsPull
&& list
.size() > 1 ? 1 : 0);
283 m_Remote
.SetCurSel(sel
);
284 OnCbnSelchangeRemote();
286 // CPullFetchDlg message handlers
288 void CPullFetchDlg::OnCbnSelchangeRemote()
290 CString remote
= m_Remote
.GetString();
291 if (remote
.IsEmpty() || remote
== CString(MAKEINTRESOURCE(IDS_PROC_PUSHFETCH_ALLREMOTES
)))
293 GetDlgItem(IDC_STATIC_TAGOPT
)->SetWindowText(_T(""));
294 GetDlgItem(IDC_STATIC_PRUNE
)->SetWindowText(_T(""));
299 key
.Format(_T("remote.%s.tagopt"), remote
);
300 CString tagopt
= g_Git
.GetConfigValue(key
);
301 if (tagopt
== "--no-tags")
302 tagopt
= CString(MAKEINTRESOURCE(IDS_NONE
));
303 else if (tagopt
== "--tags")
304 tagopt
= CString(MAKEINTRESOURCE(CAppUtils::GetMsysgitVersion() < 0x01090000 ? IDS_FETCH_TAGS_ONLY
: IDS_ALL
));
306 tagopt
= CString(MAKEINTRESOURCE(IDS_FETCH_REACHABLE
));
308 value
.Format(_T("%s: %s"), CString(MAKEINTRESOURCE(IDS_DEFAULT
)), tagopt
);
309 GetDlgItem(IDC_STATIC_TAGOPT
)->SetWindowText(value
);
312 if (CAppUtils::GetMsysgitVersion() >= 0x01080500)
314 key
.Format(_T("remote.%s.prune"), remote
);
315 prune
= g_Git
.GetConfigValue(key
);
317 prune
= g_Git
.GetConfigValue(_T("fetch.prune"));
319 if (!prune
.IsEmpty())
322 value
.Format(_T("%s: %s"), CString(MAKEINTRESOURCE(IDS_DEFAULT
)), prune
);
323 GetDlgItem(IDC_STATIC_PRUNE
)->SetWindowText(value
);
326 GetDlgItem(IDC_STATIC_PRUNE
)->SetWindowText(_T(""));
329 void CPullFetchDlg::OnBnClickedRd()
331 if( GetCheckedRadioButton(IDC_REMOTE_RD
,IDC_OTHER_RD
) == IDC_REMOTE_RD
)
333 m_Remote
.EnableWindow(TRUE
);
334 m_Other
.EnableWindow(FALSE
);
335 DialogEnableWindow(IDC_CHECK_REBASE
, TRUE
);
336 m_bRebase
= m_bRebaseActivatedInConfigForPull
;
339 m_RemoteBranch
.EnableWindow(FALSE
);
341 if( GetCheckedRadioButton(IDC_REMOTE_RD
,IDC_OTHER_RD
) == IDC_OTHER_RD
)
343 CString clippath
= CAppUtils::GetClipboardLink(m_IsPull
? _T("git pull") : _T("git fetch"), 1);
344 if (clippath
.IsEmpty())
345 m_Other
.SetCurSel(0);
348 int argSeparator
= clippath
.Find(' ');
349 if (argSeparator
> 1 && clippath
.GetLength() > argSeparator
+ 2)
351 m_Other
.SetWindowText(clippath
.Left(argSeparator
));
352 m_RemoteBranch
.SetWindowText(clippath
.Mid(argSeparator
+ 1));
355 m_Other
.SetWindowText(clippath
);
357 m_Remote
.EnableWindow(FALSE
);
358 m_Other
.EnableWindow(TRUE
);;
359 DialogEnableWindow(IDC_CHECK_REBASE
, FALSE
);
363 m_RemoteBranch
.EnableWindow(TRUE
);
367 void CPullFetchDlg::OnBnClickedOk()
370 if( GetCheckedRadioButton(IDC_REMOTE_RD
,IDC_OTHER_RD
) == IDC_REMOTE_RD
)
372 m_RemoteURL
=m_Remote
.GetString();
373 m_bAllRemotes
= (m_Remote
.GetCurSel() == 0 && m_Remote
.GetCount() > 1 && !m_IsPull
);
375 (m_configPullRemote
== m_RemoteURL
&& m_configPullBranch
== m_RemoteBranch
.GetString() ))
376 //When fetching or when pulling from the configured tracking branch, dont explicitly set the remote branch name,
377 //because otherwise git will not update the remote tracking branches.
378 m_RemoteBranchName
.Empty();
380 m_RemoteBranchName
=m_RemoteBranch
.GetString();
382 if( GetCheckedRadioButton(IDC_REMOTE_RD
,IDC_OTHER_RD
) == IDC_OTHER_RD
)
384 m_Other
.GetWindowTextW(m_RemoteURL
);
385 m_RemoteBranchName
=m_RemoteBranch
.GetString();
387 // only store URL in history if it's value was used
388 m_Other
.SaveHistory();
391 m_RemoteReg
= m_Remote
.GetString();
393 m_RemoteBranch
.SaveHistory();
394 this->m_regRebase
=this->m_bRebase
;
395 m_regFFonly
= m_bFFonly
;
397 m_regAutoLoadPutty
= m_bAutoLoad
;
402 void CPullFetchDlg::OnStnClickedRemoteManage()
404 CAppUtils::LaunchRemoteSetting();
408 void CPullFetchDlg::OnBnClickedButtonBrowseRef()
411 initialRef
.Format(L
"refs/remotes/%s/%s", m_Remote
.GetString(), m_RemoteBranch
.GetString());
412 CString selectedRef
= CBrowseRefsDlg::PickRef(false, initialRef
, gPickRef_Remote
);
413 if(selectedRef
.Left(13) != "refs/remotes/")
416 selectedRef
= selectedRef
.Mid(13);
417 int ixSlash
= selectedRef
.Find('/');
419 CString remoteName
= selectedRef
.Left(ixSlash
);
420 CString remoteBranch
= selectedRef
.Mid(ixSlash
+ 1);
422 int ixFound
= m_Remote
.FindStringExact(0, remoteName
);
424 m_Remote
.SetCurSel(ixFound
);
425 m_RemoteBranch
.AddString(remoteBranch
, 0);
427 CheckRadioButton(IDC_REMOTE_RD
,IDC_OTHER_RD
,IDC_REMOTE_RD
);
430 void CPullFetchDlg::OnBnClickedCheckDepth()
433 GetDlgItem(IDC_EDIT_DEPTH
)->EnableWindow(m_bDepth
);
436 void CPullFetchDlg::OnBnClickedCheckFetchtags()
438 if (CAppUtils::GetMsysgitVersion() < 0x01090000)
441 if (m_bFetchTags
== TRUE
)
447 void CPullFetchDlg::OnBnClickedCheckFfonly()
453 GetDlgItem(IDC_CHECK_FFONLY
)->EnableWindow(FALSE
);
457 GetDlgItem(IDC_CHECK_FFONLY
)->EnableWindow(TRUE
);
462 GetDlgItem(IDC_CHECK_NOFF
)->EnableWindow(FALSE
);
466 GetDlgItem(IDC_CHECK_NOFF
)->EnableWindow(TRUE
);