Пример #1
0
void test_config_read__foreach_match(void)
{
	git_config *cfg;
	int count;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, "core.*", count_cfg_entries, &count));
	cl_assert_equal_i(3, count);

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, "remote\\.ab.*", count_cfg_entries, &count));
	cl_assert_equal_i(2, count);

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, ".*url$", count_cfg_entries, &count));
	cl_assert_equal_i(2, count);

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, ".*dummy.*", count_cfg_entries, &count));
	cl_assert_equal_i(2, count);

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, ".*nomatch.*", count_cfg_entries, &count));
	cl_assert_equal_i(0, count);

	git_config_free(cfg);
}
Пример #2
0
void test_submodule_modify__init(void)
{
	git_config *cfg;
	const char *str;

	/* erase submodule data from .git/config */
	cl_git_pass(git_repository_config(&cfg, g_repo));
	cl_git_pass(
		git_config_foreach_match(cfg, "submodule\\..*", delete_one_config, cfg));
	git_config_free(cfg);

	/* confirm no submodule data in config */
	cl_git_pass(git_repository_config(&cfg, g_repo));
	cl_git_fail(git_config_get_string(&str, cfg, "submodule.sm_unchanged.url"));
	cl_git_fail(git_config_get_string(&str, cfg, "submodule.sm_changed_head.url"));
	cl_git_fail(git_config_get_string(&str, cfg, "submodule.sm_added_and_uncommited.url"));
	git_config_free(cfg);

	/* call init and see that settings are copied */
	cl_git_pass(git_submodule_foreach(g_repo, init_one_submodule, NULL));

	git_submodule_reload_all(g_repo);

	/* confirm submodule data in config */
	cl_git_pass(git_repository_config(&cfg, g_repo));
	cl_git_pass(git_config_get_string(&str, cfg, "submodule.sm_unchanged.url"));
	cl_assert(git__suffixcmp(str, "/submod2_target") == 0);
	cl_git_pass(git_config_get_string(&str, cfg, "submodule.sm_changed_head.url"));
	cl_assert(git__suffixcmp(str, "/submod2_target") == 0);
	cl_git_pass(git_config_get_string(&str, cfg, "submodule.sm_added_and_uncommited.url"));
	cl_assert(git__suffixcmp(str, "/submod2_target") == 0);
	git_config_free(cfg);
}
static int DeleteOtherKeys(int type)
{
	CString match;
	if (type == SimpleCredentialType::LocalWincred)
		match = _T("L\ncredential.helper\nwincred");
	else if (type == SimpleCredentialType::LocalWinstore)
		match = _T("L\ncredential.helper\n") + GetWinstorePath();
	else if (type == SimpleCredentialType::GlobalWincred)
		match = _T("G\ncredential.helper\nwincred");
	else if (type == SimpleCredentialType::GlobalWinstore)
		match = _T("G\ncredential.helper\n") + GetWinstorePath();
	else if (type == SimpleCredentialType::SystemWincred)
		match = _T("S\ncredential.helper\nwincred");

	CAutoConfig config(true);
	git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitLocalConfig()), GIT_CONFIG_LEVEL_LOCAL, FALSE);
	git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitGlobalConfig()), GIT_CONFIG_LEVEL_GLOBAL, FALSE);
	git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitGlobalXDGConfig()), GIT_CONFIG_LEVEL_XDG, FALSE);
	git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitSystemConfig()), GIT_CONFIG_LEVEL_SYSTEM, FALSE);

	STRING_VECTOR list;
	git_config_foreach_match(config, "credential\\..*", GetCredentialAnyEntryCallback, &list);
	for (size_t i = 0; i < list.size(); ++i)
	{
		int pos = 0;
		CString prefix = list[i].Tokenize(_T("\n"), pos);
		if (prefix == _T("S") && !CAppUtils::IsAdminLogin())
		{
			RunUAC();
			return -1;
		}
	}

	int result = 0;
	// workaround gitdll bug
	// TODO: switch to libgit2
	bool old = g_Git.m_IsUseGitDLL;
	g_Git.m_IsUseGitDLL = false;
	for (size_t i = 0; i < list.size(); ++i)
	{
		if (list[i] != match)
		{
			int pos = 0;
			CString prefix = list[i].Tokenize(_T("\n"), pos);
			CString key = list[i].Tokenize(_T("\n"), pos);
			CONFIG_TYPE configLevel = prefix == _T("S") ? CONFIG_SYSTEM : prefix == _T("G") || prefix == _T("X") ? CONFIG_GLOBAL : CONFIG_LOCAL;
			if (g_Git.UnsetConfigValue(key, configLevel))
			{
				CString msg;
				msg.Format(IDS_PROC_SAVECONFIGFAILED, key, _T(""));
				CMessageBox::Show(NULL, msg, _T("TortoiseGit"), MB_OK | MB_ICONERROR);
				result = 1;
				break;
			}
		}
	}
	g_Git.m_IsUseGitDLL = old;

	return result;
}
Пример #4
0
void CSettingGitCredential::OnBnClickedButtonRemove()
{
	int index = m_ctrlUrlList.GetCurSel();
	if (index >= 0)
	{
		CString str;
		m_ctrlUrlList.GetText(index, str);
		CString msg;
		msg.Format(IDS_WARN_REMOVE, (LPCTSTR)str);
		if (CMessageBox::Show(GetSafeHwnd(), msg, L"TortoiseGit", MB_YESNO | MB_ICONQUESTION) == IDYES)
		{
			CAutoConfig config(true);
			int pos = str.Find(L':');
			CString prefix = pos >= 0 ? str.Left(pos) : str;
			CString url = pos >= 0 ? str.Mid(pos + 1) : L"";
			CONFIG_TYPE configLevel = CONFIG_LOCAL;
			switch (prefix[0])
			{
			case L'L':
				{
				configLevel = CONFIG_LOCAL;
				git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitLocalConfig()), GIT_CONFIG_LEVEL_LOCAL, FALSE);
				break;
				}
			case L'G':
			case L'X':
				{
				configLevel = CONFIG_GLOBAL;
				git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitGlobalConfig()), GIT_CONFIG_LEVEL_GLOBAL, FALSE);
				git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitGlobalXDGConfig()), GIT_CONFIG_LEVEL_XDG, FALSE);
				break;
				}
			case L'P':
			case L'S':
				{
				if (!CAppUtils::IsAdminLogin())
				{
					RunUAC();
					EndDialog(0);
					return;
				}
				configLevel = CONFIG_SYSTEM;
				git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitSystemConfig()), GIT_CONFIG_LEVEL_SYSTEM, FALSE);
				if (!g_Git.ms_bCygwinGit && !g_Git.ms_bMsys2Git)
					git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitProgramDataConfig()), GIT_CONFIG_LEVEL_PROGRAMDATA, FALSE);
				break;
				}
			}

			STRING_VECTOR list;
			CStringA urlA = CUnicodeUtils::GetUTF8(url);
			CStringA pattern = urlA.IsEmpty() ? "^credential\\.[^.]+$" : ("credential\\." + RegexEscape(urlA) + "\\..*");
			git_config_foreach_match(config, pattern, GetCredentialEntryCallback, &list);
			for (size_t i = 0; i < list.size(); ++i)
				g_Git.UnsetConfigValue(list[i], configLevel);
			m_ctrlUrlList.DeleteString(index);
			OnLbnSelchangeListUrl();
		}
	}
}
Пример #5
0
int CTGitPath::GetAdminDirMask() const
{
	int status = 0;
	CString topdir;
	if (!GitAdminDir::HasAdminDir(GetWinPathString(), &topdir))
	{
		return status;
	}

	// ITEMIS_INGIT will be revoked if necessary in TortoiseShell/ContextMenu.cpp
	status |= ITEMIS_INGIT|ITEMIS_INVERSIONEDFOLDER;

	if (IsDirectory())
	{
		status |= ITEMIS_FOLDERINGIT;
		if (IsWCRoot())
		{
			status |= ITEMIS_WCROOT;

			CString topProjectDir;
			if (GitAdminDir::HasAdminDir(GetWinPathString(), false, &topProjectDir))
			{
				if (PathFileExists(topProjectDir + _T("\\.gitmodules")))
				{
					CAutoConfig config(true);
					git_config_add_file_ondisk(config, CGit::GetGitPathStringA(topProjectDir + _T("\\.gitmodules")), GIT_CONFIG_LEVEL_APP, FALSE);
					CString relativePath = GetWinPathString().Mid(topProjectDir.GetLength());
					relativePath.Replace(_T("\\"), _T("/"));
					relativePath.Trim(_T("/"));
					CStringA submodulePath = CUnicodeUtils::GetUTF8(relativePath);
					if (git_config_foreach_match(config, "submodule\\..*\\.path", 
						[](const git_config_entry *entry, void *data) { return entry->value == *(CStringA *)data ? GIT_EUSER : 0; }, &submodulePath) == GIT_EUSER)
						status |= ITEMIS_SUBMODULE;
				}
			}
		}
	}

	CString dotGitPath;
	GitAdminDir::GetAdminDirPath(topdir, dotGitPath);

	if (PathFileExists(dotGitPath + _T("BISECT_START")))
		status |= ITEMIS_BISECT;

	if (PathFileExists(dotGitPath + _T("MERGE_HEAD")))
		status |= ITEMIS_MERGEACTIVE;

	if (PathFileExists(dotGitPath + _T("refs\\stash")))
		status |= ITEMIS_STASH;

	if (PathFileExists(dotGitPath + _T("svn")))
		status |= ITEMIS_GITSVN;

	if (PathFileExists(topdir + _T("\\.gitmodules")))
		status |= ITEMIS_SUBMODULECONTAINER;

	return status;
}
Пример #6
0
MAP_STRING_STRING GetBranchDescriptions()
{
	MAP_STRING_STRING descriptions;
	git_config * config;
	git_config_new(&config);
	git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitLocalConfig()), GIT_CONFIG_LEVEL_LOCAL, FALSE);
	git_config_foreach_match(config, "branch\\..*\\.description", GetBranchDescriptionsCallback, &descriptions);
	git_config_free(config);
	return descriptions;
}
Пример #7
0
MAP_STRING_STRING GetBranchDescriptions()
{
	MAP_STRING_STRING descriptions;
	git_config * config;
	git_config_new(&config);
	CStringA projectConfigA = CUnicodeUtils::GetMulti(g_Git.GetGitLocalConfig(), CP_UTF8);
	git_config_add_file_ondisk(config, projectConfigA.GetBuffer(), 3);
	projectConfigA.ReleaseBuffer();
	git_config_foreach_match(config, "branch\\..*\\.description", GetBranchDescriptionsCallback, &descriptions);
	git_config_free(config);
	return descriptions;
}
Пример #8
0
bool CSettingGitRemote::IsRemoteCollideWithRefspec(CString remote)
{
	CheckRefspecStruct crs = { CUnicodeUtils::GetUTF8(remote), false };
	CAutoConfig config(true);
	git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitLocalConfig()), GIT_CONFIG_LEVEL_LOCAL, g_Git.GetGitRepository(), FALSE);
	for (const auto pattern : { "remote\\..*\\.fetch", "svn-remote\\..*\\.fetch", "svn-remote\\..*\\.branches", "svn-remote\\..*\\.tags" })
	{
		git_config_foreach_match(config, pattern, CheckRemoteCollideWithRefspec, &crs);
		if (crs.result)
			return true;
	}
	return false;
}
void CSettingGitCredential::OnBnClickedButtonRemove()
{
	int index = m_ctrlUrlList.GetCurSel();
	if (index >= 0)
	{
		CString str;
		m_ctrlUrlList.GetText(index, str);
		CString msg;
		msg.Format(IDS_GITCREDENTIAL_DELETEHELPER, str);
		if (CMessageBox::Show(NULL, msg, _T("TortoiseGit"), MB_YESNO | MB_ICONQUESTION) == IDYES)
		{
			git_config * config;
			git_config_new(&config);
			int pos = str.Find(_T(':'));
			CString prefix = pos >= 0 ? str.Left(pos) : str;
			CString url = pos >= 0 ? str.Mid(pos + 1) : _T("");
			CONFIG_TYPE configLevel = CONFIG_LOCAL;
			switch (prefix[0])
			{
			case _T('L'):
				{
				configLevel = CONFIG_LOCAL;
				CStringA projectConfigA = CUnicodeUtils::GetUTF8(g_Git.GetGitLocalConfig());
				git_config_add_file_ondisk(config, projectConfigA.GetBuffer(), GIT_CONFIG_LEVEL_LOCAL, FALSE);
				projectConfigA.ReleaseBuffer();
				break;
				}
			case _T('G'):
			case _T('X'):
				{
				configLevel = CONFIG_GLOBAL;
				CStringA globalConfigA = CUnicodeUtils::GetUTF8(g_Git.GetGitGlobalConfig());
				git_config_add_file_ondisk(config, globalConfigA.GetBuffer(), GIT_CONFIG_LEVEL_GLOBAL, FALSE);
				globalConfigA.ReleaseBuffer();
				CStringA globalXDGConfigA = CUnicodeUtils::GetUTF8(g_Git.GetGitGlobalXDGConfig());
				git_config_add_file_ondisk(config, globalXDGConfigA.GetBuffer(), GIT_CONFIG_LEVEL_XDG, FALSE);
				globalXDGConfigA.ReleaseBuffer();
				break;
				}
			case _T('S'):
				{
				if (!CAppUtils::IsAdminLogin())
				{
					RunUAC();
					git_config_free(config);
					EndDialog(0);
					return;
				}
				configLevel = CONFIG_SYSTEM;
				CStringA systemConfigA = CUnicodeUtils::GetUTF8(g_Git.GetGitSystemConfig());
				git_config_add_file_ondisk(config, systemConfigA.GetBuffer(), GIT_CONFIG_LEVEL_SYSTEM, FALSE);
				systemConfigA.ReleaseBuffer();
				break;
				}
			}

			STRING_VECTOR list;
			CStringA urlA = CUnicodeUtils::GetUTF8(url);
			CStringA pattern = urlA.IsEmpty() ? "^credential\\.[^.]+$" : ("credential\\." + RegexEscape(urlA) + "\\..*");
			git_config_foreach_match(config, pattern, GetCredentialEntryCallback, &list);
			git_config_free(config);
			for (size_t i = 0; i < list.size(); ++i)
				g_Git.UnsetConfigValue(list[i], configLevel, CP_UTF8);
			m_ctrlUrlList.DeleteString(index);
			OnLbnSelchangeListUrl();
		}
	}
}
void CSettingGitCredential::LoadList()
{
	git_config * config;
	git_config_new(&config);
	CStringA projectConfigA = CUnicodeUtils::GetUTF8(g_Git.GetGitLocalConfig());
	git_config_add_file_ondisk(config, projectConfigA.GetBuffer(), GIT_CONFIG_LEVEL_LOCAL, FALSE);
	projectConfigA.ReleaseBuffer();
	CStringA globalConfigA = CUnicodeUtils::GetUTF8(g_Git.GetGitGlobalConfig());
	git_config_add_file_ondisk(config, globalConfigA.GetBuffer(), GIT_CONFIG_LEVEL_GLOBAL, FALSE);
	globalConfigA.ReleaseBuffer();
	CStringA globalXDGConfigA = CUnicodeUtils::GetUTF8(g_Git.GetGitGlobalXDGConfig());
	git_config_add_file_ondisk(config, globalXDGConfigA.GetBuffer(), GIT_CONFIG_LEVEL_XDG, FALSE);
	globalXDGConfigA.ReleaseBuffer();
	CStringA systemConfigA = CUnicodeUtils::GetUTF8(g_Git.GetGitSystemConfig());
	git_config_add_file_ondisk(config, systemConfigA.GetBuffer(), GIT_CONFIG_LEVEL_SYSTEM, FALSE);
	systemConfigA.ReleaseBuffer();

	STRING_VECTOR defaultList, urlList;
	git_config_foreach_match(config, "credential\\.helper", GetCredentialDefaultUrlCallback, &defaultList);
	git_config_foreach_match(config, "credential\\..*\\.helper", GetCredentialUrlCallback, &urlList);
	STRING_VECTOR anyList;
	git_config_foreach_match(config, "credential\\..*", GetCredentialAnyEntryCallback, &anyList);
	git_config_free(config);

	for (int i = 0; i < defaultList.size(); ++i)
		m_ctrlUrlList.AddString(defaultList[i]);
	for (int i = 0; i < urlList.size(); ++i)
		m_ctrlUrlList.AddString(urlList[i]);

	if (anyList.empty())
	{
		m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::None);
		return;
	}
	if (anyList.size() > 1)
	{
		m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::Advanced);
		return;
	}

	int pos = 0;
	CString prefix = anyList[0].Tokenize(_T("\n"), pos);
	CString key = anyList[0].Tokenize(_T("\n"), pos);
	CString value = anyList[0].Tokenize(_T("\n"), pos);
	if (key != _T("credential.helper"))
	{
		m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::Advanced);
		return;
	}

	CString winstore = GetWinstorePath();
	if (prefix == _T("L"))
	{
		if (value == _T("wincred"))
		{
			m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::LocalWincred);
			return;
		}
		else if (value == winstore)
		{
			m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::LocalWinstore);
			return;
		}
	}

	if (prefix == _T("G") || prefix == _T("X"))
	{
		if (value == _T("wincred"))
		{
			m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::GlobalWincred);
			return;
		}
		else if (value == winstore)
		{
			m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::GlobalWinstore);
			return;
		}
	}

	if (prefix == _T("S"))
	{
		if (value == _T("wincred"))
		{
			m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::SystemWincred);
			return;
		}
	}

	m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::Advanced);
}
BOOL CFirstStartWizardAuthentication::OnInitDialog()
{
	CFirstStartWizardBasePage::OnInitDialog();

	CString tmp;
	tmp.LoadString(IDS_FIRSTSTART_SSHHINT);
	GetDlgItem(IDC_FIRSTSTART_SSHHINT)->SetWindowText(tmp);

	CAutoConfig config(true);
	if (git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitGlobalConfig()), GIT_CONFIG_LEVEL_GLOBAL, nullptr, FALSE))
		MessageBox(g_Git.GetLibGit2LastErr(), L"TortoiseGit", MB_ICONEXCLAMATION);
	else
	{
		if (git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitGlobalXDGConfig()), GIT_CONFIG_LEVEL_XDG, nullptr, FALSE))
			MessageBox(g_Git.GetLibGit2LastErr(), L"TortoiseGit", MB_ICONEXCLAMATION);
	}
	if (!g_Git.ms_bCygwinGit && !g_Git.ms_bMsys2Git)
	{
		if (git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitProgramDataConfig()), GIT_CONFIG_LEVEL_PROGRAMDATA, nullptr, FALSE))
			MessageBox(g_Git.GetLibGit2LastErr(), L"TortoiseGit", MB_ICONEXCLAMATION);
	}
	if (git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitSystemConfig()), GIT_CONFIG_LEVEL_SYSTEM, nullptr, FALSE))
		MessageBox(g_Git.GetLibGit2LastErr(), L"TortoiseGit", MB_ICONEXCLAMATION);

	STRING_VECTOR defaultList;
	git_config_foreach_match(config, "credential\\.helper", CSettingGitCredential::GetCredentialDefaultUrlCallback, &defaultList);

	if (defaultList.size() <= 1 && (defaultList.empty() || defaultList.at(0)[0] == 'X' || defaultList.at(0)[0] == 'G'))
		AddHelper(m_ctrlSimpleCredential, m_availableHelpers, MAKEINTRESOURCE(IDS_NONE));
	CString selectedHelper;
	if (config.GetString(L"credential.helper", selectedHelper) == GIT_ENOTFOUND)
		m_ctrlSimpleCredential.SetCurSel(0);

	if (CSettingGitCredential::GCMExists())
		AddHelper(m_ctrlSimpleCredential, m_availableHelpers, L"manager", selectedHelper);
	if (CSettingGitCredential::WincredExists())
		AddHelper(m_ctrlSimpleCredential, m_availableHelpers, L"wincred", selectedHelper);
	if (CSettingGitCredential::WinstoreExists())
		AddHelper(m_ctrlSimpleCredential, m_availableHelpers, CSettingGitCredential::GetWinstorePath(), selectedHelper);

	STRING_VECTOR urlList;
	git_config_foreach_match(config, "credential\\..*\\.helper", CSettingGitCredential::GetCredentialUrlCallback, &urlList);
	if (!urlList.empty() || m_ctrlSimpleCredential.GetCurSel() == -1)
	{
		m_ctrlSimpleCredential.EnableWindow(FALSE);
		m_availableHelpers.clear();
		m_ctrlSimpleCredential.Clear();
		AddHelper(m_ctrlSimpleCredential, m_availableHelpers, MAKEINTRESOURCE(IDS_ADVANCED));
		m_ctrlSimpleCredential.SetCurSel(0);
	}

	AdjustControlSize(IDC_DONTSAVE);

	CString sshclient = CRegString(L"Software\\TortoiseGit\\SSH");
	if (sshclient.IsEmpty())
		sshclient = CRegString(L"Software\\TortoiseGit\\SSH", L"", FALSE, HKEY_LOCAL_MACHINE);

	int idx = m_ctrlSSHClient.AddString(L"TortoiseGitPlink");
	if (sshclient.IsEmpty() || IsTool(L"tortoisegitplink", sshclient) || IsTool(L"tortoiseplink", sshclient))
		m_ctrlSSHClient.SetCurSel(idx);
	idx = m_ctrlSSHClient.AddString(L"OpenSSH");
	if (IsTool(L"ssh", sshclient))
		m_ctrlSSHClient.SetCurSel(idx);
	if (m_ctrlSSHClient.GetCurSel() == -1)
	{
		idx = m_ctrlSSHClient.AddString(sshclient);
		m_ctrlSSHClient.SetCurSel(idx);
	}

	// TODO: Hide the button if PuTTY is not used?
	//GetDlgItem(IDC_GENERATEPUTTYKEY)->ShowWindow(CAppUtils::IsSSHPutty() ? SW_SHOW : SW_HIDE);

	UpdateData(FALSE);

	return TRUE;
}
Пример #12
0
void CSettingGitCredential::LoadList()
{
	CAutoConfig config(true);
	git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitLocalConfig()), GIT_CONFIG_LEVEL_LOCAL, FALSE);
	git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitGlobalConfig()), GIT_CONFIG_LEVEL_GLOBAL, FALSE);
	git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitGlobalXDGConfig()), GIT_CONFIG_LEVEL_XDG, FALSE);
	git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitSystemConfig()), GIT_CONFIG_LEVEL_SYSTEM, FALSE);
	if (!g_Git.ms_bCygwinGit && !g_Git.ms_bMsys2Git)
		git_config_add_file_ondisk(config, CGit::GetGitPathStringA(g_Git.GetGitProgramDataConfig()), GIT_CONFIG_LEVEL_PROGRAMDATA, FALSE);

	STRING_VECTOR defaultList, urlList;
	git_config_foreach_match(config, "credential\\.helper", GetCredentialDefaultUrlCallback, &defaultList);
	git_config_foreach_match(config, "credential\\..*\\.helper", GetCredentialUrlCallback, &urlList);
	STRING_VECTOR anyList;
	git_config_foreach_match(config, "credential\\..*", GetCredentialAnyEntryCallback, &anyList);

	for (size_t i = 0; i < defaultList.size(); ++i)
		m_ctrlUrlList.AddString(defaultList[i]);
	for (size_t i = 0; i < urlList.size(); ++i)
		m_ctrlUrlList.AddString(urlList[i]);

	if (anyList.empty())
	{
		m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::None);
		return;
	}
	if (anyList.size() > 1)
	{
		m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::Advanced);
		return;
	}

	int pos = 0;
	CString prefix = anyList[0].Tokenize(L"\n", pos);
	CString key = anyList[0].Tokenize(L"\n", pos);
	CString value = anyList[0].Tokenize(L"\n", pos);
	if (key != L"credential.helper")
	{
		m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::Advanced);
		return;
	}

	CString winstore = GetWinstorePath();
	if (prefix == L"L")
	{
		if (value == L"wincred")
		{
			m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::LocalWincred);
			return;
		}
		else if (value == winstore)
		{
			m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::LocalWinstore);
			return;
		}
		else if (value == L"manager")
		{
			m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::LocalGCM);
			return;
		}
	}

	if (prefix == L"G" || prefix == L"X")
	{
		if (value == L"wincred")
		{
			m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::GlobalWincred);
			return;
		}
		else if (value == winstore)
		{
			m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::GlobalWinstore);
			return;
		}
		else if (value == L"manager")
		{
			m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::GlobalGCM);
			return;
		}
	}

	if (prefix == L"S" || prefix == L"P")
	{
		if (value == L"wincred")
		{
			m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::SystemWincred);
			return;
		}
		else if (value == L"manager")
		{
			m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::SystemGCM);
			return;
		}
	}

	m_ctrlSimpleCredential.SetCurSel(SimpleCredentialType::Advanced);
}