Exemple #1
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 #2
0
int CGit::GetTagList(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 tag_names;

		if (git_tag_list(&tag_names, repo))
		{
			git_repository_free(repo);
			return -1;
		}

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

		git_strarray_free(&tag_names);

		git_repository_free(repo);

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

		return 0;
	}
	else
	{
		CString cmd, output;
		cmd=_T("git.exe tag -l");
		int 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);
			}
			std::sort(list.begin(), list.end(), LogicalComparePredicate);
		}
		return ret;
	}
}
Exemple #3
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);
}
Exemple #4
0
void CSyncDlg::FetchComplete()
{
	EnableControlButton(true);
	SwitchToInput();
	this->FetchOutList(true);

	if (g_Git.UsingLibGit2(CGit::GIT_CMD_FETCH))
		ShowTab(IDC_CMD_GIT_PROG);
	else
		ShowTab(IDC_REFLIST);
	if( (!this->m_GitCmdStatus) && this->m_CurrentCmd == GIT_COMMAND_FETCHANDREBASE)
	{
		CRebaseDlg dlg;
		CString remote, remotebranch;
		m_ctrlURL.GetWindowText(remote);
		if (!remote.IsEmpty())
		{
			STRING_VECTOR remotes;
			g_Git.GetRemoteList(remotes);
			if (std::find(remotes.begin(), remotes.end(), remote) == remotes.end())
				remote.Empty();
		}
		m_ctrlRemoteBranch.GetWindowText(remotebranch);
		if (!remote.IsEmpty() && !remotebranch.IsEmpty())
			dlg.m_Upstream = _T("remotes/") + remote + _T("/") + remotebranch;
		dlg.m_PostButtonTexts.Add(CString(MAKEINTRESOURCE(IDS_MENULOG)));
		dlg.m_PostButtonTexts.Add(_T("Email &Patch..."));
		INT_PTR response = dlg.DoModal();
		if(response == IDOK)
		{
			return ;
		}

		if (response == IDC_REBASE_POST_BUTTON)
		{
			CString cmd = _T("/command:log");
			cmd += _T(" /path:\"") + g_Git.m_CurrentDir + _T("\"");
			CAppUtils::RunTortoiseGitProc(cmd);
		}
		if(response == IDC_REBASE_POST_BUTTON + 1)
		{
			CString cmd, out, err;
			cmd.Format(_T("git.exe format-patch -o \"%s\" %s..%s"),
					g_Git.m_CurrentDir,
					g_Git.FixBranchName(dlg.m_Upstream),
					g_Git.FixBranchName(dlg.m_Branch));
			if (g_Git.Run(cmd, &out, &err, CP_UTF8))
			{
				CMessageBox::Show(NULL, out + L"\n" + err, _T("TortoiseGit"), MB_OK|MB_ICONERROR);
				return ;
			}

			CAppUtils::SendPatchMail(cmd,out);
		}
	}
}
Exemple #5
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;
}
static void GetSubmodulePathList(STRING_VECTOR &list, STRING_VECTOR &prefixList)
{
	CAutoRepository repo(g_Git.GetGitRepository());
	if (!repo)
	{
		MessageBox(NULL, CGit::GetLibGit2LastErr(_T("Could not open repository.")), _T("TortoiseGit"), MB_ICONERROR);
		return;
	}

	STRING_VECTOR *listParams[] = { &list, &prefixList };
	if (git_submodule_foreach(repo, SubmoduleCallback, &listParams))
	{
		MessageBox(NULL, CGit::GetLibGit2LastErr(_T("Could not get submodule list.")), _T("TortoiseGit"), MB_ICONERROR);
		return;
	}

	std::sort(list.begin(), list.end(), LogicalComparePredicate);
}
static void GetSubmodulePathList(STRING_VECTOR &list, STRING_VECTOR &prefixList)
{
    git_repository *repo;
    if (git_repository_open(&repo, CUnicodeUtils::GetUTF8(g_Git.m_CurrentDir)))
    {
        MessageBox(NULL, CGit::GetLibGit2LastErr(_T("Could not open repository.")), _T("TortoiseGit"), MB_ICONERROR);
        return;
    }

    STRING_VECTOR *listParams[] = { &list, &prefixList };
    if (git_submodule_foreach(repo, SubmoduleCallback, &listParams))
    {
        MessageBox(NULL, CGit::GetLibGit2LastErr(_T("Could not get submodule list.")), _T("TortoiseGit"), MB_ICONERROR);
        return;
    }

    git_repository_free(repo);
    std::sort(list.begin(), list.end());
}
Exemple #8
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 #9
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;
}
Exemple #10
0
static bool DoCleanUp(const CTGitPathList& pathList, int cleanType, bool bDir, bool bSubmodules, bool bDryRun, bool bNoRecycleBin)
{
    CString cmd;
    cmd.Format(_T("git.exe clean"));
    if (bDryRun || !bNoRecycleBin)
        cmd += _T(" -n ");
    if (bDir)
        cmd += _T(" -d ");
    switch (cleanType)
    {
    case 0:
        cmd += _T(" -fx");
        break;
    case 1:
        cmd += _T(" -f");
        break;
    case 2:
        cmd += _T(" -fX");
        break;
    }

    STRING_VECTOR submoduleList;
    if (bSubmodules)
    {
        SubmodulePayload payload(submoduleList);
        payload.basePath = CTGitPath(g_Git.m_CurrentDir).GetGitPathString();
        if (pathList.GetCount() != 1 || pathList.GetCount() == 1 && !pathList[0].IsEmpty())
        {
            for (int i = 0; i < pathList.GetCount(); ++i)
            {
                CString path;
                if (pathList[i].IsDirectory())
                    payload.prefixList.push_back(pathList[i].GetGitPathString());
                else
                    payload.prefixList.push_back(pathList[i].GetContainingDirectory().GetGitPathString());
            }
        }
        if (!GetSubmodulePathList(payload))
            return false;
        std::sort(submoduleList.begin(), submoduleList.end());
    }

    if (bDryRun || bNoRecycleBin)
    {
        CProgressDlg progress;
        for (int i = 0; i < pathList.GetCount(); ++i)
        {
            CString path;
            if (pathList[i].IsDirectory())
                path = pathList[i].GetGitPathString();
            else
                path = pathList[i].GetContainingDirectory().GetGitPathString();

            progress.m_GitDirList.push_back(g_Git.m_CurrentDir);
            progress.m_GitCmdList.push_back(cmd + _T(" -- \"") + path + _T("\""));
        }

        for (CString dir : submoduleList)
        {
            progress.m_GitDirList.push_back(CTGitPath(dir).GetWinPathString());
            progress.m_GitCmdList.push_back(cmd);
        }

        progress.m_PostCmdCallback = [&](DWORD status, PostCmdList& postCmdList)
        {
            if (status)
                postCmdList.push_back(PostCmd(IDS_MSGBOX_RETRY, [&] { DoCleanUp(pathList, cleanType, bDir, bSubmodules, bDryRun, bNoRecycleBin); }));

            if (status || !bDryRun)
                return;

            if (bNoRecycleBin)
            {
                postCmdList.push_back(PostCmd(IDS_CLEAN_NO_RECYCLEBIN, [&] { DoCleanUp(pathList, cleanType, bDir, bSubmodules, FALSE, TRUE); }));
                postCmdList.push_back(PostCmd(IDS_CLEAN_TO_RECYCLEBIN, [&] { DoCleanUp(pathList, cleanType, bDir, bSubmodules, FALSE, FALSE); }));
            }
            else
            {
                postCmdList.push_back(PostCmd(IDS_CLEAN_TO_RECYCLEBIN, [&] { DoCleanUp(pathList, cleanType, bDir, bSubmodules, FALSE, FALSE); }));
                postCmdList.push_back(PostCmd(IDS_CLEAN_NO_RECYCLEBIN, [&] { DoCleanUp(pathList, cleanType, bDir, bSubmodules, FALSE, TRUE); }));
            }
        };

        INT_PTR result = progress.DoModal();
        return result == IDOK;
    }
    else
    {
        CSysProgressDlg sysProgressDlg;
        sysProgressDlg.SetAnimation(IDR_CLEANUPANI);
        sysProgressDlg.SetTitle(CString(MAKEINTRESOURCE(IDS_APPNAME)));
        sysProgressDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO1)));
        sysProgressDlg.SetLine(2, CString(MAKEINTRESOURCE(IDS_PROGRESSWAIT)));
        sysProgressDlg.SetShowProgressBar(false);
        sysProgressDlg.ShowModeless((HWND)NULL, true);

        bool quotepath = g_Git.GetConfigValueBool(_T("core.quotepath"));

        CTGitPathList delList;
        for (int i = 0; i < pathList.GetCount(); ++i)
        {
            CString path;
            if (pathList[i].IsDirectory())
                path = pathList[i].GetGitPathString();
            else
                path = pathList[i].GetContainingDirectory().GetGitPathString();

            if (!GetFilesToCleanUp(delList, cmd, &g_Git, path, quotepath, sysProgressDlg))
                return false;
        }

        for (CString dir : submoduleList)
        {
            CGit git;
            git.m_CurrentDir = dir;
            if (!GetFilesToCleanUp(delList, cmd, &git, _T(""), quotepath, sysProgressDlg))
                return false;
        }

        delList.DeleteAllFiles(true, false, true);

        sysProgressDlg.Stop();
    }

    return true;
}
bool CleanupCommand::Execute()
{
	bool bRet = false;

	CCleanTypeDlg dlg;
	if( dlg.DoModal() == IDOK)
	{
		bool quotepath = g_Git.GetConfigValueBool(_T("core.quotepath"));

		CString cmd;
		cmd.Format(_T("git.exe clean"));
		if (dlg.m_bDryRun || !dlg.m_bNoRecycleBin)
			cmd += _T(" -n ");
		if(dlg.m_bDir)
			cmd += _T(" -d ");
		switch(dlg.m_CleanType)
		{
		case 0:
			cmd += _T(" -fx");
			break;
		case 1:
			cmd += _T(" -f");
			break;
		case 2:
			cmd += _T(" -fX");
			break;
		}

		STRING_VECTOR submoduleList;
		SubmodulePayload payload(submoduleList);
		if (dlg.m_bSubmodules)
		{
			payload.basePath = CTGitPath(g_Git.m_CurrentDir).GetGitPathString();
			if (pathList.GetCount() != 1 || pathList.GetCount() == 1 && !pathList[0].IsEmpty())
			{
				for (int i = 0; i < pathList.GetCount(); ++i)
				{
					CString path;
					if (pathList[i].IsDirectory())
						payload.prefixList.push_back(pathList[i].GetGitPathString());
					else
						payload.prefixList.push_back(pathList[i].GetContainingDirectory().GetGitPathString());
				}
			}
			if (!GetSubmodulePathList(payload))
				return FALSE;
			std::sort(submoduleList.begin(), submoduleList.end());
		}

		if (dlg.m_bDryRun || dlg.m_bNoRecycleBin)
		{
			while (true)
			{
				CProgressDlg progress;
				for (int i = 0; i < this->pathList.GetCount(); ++i)
				{
					CString path;
					if (this->pathList[i].IsDirectory())
						path = pathList[i].GetGitPathString();
					else
						path = pathList[i].GetContainingDirectory().GetGitPathString();

					progress.m_GitDirList.push_back(g_Git.m_CurrentDir);
					progress.m_GitCmdList.push_back(cmd + _T(" \"") + path + _T("\""));
				}

				if (dlg.m_bSubmodules)
				{
					for (CString dir : submoduleList)
					{
						progress.m_GitDirList.push_back(CTGitPath(dir).GetWinPathString());
						progress.m_GitCmdList.push_back(cmd);
					}
				}

				INT_PTR idRetry = -1;
				if (!dlg.m_bDryRun)
					idRetry = progress.m_PostFailCmdList.Add(CString(MAKEINTRESOURCE(IDS_MSGBOX_RETRY)));
				INT_PTR result = progress.DoModal();
				if (result == IDOK)
					return TRUE;
				if (progress.m_GitStatus && result == IDC_PROGRESS_BUTTON1 + idRetry)
					continue;
				break;
			}
		}
		else
		{
			CSysProgressDlg sysProgressDlg;
			sysProgressDlg.SetAnimation(IDR_CLEANUPANI);
			sysProgressDlg.SetTitle(CString(MAKEINTRESOURCE(IDS_APPNAME)));
			sysProgressDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO1)));
			sysProgressDlg.SetLine(2, CString(MAKEINTRESOURCE(IDS_PROGRESSWAIT)));
			sysProgressDlg.SetShowProgressBar(false);
			sysProgressDlg.ShowModeless((HWND)NULL, true);

			CTGitPathList delList;
			for (size_t i = 0; i <= submoduleList.size(); ++i)
			{
				CGit git;
				CGit *pGit;
				if (i == 0)
					pGit = &g_Git;
				else
				{
					git.m_CurrentDir = submoduleList[i - 1];
					pGit = &git;
				}
				CString cmdout, cmdouterr;
				if (pGit->Run(cmd, &cmdout, &cmdouterr, CP_UTF8))
				{
					MessageBox(nullptr, cmdouterr, _T("TortoiseGit"), MB_ICONERROR);
					return FALSE;
				}

				if (sysProgressDlg.HasUserCancelled())
				{
					CMessageBox::Show(nullptr, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_OK);
					return FALSE;
				}

				int pos = 0;
				CString token = cmdout.Tokenize(_T("\n"), pos);
				while (!token.IsEmpty())
				{
					if (token.Mid(0, 13) == _T("Would remove "))
					{
						CString tempPath = token.Mid(13).TrimRight();
						if (quotepath)
						{
							tempPath = UnescapeQuotePath(tempPath.Trim(_T('"')));
						}
						if (i == 0)
							delList.AddPath(CTGitPath(tempPath));
						else
							delList.AddPath(CTGitPath(submoduleList[i - 1] + "/" + tempPath));
					}

					token = cmdout.Tokenize(_T("\n"), pos);
				}

				if (sysProgressDlg.HasUserCancelled())
				{
					CMessageBox::Show(nullptr, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_OK);
					return FALSE;
				}
			}

			delList.DeleteAllFiles(true, false);

			sysProgressDlg.Stop();
		}
	}
