Exemple #1
0
int CGit::GetRemoteList(STRING_VECTOR &list)
{
	if (this->m_IsUseLibGit2)
	{
		git_repository *repo = NULL;

		CStringA gitdir = CUnicodeUtils::GetMulti(CTGitPath(m_CurrentDir).GetGitPathString(), CP_UTF8);
		if (git_repository_open(&repo, gitdir.GetBuffer()))
		{
			gitdir.ReleaseBuffer();
			return -1;
		}
		gitdir.ReleaseBuffer();

		git_strarray remotes;

		if (git_remote_list(&remotes, repo))
		{
			git_repository_free(repo);
			return -1;
		}

		for (size_t i = 0; i < remotes.count; i++)
		{
			CStringA remote(remotes.strings[i]);
			list.push_back(CUnicodeUtils::GetUnicode(remote));
		}

		git_strarray_free(&remotes);

		git_repository_free(repo);

		std::sort(list.begin(), list.end());

		return 0;
	}
	else
	{
		int ret;
		CString cmd, output;
		cmd=_T("git.exe remote");
		ret = Run(cmd, &output, NULL, CP_UTF8);
		if(!ret)
		{
			int pos=0;
			CString one;
			while( pos>=0 )
			{
				one=output.Tokenize(_T("\n"),pos);
				if (!one.IsEmpty())
					list.push_back(one);
			}
		}
		return ret;
	}
}
Exemple #2
0
int CGit::GetBranchList(STRING_VECTOR &list,int *current,BRANCH_TYPE type)
{
	int ret;
	CString cmd, output, cur;
	cmd = _T("git.exe branch --no-color");

	if((type&BRANCH_ALL) == BRANCH_ALL)
		cmd += _T(" -a");
	else if(type&BRANCH_REMOTE)
		cmd += _T(" -r");

	ret = Run(cmd, &output, NULL, CP_UTF8);
	if(!ret)
	{
		int pos=0;
		CString one;
		while( pos>=0 )
		{
			one=output.Tokenize(_T("\n"),pos);
			one.Trim(L" \r\n\t");
			if(one.Find(L" -> ") >= 0 || one.IsEmpty())
				continue; // skip something like: refs/origin/HEAD -> refs/origin/master
			if(one[0] == _T('*'))
			{
				one = one.Mid(2);
				cur = one;
			}
			if (one != _T("(no branch)"))
				list.push_back(one);
		}
	}

	if(type & BRANCH_FETCH_HEAD && !DerefFetchHead().IsEmpty())
		list.push_back(L"FETCH_HEAD");

	std::sort(list.begin(), list.end(), LogicalComparePredicate);

	if (current && cur != _T("(no branch)"))
	{
		for (unsigned int i = 0; i < list.size(); i++)
		{
			if (list[i] == cur)
			{
				*current = i;
				break;
			}
		}
	}

	return ret;
}
Exemple #3
0
int CGit::GetRefList(STRING_VECTOR &list)
{
	int ret;
	if(this->m_IsUseGitDLL)
	{
		CAutoLocker lock(g_Git.m_critGitDllSec);
		ret = git_for_each_ref_in("",addto_list_each_ref_fn, &list);
		std::sort(list.begin(), list.end(), LogicalComparePredicate);
	}
	else
	{
		CString cmd, output;
		cmd=_T("git.exe show-ref -d");
		ret = Run(cmd, &output, NULL, CP_UTF8);
		if(!ret)
		{
			int pos=0;
			CString one;
			while( pos>=0 )
			{
				one=output.Tokenize(_T("\n"),pos);
				int start=one.Find(_T(" "),0);
				if(start>0)
				{
					CString name;
					name=one.Right(one.GetLength()-start-1);
					list.push_back(name);
				}
			}
			std::sort(list.begin(), list.end(), LogicalComparePredicate);
		}
	}
	return ret;
}
Exemple #4
0
void CRefLogDlg::Refresh()
{
	STRING_VECTOR list;
	list.push_back(_T("HEAD"));
	if (g_Git.GetRefList(list))
		MessageBox(g_Git.GetGitLastErr(_T("Could not get all refs.")), _T("TortoiseGit"), MB_ICONERROR);

	m_ChooseRef.SetList(list);

	if (m_CurrentBranch.IsEmpty())
	{
		m_CurrentBranch.Format(_T("refs/heads/%s"), (LPCTSTR)g_Git.GetCurrentBranch());
		m_ChooseRef.SetCurSel(0); /* Choose HEAD */
	}
	else
	{
		bool found = false;
		for (int i = 0; i < (int)list.size(); ++i)
		{
			if(list[i] == m_CurrentBranch)
			{
				m_ChooseRef.SetCurSel(i);
				found = true;
				break;
			}
		}
		if (!found)
			m_ChooseRef.SetCurSel(0);
	}

	m_RefList.m_RevCache.clear();

	OnCbnSelchangeRef();
}
static void AddHelper(CComboBox& combobox, STRING_VECTOR& availableHelpers, const CString& helper, const CString& selected = L"")
{
	availableHelpers.push_back(helper);
	int idx = combobox.AddString(helper);
	if (selected == helper)
		combobox.SetCurSel(idx);
}
void CDeleteRemoteTagDlg::OnBnClickedOk()
{
	if (m_ctrlTags.GetSelectedCount() > 1)
	{
		CString msg;
		msg.Format(IDS_PROC_DELETENREFS, m_ctrlTags.GetSelectedCount());
		if (CMessageBox::Show(m_hWnd, msg, _T("TortoiseGit"), 2, IDI_QUESTION, CString(MAKEINTRESOURCE(IDS_DELETEBUTTON)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON))) == 2)
			return;
	}
	else // GetSelectedCount() is 1, otherwise the button is disabled
	{
		POSITION pos = m_ctrlTags.GetFirstSelectedItemPosition();
		CString msg;
		msg.Format(IDS_PROC_DELETEBRANCHTAG, (LPCTSTR)m_taglist[(m_ctrlTags.GetNextSelectedItem(pos))]);
		if (CMessageBox::Show(m_hWnd, msg, _T("TortoiseGit"), 2, IDI_QUESTION, CString(MAKEINTRESOURCE(IDS_DELETEBUTTON)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON))) == 2)
			return;
	}

	STRING_VECTOR list;
	POSITION pos = m_ctrlTags.GetFirstSelectedItemPosition();
	int index;
	while ((index = m_ctrlTags.GetNextSelectedItem(pos)) >= 0)
		list.push_back(_T("refs/tags/") + m_taglist[index]);
	CSysProgressDlg sysProgressDlg;
	sysProgressDlg.SetTitle(CString(MAKEINTRESOURCE(IDS_APPNAME)));
	sysProgressDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_DELETING_REMOTE_REFS)));
	sysProgressDlg.SetLine(2, CString(MAKEINTRESOURCE(IDS_PROGRESSWAIT)));
	sysProgressDlg.SetShowProgressBar(false);
	sysProgressDlg.ShowModal(this, true);
	if (g_Git.DeleteRemoteRefs(m_sRemote, list))
		CMessageBox::Show(m_hWnd, g_Git.GetGitLastErr(_T("Could not delete remote ref."), CGit::GIT_CMD_PUSH), _T("TortoiseGit"), MB_OK | MB_ICONERROR);
	sysProgressDlg.Stop();
	BringWindowToTop();
	Refresh();
}
Exemple #7
0
int CGit::GetRemoteList(STRING_VECTOR &list)
{
	int ret;
	CString cmd,output;
	cmd=_T("git.exe config  --get-regexp remote.*.url");
	ret=g_Git.Run(cmd,&output,CP_UTF8);
	if(!ret)
	{
		int pos=0;
		CString one;
		while( pos>=0 )
		{
			one=output.Tokenize(_T("\n"),pos);
			int start=one.Find(_T("."),0);
			if(start>0)
			{
				CString url;
				url=one.Right(one.GetLength()-start-1);
				one=url;
				one=one.Left(one.Find(_T("."),0));
				list.push_back(one);
			}
		}
	}
	return ret;
}
Exemple #8
0
int CGit::GetBranchList(STRING_VECTOR &list,int *current,BRANCH_TYPE type)
{
	int ret;
	CString cmd,output;
	cmd=_T("git.exe branch");

	if(type==(BRANCH_LOCAL|BRANCH_REMOTE))
		cmd+=_T(" -a");
	else if(type==BRANCH_REMOTE)
		cmd+=_T(" -r");

	int i=0;
	ret=g_Git.Run(cmd,&output,CP_UTF8);
	if(!ret)
	{		
		int pos=0;
		CString one;
		while( pos>=0 )
		{
			one=output.Tokenize(_T("\n"),pos);
			list.push_back(one.Right(one.GetLength()-2));
			if(one[0] == _T('*'))
				if(current)
					*current=i;
			i++;
		}
	}
	return ret;
}
void CSubmoduleUpdateDlg::Refresh()
{
	while (m_PathListBox.GetCount() > 0)
		m_PathListBox.DeleteString(m_PathListBox.GetCount() - 1);

	CString WorkingDir = g_Git.m_CurrentDir;
	WorkingDir.Replace(_T(':'), _T('_'));

	m_regPath = CRegString(CString(_T("Software\\TortoiseGit\\History\\SubmoduleUpdatePath\\") + WorkingDir));
	CString path = m_regPath;
	STRING_VECTOR emptylist;
	STRING_VECTOR list;
	GetSubmodulePathList(list, m_bWholeProject ? emptylist : m_PathFilterList);
	STRING_VECTOR selected;
	if (m_PathList.empty())
	{
		int pos = 0;
		while (pos >= 0)
		{
			CString part = path.Tokenize(_T("|"), pos);
			if (!part.IsEmpty())
				selected.push_back(part);
		}
	}
	else
	{
		for (size_t i = 0; i < m_PathList.size(); ++i)
			selected.push_back(m_PathList[i]);
	}

	for (size_t i = 0; i < list.size(); ++i)
	{
		m_PathListBox.AddString(list[i]);
		if (selected.size() == 0)
			m_PathListBox.SetSel((int)i);
		else
		{
			for (size_t j = 0; j < selected.size(); ++j)
			{
				if (selected[j] == list[i])
					m_PathListBox.SetSel((int)i);
			}
		}
	}

	OnLbnSelchangeListPath();
}
Exemple #10
0
int addto_list_each_ref_fn(const char *refname, const unsigned char * /*sha1*/, int /*flags*/, void *cb_data)
{
	STRING_VECTOR *list = (STRING_VECTOR*)cb_data;
	CString str;
	g_Git.StringAppend(&str, (BYTE*)refname, CP_UTF8);
	list->push_back(str);
	return 0;
}
Exemple #11
0
void CPushDlg::Refresh()
{
	CString WorkingDir=g_Git.m_CurrentDir;
	WorkingDir.Replace(_T(':'),_T('_'));

	CRegString remote(CString(_T("Software\\TortoiseGit\\History\\PushRemote\\")+WorkingDir));
	m_RemoteReg = remote;
	int sel = -1;

	STRING_VECTOR list;
	m_Remote.Reset();

	list.push_back(CString(MAKEINTRESOURCE(IDS_PROC_PUSHFETCH_ALLREMOTES)));
	if(!g_Git.GetRemoteList(list))
	{
		if (list.size() <= 2)
			list.erase(list.begin());

		for (unsigned int i = 0; i < list.size(); ++i)
		{
			m_Remote.AddString(list[i]);
			if(list[i] == remote)
				sel = i;
		}
	}
	// if the last selected remote was "- All -" and "- All -" is still in the list -> select it
	if (list.size() > 1 && remote == CString(MAKEINTRESOURCE(IDS_PROC_PUSHFETCH_ALLREMOTES)))
		sel = 0;
	m_Remote.SetCurSel(sel);

	int current=0;
	list.clear();
	m_BranchSource.Reset();
	m_BranchSource.AddString(_T(" ")); // empty string does not work, for removal of remote branches/tags
	m_BranchSource.SetMaxHistoryItems(0x7FFFFFFF);
	if(!g_Git.GetBranchList(list,&current))
	{
		for (unsigned int i = 0; i < list.size(); ++i)
			m_BranchSource.AddString(list[i]);
		++current; // shift for " "
	}
	if (wcsncmp(m_BranchSourceName, _T("refs/"), 5) == 0)
		m_BranchSourceName = m_BranchSourceName.Mid(5);
	if (wcsncmp(m_BranchSourceName, _T("heads/"), 6) == 0)
	{
		m_BranchSourceName = m_BranchSourceName.Mid(6);
		m_BranchSource.SetCurSel(m_BranchSource.FindStringExact(-1, m_BranchSourceName));
	}
	else if (wcsncmp(m_BranchSourceName, _T("remotes/"), 8) == 0)
		m_BranchSource.SetCurSel(m_BranchSource.FindStringExact(-1, m_BranchSourceName));
	else
		m_BranchSource.SetCurSel(current);

	GetRemoteBranch(m_BranchSource.GetString());

	this->GetDlgItem(IDOK)->EnableWindow(m_BranchSource.GetCount() != 0);
}
static int SubmoduleCallback(git_submodule *sm, const char * /*name*/, void *payload)
{
	STRING_VECTOR *list = *(STRING_VECTOR **)payload;
	STRING_VECTOR *prefixList = *((STRING_VECTOR **)payload + 1);
	CString path = CUnicodeUtils::GetUnicode(git_submodule_path(sm));
	if (prefixList->empty())
		list->push_back(path);
	else
	{
		for (size_t i = 0; i < prefixList->size(); ++i)
		{
			CString prefix = prefixList->at(i) + L'/';
			if (CStringUtils::StartsWith(path, prefix))
				list->push_back(path);
		}
	}
	return 0;
}
bool CBrowseRefsDlg::DoDeleteRef(CString completeRefName)
{
	bool bIsRemoteBranch = false;
	bool bIsBranch = false;
	if		(wcsncmp(completeRefName, L"refs/remotes/",13) == 0)	{bIsBranch = true; bIsRemoteBranch = true;}
	else if	(wcsncmp(completeRefName, L"refs/heads/",11) == 0)		{bIsBranch = true;}

	if (bIsRemoteBranch)
	{
		CString branchToDelete = completeRefName.Mid(13);
		CString remoteName, remoteBranchToDelete;
		if (SplitRemoteBranchName(branchToDelete, remoteName, remoteBranchToDelete))
			return false;

		if (CAppUtils::IsSSHPutty())
			CAppUtils::LaunchPAgent(NULL, &remoteName);

		CSysProgressDlg sysProgressDlg;
		sysProgressDlg.SetTitle(CString(MAKEINTRESOURCE(IDS_APPNAME)));
		sysProgressDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_DELETING_REMOTE_REFS)));
		sysProgressDlg.SetLine(2, CString(MAKEINTRESOURCE(IDS_PROGRESSWAIT)));
		sysProgressDlg.SetShowProgressBar(false);
		sysProgressDlg.ShowModal(this, true);

		STRING_VECTOR list;
		list.push_back(_T("refs/heads/") + remoteBranchToDelete);
		if (g_Git.DeleteRemoteRefs(remoteName, list))
		{
			CMessageBox::Show(m_hWnd, g_Git.GetGitLastErr(_T("Could not delete remote ref."), CGit::GIT_CMD_PUSH), _T("TortoiseGit"), MB_OK | MB_ICONERROR);
			sysProgressDlg.Stop();
			BringWindowToTop();
			return false;
		}
		sysProgressDlg.Stop();
		BringWindowToTop();
	}
	else if (bIsBranch)
	{
		if (g_Git.DeleteRef(completeRefName))
		{
			CMessageBox::Show(m_hWnd, g_Git.GetGitLastErr(L"Could not delete reference.", CGit::GIT_CMD_DELETETAGBRANCH), _T("TortoiseGit"), MB_OK | MB_ICONERROR);
			return false;
		}
	}
	else if (wcsncmp(completeRefName, L"refs/tags/", 10) == 0)
	{
		if (g_Git.DeleteRef(completeRefName))
		{
			CMessageBox::Show(m_hWnd, g_Git.GetGitLastErr(L"Could not delete reference.", CGit::GIT_CMD_DELETETAGBRANCH), _T("TortoiseGit"), MB_OK | MB_ICONERROR);
			return false;
		}
	}
	return true;
}
static int SubmoduleCallback(git_submodule *sm, const char * /*name*/, void *payload)
{
	STRING_VECTOR *list = *(STRING_VECTOR **)payload;
	STRING_VECTOR *prefixList = *((STRING_VECTOR **)payload + 1);
	CString path = CUnicodeUtils::GetUnicode(git_submodule_path(sm));
	if (prefixList->empty())
	{
		list->push_back(path);
	}
	else
	{
		for (size_t i = 0; i < prefixList->size(); ++i)
		{
			CString prefix = prefixList->at(i) + _T("/");
			if (path.Left(prefix.GetLength()) == prefix)
				list->push_back(path);
		}
	}
	return 0;
}
static void uniqueMergeLists(STRING_VECTOR& list, const STRING_VECTOR& listToMerge)
{
	std::map<CString, int> map;
	for (CString entry : list)
		map[entry] = 1;

	for (CString entry : listToMerge)
	{
		if (map.find(entry) == map.end())
			list.push_back(entry);
	}
}
Exemple #16
0
BOOL CRefLogDlg::OnInitDialog()
{
	CResizableStandAloneDialog::OnInitDialog();
	CAppUtils::MarkWindowAsUnpinnable(m_hWnd);

	AddAnchor(IDOK,BOTTOM_RIGHT);
	AddAnchor(IDCANCEL,BOTTOM_RIGHT);

	AddAnchor(IDC_REFLOG_LIST,TOP_LEFT,BOTTOM_RIGHT);
	AddAnchor(IDHELP, BOTTOM_RIGHT);

	AddOthersToAnchor();
	this->EnableSaveRestore(_T("RefLogDlg"));

	CString sWindowTitle;
	GetWindowText(sWindowTitle);
	CAppUtils::SetWindowTitle(m_hWnd, g_Git.m_CurrentDir, sWindowTitle);

	STRING_VECTOR list;
	list.push_back(_T("HEAD"));
	g_Git.GetRefList(list);

	m_RefList.m_hasWC = !g_GitAdminDir.IsBareRepo(g_Git.m_CurrentDir);

	m_ChooseRef.SetMaxHistoryItems(0x7FFFFFFF);
	this->m_ChooseRef.AddString(list);

	this->m_RefList.InsertRefLogColumn();
	//m_RefList.m_logEntries.ParserFromRefLog(_T("master"));
	if(this->m_CurrentBranch.IsEmpty())
	{
		m_CurrentBranch.Format(_T("refs/heads/%s"),g_Git.GetCurrentBranch());
		m_ChooseRef.SetCurSel(0); /* Choose HEAD */
	}
	else
	{
		for(int i=0;i<list.size();i++)
		{
			if(list[i] == m_CurrentBranch)
			{
				m_ChooseRef.SetCurSel(i);
				break;
			}
		}
	}


	OnCbnSelchangeRef();

	return TRUE;
}
Exemple #17
0
int CGit::GetTagList(STRING_VECTOR &list)
{
	int ret;
	CString cmd,output;
	cmd=_T("git.exe tag -l");
	int i=0;
	ret=g_Git.Run(cmd,&output,CP_UTF8);
	if(!ret)
	{		
		int pos=0;
		CString one;
		while( pos>=0 )
		{
			i++;
			one=output.Tokenize(_T("\n"),pos);
			list.push_back(one);
		}
	}
	return ret;
}
Exemple #18
0
void CPullFetchDlg::Refresh()
{
	//Select pull-remote from current branch
	CString currentBranch = g_Git.GetSymbolicRef();
	CString configName;
	configName.Format(L"branch.%s.remote", currentBranch);
	CString pullRemote = this->m_configPullRemote = g_Git.GetConfigValue(configName);

	//Select pull-branch from current branch
	configName.Format(L"branch.%s.merge", currentBranch);
	CString pullBranch = m_configPullBranch = CGit::StripRefName(g_Git.GetConfigValue(configName));
	if (pullBranch.IsEmpty())
		m_RemoteBranch.AddString(currentBranch);
	else
		m_RemoteBranch.AddString(pullBranch);

	if(pullRemote.IsEmpty())
		pullRemote = m_RemoteReg;

	if (!m_PreSelectRemote.IsEmpty())
		pullRemote = m_PreSelectRemote;

	STRING_VECTOR list;
	int sel=0;
	if (!m_IsPull)
		list.push_back(_T("- all -"));
	if(!g_Git.GetRemoteList(list))
	{
		if (!m_IsPull && list.size() <= 2)
			list.erase(list.begin());

		for (unsigned int i = 0; i < list.size(); ++i)
		{
			m_Remote.AddString(list[i]);
			if (!m_bAllRemotes && list[i] == pullRemote)
				sel = i;
		}
	}
	m_Remote.SetCurSel(sel);
	OnCbnSelchangeRemote();
}
Exemple #19
0
int CGit::GetRemoteTags(CString remote, STRING_VECTOR &list)
{
	CString cmd, out, err;
	cmd.Format(_T("git.exe ls-remote -t \"%s\""), remote);
	if (Run(cmd, &out, &err, CP_UTF8))
	{
		MessageBox(NULL, err, _T("TortoiseGit"), MB_ICONERROR);
		return -1;
	}

	int pos = 0;
	while (pos >= 0)
	{
		CString one = out.Tokenize(_T("\n"), pos).Mid(51).Trim(); // sha1, tab + refs/tags/
		// dot not include annotated tags twice; this works, because an annotated tag appears twice (one normal tag and one with ^{} at the end)
		if (one.Find(_T("^{}")) >= 1)
			continue;
		if (!one.IsEmpty())
			list.push_back(one);
	}
	std::sort(list.begin(), list.end(), LogicalComparePredicate);
	return 0;
}
bool SubmoduleUpdateCommand::Execute()
{
	CString bkpath;
	if (parser.HasKey(_T("bkpath")))
		bkpath = parser.GetVal(_T("bkpath"));
	else
	{
		bkpath = this->orgPathList[0].GetWinPathString();
		int start = bkpath.ReverseFind(_T('\\'));
		if (start >= 0)
			bkpath = bkpath.Left(start);
	}

	CString super = GitAdminDir::GetSuperProjectRoot(bkpath);
	if (super.IsEmpty())
	{
		CMessageBox::Show(NULL,IDS_ERR_NOTFOUND_SUPER_PRJECT,IDS_APPNAME,MB_OK|MB_ICONERROR);
		//change current project root to super project
		return false;
	}

	STRING_VECTOR pathFilterList;
	for (int i = 0; i < orgPathList.GetCount(); i++)
	{
		if (orgPathList[i].IsDirectory())
		{
			CString path = ((CTGitPath &)orgPathList[i]).GetSubPath(CTGitPath(super)).GetGitPathString();
			if (!path.IsEmpty())
				pathFilterList.push_back(path);
		}
	}

	CSubmoduleUpdateDlg submoduleUpdateDlg;
	submoduleUpdateDlg.m_PathFilterList = pathFilterList;
	if (parser.HasKey(_T("selectedpath")))
	{
		CString selectedPath = parser.GetVal(_T("selectedpath"));
		selectedPath.Replace(_T('\\'), _T('/'));
		submoduleUpdateDlg.m_PathList.push_back(selectedPath);
	}
	if (submoduleUpdateDlg.DoModal() != IDOK)
		return false;

	CProgressDlg progress;

	g_Git.m_CurrentDir = super;

	CString params;
	if (submoduleUpdateDlg.m_bInit)
		params = _T(" --init");
	if (submoduleUpdateDlg.m_bRecursive)
		params += _T(" --recursive");
	if (submoduleUpdateDlg.m_bForce)
		params += _T(" --force");
	if (submoduleUpdateDlg.m_bNoFetch)
		params += _T(" --no-fetch");
	if (submoduleUpdateDlg.m_bMerge)
		params += _T(" --merge");
	if (submoduleUpdateDlg.m_bRebase)
		params += _T(" --rebase");
	if (submoduleUpdateDlg.m_bRemote)
		params += _T(" --remote");

	for (size_t i = 0; i < submoduleUpdateDlg.m_PathList.size(); ++i)
	{
		CString str;
		str.Format(_T("git.exe submodule update%s -- \"%s\""), (LPCTSTR)params, (LPCTSTR)submoduleUpdateDlg.m_PathList[i]);
		progress.m_GitCmdList.push_back(str);
	}

	progress.DoModal();

	return !progress.m_GitStatus;
}
int CGitLogList::DeleteRef(const CString& ref)
{
	CString shortname;
	if (CGit::GetShortName(ref, shortname, _T("refs/remotes/")))
	{
		CString msg;
		msg.Format(IDS_PROC_DELETEREMOTEBRANCH, (LPCTSTR)ref);
		int result = CMessageBox::Show(nullptr, msg, _T("TortoiseGit"), 3, IDI_QUESTION, CString(MAKEINTRESOURCE(IDS_PROC_DELETEREMOTEBRANCH_LOCALREMOTE)), CString(MAKEINTRESOURCE(IDS_PROC_DELETEREMOTEBRANCH_LOCAL)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON)));
		if (result == 1)
		{
			CString remoteName = shortname.Left(shortname.Find(L'/'));
			shortname = shortname.Mid(shortname.Find(L'/') + 1);
			if (CAppUtils::IsSSHPutty())
				CAppUtils::LaunchPAgent(nullptr, &remoteName);

			CSysProgressDlg sysProgressDlg;
			sysProgressDlg.SetTitle(CString(MAKEINTRESOURCE(IDS_APPNAME)));
			sysProgressDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_DELETING_REMOTE_REFS)));
			sysProgressDlg.SetLine(2, CString(MAKEINTRESOURCE(IDS_PROGRESSWAIT)));
			sysProgressDlg.SetShowProgressBar(false);
			sysProgressDlg.ShowModal(this, true);
			STRING_VECTOR list;
			list.push_back(_T("refs/heads/") + shortname);
			if (g_Git.DeleteRemoteRefs(remoteName, list))
				CMessageBox::Show(nullptr, g_Git.GetGitLastErr(_T("Could not delete remote ref."), CGit::GIT_CMD_PUSH), _T("TortoiseGit"), MB_OK | MB_ICONERROR);
			sysProgressDlg.Stop();
			return TRUE;
		}
		else if (result == 2)
		{
			if (g_Git.DeleteRef(ref))
			{
				CMessageBox::Show(nullptr, g_Git.GetGitLastErr(L"Could not delete reference.", CGit::GIT_CMD_DELETETAGBRANCH), _T("TortoiseGit"), MB_OK | MB_ICONERROR);
				return FALSE;
			}
			return TRUE;
		}
		return FALSE;
	}
	else if (CGit::GetShortName(ref, shortname, _T("refs/stash")))
	{
		CString err;
		std::vector<GitRevLoglist> stashList;
		size_t count = !GitRevLoglist::GetRefLog(ref, stashList, err) ? stashList.size() : 0;
		CString msg;
		msg.Format(IDS_PROC_DELETEALLSTASH, count);
		if (CMessageBox::Show(nullptr, msg, _T("TortoiseGit"), 2, IDI_QUESTION, CString(MAKEINTRESOURCE(IDS_DELETEBUTTON)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON))) == 1)
		{
			CString sCmd;
			sCmd.Format(_T("git.exe stash clear"));
			CString out;
			if (g_Git.Run(sCmd, &out, CP_UTF8))
				CMessageBox::Show(nullptr, out, _T("TortoiseGit"), MB_OK | MB_ICONERROR);
			return TRUE;
		}
		return FALSE;
	}

	CString msg;
	msg.Format(IDS_PROC_DELETEBRANCHTAG, (LPCTSTR)ref);
	if (CMessageBox::Show(nullptr, msg, _T("TortoiseGit"), 2, IDI_QUESTION, CString(MAKEINTRESOURCE(IDS_DELETEBUTTON)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON))) == 1)
	{
		if (g_Git.DeleteRef(ref))
		{
			CMessageBox::Show(nullptr, g_Git.GetGitLastErr(L"Could not delete reference.", CGit::GIT_CMD_DELETETAGBRANCH), _T("TortoiseGit"), MB_OK | MB_ICONERROR);
			return FALSE;
		}
		return TRUE;
	}
	return FALSE;
}