1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2013 - 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.
21 #include "../TortoiseProc.h"
24 #include "../../Utils/UnicodeUtils.h"
34 , m_bIsBareRepo(false)
35 , m_bHonorProjectConfig(false)
44 bool m_bHonorProjectConfig
;
46 void InitGitSettings(ISettingsPropPage
*page
, bool honorProjectConfig
, CToolTips
* tooltips
)
48 m_bHonorProjectConfig
= honorProjectConfig
;
52 tooltips
->AddTool(IDC_RADIO_SETTINGS_LOCAL
, IDS_CONFIG_LOCAL_TT
);
53 if (page
->GetDlgItem(IDC_RADIO_SETTINGS_PROJECT
) != nullptr)
54 tooltips
->AddTool(IDC_RADIO_SETTINGS_PROJECT
, IDS_CONFIG_PROJECT_TT
);
55 tooltips
->AddTool(IDC_RADIO_SETTINGS_GLOBAL
, IDS_CONFIG_GLOBAL_TT
);
58 CString str
= g_Git
.m_CurrentDir
;
59 m_bIsBareRepo
= g_GitAdminDir
.IsBareRepo(str
);
61 if (g_GitAdminDir
.HasAdminDir(str
, &proj
) || m_bIsBareRepo
)
64 page
->GetWindowText(title
);
65 page
->SetWindowText(title
+ _T(" - ") + proj
);
66 page
->GetDlgItem(IDC_RADIO_SETTINGS_LOCAL
)->EnableWindow(TRUE
);
68 m_cSaveTo
.AddString(CString(MAKEINTRESOURCE(IDS_CONFIG_LOCAL
)));
70 if (page
->GetDlgItem(IDC_RADIO_SETTINGS_PROJECT
) != nullptr)
72 page
->GetDlgItem(IDC_RADIO_SETTINGS_PROJECT
)->EnableWindow(honorProjectConfig
);
73 if (honorProjectConfig
&& !m_bIsBareRepo
)
74 m_cSaveTo
.AddString(CString(MAKEINTRESOURCE(IDS_CONFIG_PROJECT
)));
80 page
->GetDlgItem(IDC_RADIO_SETTINGS_LOCAL
)->EnableWindow(FALSE
);
81 if (page
->GetDlgItem(IDC_RADIO_SETTINGS_PROJECT
) != nullptr)
82 page
->GetDlgItem(IDC_RADIO_SETTINGS_PROJECT
)->EnableWindow(FALSE
);
84 m_cSaveTo
.AddString(CString(MAKEINTRESOURCE(IDS_CONFIG_GLOBAL
)));
85 m_cSaveTo
.SetCurSel(0);
87 page
->CheckRadioButton(IDC_RADIO_SETTINGS_EFFECTIVE
, IDC_RADIO_SETTINGS_SYSTEM
, IDC_RADIO_SETTINGS_EFFECTIVE
+ m_iConfigSource
);
92 bool Save(git_config
* config
, const CString
&key
, const CString
&value
, const bool askEmptyDelete
= false, const CString def
= _T(""))
94 CStringA keyA
= CUnicodeUtils::GetUTF8(key
);
96 if (value
.IsEmpty() || value
== def
)
98 const git_config_entry
* entry
= nullptr;
99 if (git_config_get_entry(&entry
, config
, keyA
) == GIT_ENOTFOUND
)
101 if (askEmptyDelete
&& CMessageBox::Show(nullptr, IDS_ASK_DELETE_EMPTY
, IDS_APPNAME
, 2, IDI_QUESTION
, IDS_DELETEBUTTON
, IDS_NO
) == 2)
103 err
= git_config_delete_entry(config
, keyA
);
107 CStringA valueA
= CUnicodeUtils::GetMulti(value
, CP_UTF8
);
108 err
= git_config_set_string(config
, keyA
, valueA
);
113 msg
.Format(IDS_PROC_SAVECONFIGFAILED
, key
, value
);
114 CMessageBox::Show(nullptr, g_Git
.GetLibGit2LastErr(msg
), _T("TortoiseGit"), MB_OK
| MB_ICONERROR
);
123 git_config_new(&config
);
124 if (!m_bGlobal
&& (m_iConfigSource
== 0 || m_iConfigSource
== 1))
126 if (git_config_add_file_ondisk(config
, CUnicodeUtils::GetUTF8(g_Git
.GetGitLocalConfig()), GIT_CONFIG_LEVEL_APP
, FALSE
)) // this needs to have the highest priority in order to override .tgitconfig settings
127 MessageBox(nullptr, g_Git
.GetLibGit2LastErr(), _T("TortoiseGit"), MB_ICONEXCLAMATION
);
129 if ((m_iConfigSource
== 0 && m_bHonorProjectConfig
) || m_iConfigSource
== 2)
133 if (git_config_add_file_ondisk(config
, CUnicodeUtils::GetUTF8(g_Git
.m_CurrentDir
) + "\\.tgitconfig", GIT_CONFIG_LEVEL_LOCAL
, FALSE
)) // this needs to have the second highest priority
134 MessageBox(nullptr, g_Git
.GetLibGit2LastErr(), _T("TortoiseGit"), MB_ICONEXCLAMATION
);
138 CString tmpFile
= GetTempFile();
139 CTGitPath
path(_T(".tgitconfig"));
140 if (g_Git
.GetOneFile(_T("HEAD"), path
, tmpFile
) == 0)
142 if (git_config_add_file_ondisk(config
, CUnicodeUtils::GetUTF8(tmpFile
), GIT_CONFIG_LEVEL_LOCAL
, FALSE
)) // this needs to have the second highest priority
143 MessageBox(nullptr, g_Git
.GetLibGit2LastErr(), _T("TortoiseGit"), MB_ICONEXCLAMATION
);
147 if (m_iConfigSource
== 0 || m_iConfigSource
== 3)
149 if (git_config_add_file_ondisk(config
, CUnicodeUtils::GetUTF8(g_Git
.GetGitGlobalConfig()), GIT_CONFIG_LEVEL_GLOBAL
, FALSE
))
150 MessageBox(nullptr, g_Git
.GetLibGit2LastErr(), _T("TortoiseGit"), MB_ICONEXCLAMATION
);
153 if (git_config_add_file_ondisk(config
, CUnicodeUtils::GetUTF8(g_Git
.GetGitGlobalXDGConfig()), GIT_CONFIG_LEVEL_XDG
, FALSE
))
154 MessageBox(nullptr, g_Git
.GetLibGit2LastErr(), _T("TortoiseGit"), MB_ICONEXCLAMATION
);
157 if (m_iConfigSource
== 0 || m_iConfigSource
== 4)
159 if (git_config_add_file_ondisk(config
, CUnicodeUtils::GetUTF8(g_Git
.GetGitSystemConfig()), GIT_CONFIG_LEVEL_SYSTEM
, FALSE
))
160 MessageBox(nullptr, g_Git
.GetLibGit2LastErr(), _T("TortoiseGit"), MB_ICONEXCLAMATION
);
163 LoadDataImpl(config
);
165 git_config_free(config
);
168 bool WarnUserSafeToDifferentDestination(int storeTo
)
170 if ((storeTo
== IDS_CONFIG_GLOBAL
&& m_iConfigSource
!= 3) || (storeTo
== IDS_CONFIG_PROJECT
&& m_iConfigSource
!= 2) || (storeTo
== IDS_CONFIG_LOCAL
&& m_iConfigSource
!= 1))
173 dest
.LoadString(storeTo
);
175 msg
.Format(IDS_WARNUSERSAFEDIFFERENT
, dest
);
176 if (CMessageBox::Show(nullptr, msg
, _T("TortoiseGit"), 2, IDI_QUESTION
, CString(MAKEINTRESOURCE(IDS_SAVEBUTTON
)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON
))) == 2)
185 git_config_new(&config
);
188 if (m_bGlobal
|| (m_cSaveTo
.GetCurSel() == 1 && (!m_bHonorProjectConfig
|| m_bIsBareRepo
)) || m_cSaveTo
.GetCurSel() == 2)
190 if (!WarnUserSafeToDifferentDestination(IDS_CONFIG_GLOBAL
))
192 if (PathIsDirectory(g_Git
.GetGitGlobalXDGConfigPath()))
193 err
= git_config_add_file_ondisk(config
, CUnicodeUtils::GetUTF8(g_Git
.GetGitGlobalXDGConfig()), GIT_CONFIG_LEVEL_XDG
, FALSE
);
195 err
= git_config_add_file_ondisk(config
, CUnicodeUtils::GetUTF8(g_Git
.GetGitGlobalConfig()), GIT_CONFIG_LEVEL_GLOBAL
, FALSE
);
197 else if (m_cSaveTo
.GetCurSel() == 1 && !m_bIsBareRepo
&& m_bHonorProjectConfig
)
199 if (!WarnUserSafeToDifferentDestination(IDS_CONFIG_PROJECT
))
201 err
= git_config_add_file_ondisk(config
, CUnicodeUtils::GetUTF8(g_Git
.m_CurrentDir
) + "\\.tgitconfig", GIT_CONFIG_LEVEL_APP
, FALSE
);
205 if (!WarnUserSafeToDifferentDestination(IDS_CONFIG_PROJECT
))
207 err
= git_config_add_file_ondisk(config
, CUnicodeUtils::GetMulti(g_Git
.GetGitLocalConfig(), CP_UTF8
), GIT_CONFIG_LEVEL_LOCAL
, FALSE
);
211 MessageBox(nullptr, g_Git
.GetLibGit2LastErr(), _T("TortoiseGit"), MB_ICONEXCLAMATION
);
215 int ret
= SafeDataImpl(config
);
217 git_config_free(config
);
222 virtual void LoadDataImpl(git_config
* config
) = 0;
223 virtual BOOL
SafeDataImpl(git_config
* config
) = 0;
225 static void AddTrueFalseToComboBox(CComboBox
&combobox
)
227 combobox
.AddString(_T(""));
228 combobox
.AddString(_T("true"));
229 combobox
.AddString(_T("false"));
232 static void GetBoolConfigValueComboBox(git_config
* config
, const CString
&key
, CComboBox
&combobox
)
234 CStringA keyA
= CUnicodeUtils::GetUTF8(key
);
236 if (git_config_get_bool(&out
, config
, keyA
) == GIT_ENOTFOUND
)
237 combobox
.SetCurSel(0);
239 combobox
.SetCurSel(1);
241 combobox
.SetCurSel(2);
244 static int GetConfigValue(git_config
* config
, const CString
&key
, CString
&value
)
246 CStringA keyA
= CUnicodeUtils::GetUTF8(key
);
247 const char *out
= nullptr;
248 int retval
= git_config_get_string(&out
, config
, keyA
);
249 value
= CUnicodeUtils::GetUnicode((CStringA
)out
);
254 #define GITSETTINGS_DDX \
255 DDX_Control(pDX, IDC_COMBO_SETTINGS_SAFETO, m_cSaveTo);
257 #define GITSETTINGS_RADIO_EVENT \
258 ON_CBN_SELCHANGE(IDC_COMBO_SETTINGS_SAFETO, &OnChange) \
259 ON_BN_CLICKED(IDC_RADIO_SETTINGS_EFFECTIVE, &OnBnClickedChangedConfigSource) \
260 ON_BN_CLICKED(IDC_RADIO_SETTINGS_LOCAL, &OnBnClickedChangedConfigSource) \
261 ON_BN_CLICKED(IDC_RADIO_SETTINGS_PROJECT, &OnBnClickedChangedConfigSource) \
262 ON_BN_CLICKED(IDC_RADIO_SETTINGS_GLOBAL, &OnBnClickedChangedConfigSource) \
263 ON_BN_CLICKED(IDC_RADIO_SETTINGS_SYSTEM, &OnBnClickedChangedConfigSource)
265 #define GITSETTINGS_RADIO_EVENT_HANDLE \
266 afx_msg void OnBnClickedChangedConfigSource() \
268 m_iConfigSource = GetCheckedRadioButton(IDC_RADIO_SETTINGS_EFFECTIVE, IDC_RADIO_SETTINGS_SYSTEM) - IDC_RADIO_SETTINGS_EFFECTIVE; \