#if 0
	CProgressDlg progress;
	progress.SetTitle(IDS_PROC_CLEANUP);
	progress.SetAnimation(IDR_CLEANUPANI);
	progress.SetShowProgressBar(false);
	progress.SetLine(1, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO1)));
	progress.SetLine(2, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO2)));
	progress.ShowModeless(hwndExplorer);

	CString strSuccessfullPaths, strFailedPaths;
	for (int i=0; i<pathList.GetCount(); ++i)
	{
		SVN svn;
		if (!svn.CleanUp(pathList[i]))
		{
			strFailedPaths += _T("- ") + pathList[i].GetWinPathString() + _T("\n");
			strFailedPaths += svn.GetLastErrorMessage() + _T("\n\n");
		}
		else
		{
			strSuccessfullPaths += _T("- ") + pathList[i].GetWinPathString() + _T("\n");

			// after the cleanup has finished, crawl the path downwards and send a change
			// notification for every directory to the shell. This will update the
			// overlays in the left tree view of the explorer.
			CDirFileEnum crawler(pathList[i].GetWinPathString());
			CString sPath;
			bool bDir = false;
			CTSVNPathList updateList;
			while (crawler.NextFile(sPath, &bDir))
			{
				if ((bDir) && (!g_SVNAdminDir.IsAdminDirPath(sPath)))
				{
					updateList.AddPath(CTSVNPath(sPath));
				}
			}
			updateList.AddPath(pathList[i]);
			CShellUpdater::Instance().AddPathsForUpdate(updateList);
			CShellUpdater::Instance().Flush();
			updateList.SortByPathname(true);
			for (INT_PTR i=0; i<updateList.GetCount(); ++i)
			{
				SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, updateList[i].GetWinPath(), NULL);
				CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": notify change for path %s\n"), updateList[i].GetWinPath());
			}
		}
	}
	progress.Stop();

	CString strMessage;
	if ( !strSuccessfullPaths.IsEmpty() )
	{
		CString tmp;
		tmp.Format(IDS_PROC_CLEANUPFINISHED, (LPCTSTR)strSuccessfullPaths);
		strMessage += tmp;
		bRet = true;
	}
	if ( !strFailedPaths.IsEmpty() )
	{
		if (!strMessage.IsEmpty())
			strMessage += _T("\n");
		CString tmp;
		tmp.Format(IDS_PROC_CLEANUPFINISHED_FAILED, (LPCTSTR)strFailedPaths);
		strMessage += tmp;
		bRet = false;
	}
	CMessageBox::Show(hwndExplorer, strMessage, _T("TortoiseGit"), MB_OK | (strFailedPaths.IsEmpty()?MB_ICONINFORMATION:MB_ICONERROR));
#endif
	CShellUpdater::Instance().Flush();
	return bRet;
}
GenericRoutingTable::ROUTING_TABLE	GenericRoutingTable::detail::getRoutingTableFile (string filename, ROUTING_TEXT_FORMAT format)
{
	ROUTING_TABLE ret;

	//
	// read the contents of the file
	//

	ifstream file (filename.c_str());
	assert (file.is_open());

	string content = "";

	while (! file.eof ()) {	
		char item;
		file.read (&item, 1);
		if (! file.eof())
			content += item;
	}

	//
	// get the individual lines of the routing table
	//

	typedef vector<string>			STRING_VECTOR;
	typedef STRING_VECTOR::iterator STRING_VECTOR_ITERATOR;
	STRING_VECTOR lines;

	boost::split (lines, content, boost::is_any_of ("\n"));

	STRING_VECTOR_ITERATOR i	= lines.begin ();
	STRING_VECTOR_ITERATOR iend = lines.end	  ();

	for ( ; i != iend; i++) {
	
		string line = *i;
		boost::trim (line);

		IP_ADDR addr, mask;

		//
		// parse the content of each line
		//

		if (format == ROUTING_TEXT_FORMAT_SIMPLE) {

			STRING_VECTOR items;
			boost::split (items, line, boost::is_any_of ("/"));
			if (items.size() != 2) continue;

			addr.fromString (items[0]);
			
			int bits = Helper::stoi (items[1]);
			if (! (bits >= 0 && bits <= 32)) continue;

			IP_ADDR tempMask;
			for (int i=0; i<bits; i++) {					
				unsigned char byte = i / 8;
				tempMask.x[byte] |= (0x1 << (8 - 1 - (i % 8))); 
			}

			mask = tempMask;

		} else if (format == ROUTING_TEXT_FORMAT_DETAILED) {

			typedef enum _PROC_NET_ROUTE_FIELDS {
				PROC_NET_ROUTE_FIELDS_ADDR = 1,
				PROC_NET_ROUTE_FIELDS_MASK = 7,
			} PROC_NET_ROUTE_FIELDS;

			STRING_VECTOR items;
			boost::split (items, line, boost::is_any_of ("\t"));
			if (items.size() < (PROC_NET_ROUTE_FIELDS_MASK+1)) continue;

			boost::trim (items[PROC_NET_ROUTE_FIELDS_ADDR]);
			boost::trim (items[PROC_NET_ROUTE_FIELDS_MASK]);

			if (! isValidDetailedAddress (items[PROC_NET_ROUTE_FIELDS_ADDR])) continue;
			if (! isValidDetailedAddress (items[PROC_NET_ROUTE_FIELDS_MASK])) continue;

			addr = IP_ADDR (Helper::hstoui(items[PROC_NET_ROUTE_FIELDS_ADDR]));
			mask = IP_ADDR (Helper::hstoui(items[PROC_NET_ROUTE_FIELDS_MASK]));

			// If default route 0.0.0.0/0 shouldn't be regarded uncomment the following 2 lines
			//if (addr == IP_ADDR (0)) 
			//	continue;

		} else
			assert (false);

		ret.push_back (ROUTING_ENTRY (addr, mask));

	} // for ( ; i != iend; i++)

	return ret;
}