예제 #1
0
void CSyncDlg::RunPostAction()
{
	if (m_bWantToExit)
		return;

	FillNewRefMap();

	if (this->m_CurrentCmd == GIT_COMMAND_PUSH)
	{
		if (!m_GitCmdStatus)
		{
			CTGitPathList list;
			list.AddPath(CTGitPath(g_Git.m_CurrentDir));
			DWORD exitcode;
			CString error;
			if (CHooks::Instance().PostPush(list,exitcode, error))
			{
				if (exitcode)
				{
					CString temp;
					temp.Format(IDS_ERR_HOOKFAILED, (LPCTSTR)error);
					//ReportError(temp);
					CMessageBox::Show(NULL,temp,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
					return;
				}
			}

		}
		EnableControlButton(true);
		SwitchToInput();
		this->FetchOutList(true);
	}
	else if (this->m_CurrentCmd == GIT_COMMAND_PULL)
	{
		PullComplete();
	}
	else if (this->m_CurrentCmd == GIT_COMMAND_FETCH || this->m_CurrentCmd == GIT_COMMAND_FETCHANDREBASE)
	{
		FetchComplete();
	}
	else if (this->m_CurrentCmd == GIT_COMMAND_SUBMODULE)
	{
		//this->m_ctrlCmdOut.SetSel(-1,-1);
		//this->m_ctrlCmdOut.ReplaceSel(_T("Done\r\n"));
		//this->m_ctrlCmdOut.SetSel(-1,-1);
		EnableControlButton(true);
		SwitchToInput();
	}
	else if (this->m_CurrentCmd == GIT_COMMAND_STASH)
	{
		StashComplete();
	}
	else if (this->m_CurrentCmd == GIT_COMMAND_REMOTE)
	{
		this->FetchOutList(true);
		EnableControlButton(true);
		SwitchToInput();
		ShowTab(IDC_REFLIST);
	}
}
예제 #2
0
bool CTGitPathList::IsEqual(const CTGitPathList& list)
{
	if (list.GetCount() != GetCount())
		return false;
	for (int i=0; i<list.GetCount(); ++i)
	{
		if (!list[i].IsEquivalentTo(m_paths[i]))
			return false;
	}
	return true;
}
예제 #3
0
void CRebaseDlg::ListConflictFile()
{
	this->m_FileListCtrl.Clear();
	CTGitPathList list;
	CTGitPath path;
	list.AddPath(path);

	m_FileListCtrl.m_bIsRevertTheirMy = !m_IsCherryPick;

	this->m_FileListCtrl.GetStatus(&list,true);
	this->m_FileListCtrl.Show(CTGitPath::LOGACTIONS_UNMERGED|CTGitPath::LOGACTIONS_MODIFIED|CTGitPath::LOGACTIONS_ADDED|CTGitPath::LOGACTIONS_DELETED,
							   CTGitPath::LOGACTIONS_UNMERGED);
}
예제 #4
0
int CGit::GetCommitDiffList(const CString &rev1,const CString &rev2,CTGitPathList &outputlist)
{
	CString cmd;

	if(rev1 == GIT_REV_ZERO || rev2 == GIT_REV_ZERO)
	{
		//rev1=+_T("");
		if(rev1 == GIT_REV_ZERO)
			cmd.Format(_T("git.exe diff -r --raw -C -M --numstat -z %s"),rev2);
		else
			cmd.Format(_T("git.exe diff -r -R --raw -C -M --numstat -z %s"),rev1);
	}
	else
	{
		cmd.Format(_T("git.exe diff-tree -r --raw -C -M --numstat -z %s %s"),rev2,rev1);
	}

	BYTE_VECTOR out;
	if (Run(cmd, &out))
		return -1;

	outputlist.ParserFromLog(out);

	return 0;
}
예제 #5
0
int CGit::GetInitAddList(CTGitPathList &outputlist)
{
	CString cmd;
	BYTE_VECTOR cmdout;

	cmd=_T("git.exe ls-files -s -t -z");
	outputlist.Clear();
	if (Run(cmd, &cmdout))
		return -1;

	outputlist.ParserFromLsFile(cmdout);
	for(int i=0;i<outputlist.GetCount();i++)
		((unsigned int)outputlist[i].m_Action) = CTGitPath::LOGACTIONS_ADDED;

	return 0;
}
예제 #6
0
int CSendMailPatch::SendAsCombinedMail(CTGitPathList &list, CGitProgressList * instance)
{
	ASSERT(instance);

	CStringArray attachments;
	CString body;
	for (int i = 0; i < list.GetCount(); ++i)
	{
		CPatch patch;
		if (patch.Parse((CString &)list[i].GetWinPathString()))
		{
			instance->ReportError(_T("Could not open/parse ") + list[i].GetWinPathString());
			return -2;
		}
		if (m_bAttachment)
		{
			attachments.Add(list[i].GetWinPathString());
			body += patch.m_Subject;
			body += _T("\r\n");
		}
		else
		{
			try
			{
				g_Git.StringAppend(&body, (BYTE*)patch.m_Body.GetBuffer(), CP_UTF8, patch.m_Body.GetLength());
			}
			catch (CMemoryException *)
			{
				instance->ReportError(_T("Out of memory. Could not parse ") + list[i].GetWinPathString());
				return -2;
			}
		}
	}
	return SendMail(CTGitPath(), instance, m_sSenderName, m_sSenderMail, m_sTo, m_sCC, m_sSubject, body, attachments);
}
예제 #7
0
hookiterator CHooks::FindItem(hooktype t, const CTGitPathList& pathList)
{
	hookkey key;
	for (int i=0; i<pathList.GetCount(); ++i)
	{
		CTGitPath path = pathList[i];
		do 
		{
			key.htype = t;
			key.path = path;
			hookiterator it = find(key);
			if (it != end())
			{
				return it;
			}
			path = path.GetContainingDirectory();
		} while(!path.IsEmpty());
	}
	// look for a script with a path as '*'
	key.htype = t;
	key.path = CTGitPath(_T("*"));
	hookiterator it = find(key);
	if (it != end())
	{
		return it;
	}

	return end();
}
예제 #8
0
int CSendMailCombineable::SendAsCombinedMail(const CTGitPathList &list, CGitProgressList* instance)
{
	ASSERT(instance);

	CStringArray attachments;
	CString body;
	for (int i = 0; i < list.GetCount(); ++i)
	{
		if (m_bAttachment)
		{
			attachments.Add(list[i].GetWinPathString());
		}
		else
		{
			CString filename(list[i].GetWinPathString());
			body += filename + _T(":\n");
			if (GetFileContents(filename, body))
			{
				instance->ReportError(_T("Could not open ") + filename);
				return -2;
			}
			body += _T("\n");
		}
	}
	return SendMail(CTGitPath(), instance, m_sSenderName, m_sSenderMail, m_sTo, m_sCC, m_sSubject, body, attachments);
}
예제 #9
0
/**
* Add a list of paths for updating.
* The update will happen when the list is destroyed, at the end of execution
*/
void CShellUpdater::AddPathsForUpdate(const CTGitPathList& pathList)
{
    for(int nPath=0; nPath < pathList.GetCount(); nPath++)
    {
        AddPathForUpdate(pathList[nPath]);
    }
}
예제 #10
0
int CRebaseDlg::VerifyNoConflict()
{
	CTGitPathList list;
	if(g_Git.ListConflictFile(list))
	{
		AddLogString(_T("Get conflict files fail"));
		return -1;
	}
	if( list.GetCount() != 0 )
	{
		CMessageBox::Show(NULL,_T("There are conflict file, you should mark it resolve"),_T("TortoiseGit"),MB_OK);
		return -1;
	}
	return 0;

}
예제 #11
0
int CGit::Revert(CString commit, CTGitPathList &list, bool)
{
	int ret;
	for(int i=0;i<list.GetCount();i++)
	{
		ret = Revert(commit, (CTGitPath&)list[i]);
		if(ret)
			return ret;
	}
	return 0;
}
예제 #12
0
bool CBugTraqAssociations::FindProviderForPathList(const CTGitPathList &pathList, CBugTraqAssociation *assoc) const
{
	for (int i = 0; i < pathList.GetCount(); ++i)
	{
		CTGitPath path = pathList[i];
		if (FindProviderForPath(path, assoc))
			return true;
	}

	return false;
}
BOOL ProjectProperties::ReadPropsPathList(const CTGitPathList& pathList)
{
	for(int nPath = 0; nPath < pathList.GetCount(); nPath++)
	{
		if (ReadProps(pathList[nPath]))
		{
			return TRUE;
		}
	}
	return FALSE;
}
예제 #14
0
bool CHooks::StartUpdate(const CTGitPathList& pathList, DWORD& exitcode, CString& error)
{
	hookiterator it = FindItem(start_update_hook, pathList);
	if (it == end())
		return false;
	CString sCmd = it->second.commandline;
	AddPathParam(sCmd, pathList);
	AddCWDParam(sCmd, pathList);
	exitcode = RunScript(sCmd, pathList.GetCommonRoot().GetDirectory().GetWinPath(), error, it->second.bWait, it->second.bShow);
	return true;
}
예제 #15
0
파일: Git.cpp 프로젝트: jrk/tortoisegit
int CGit::Revert(CTGitPathList &list,bool keep)
{
	int ret;
	for(int i=0;i<list.GetCount();i++)
	{	
		ret = Revert((CTGitPath&)list[i],keep);
		if(ret)
			return ret;
	}
	return 0;
}
예제 #16
0
int CSendMailCombineable::Send(const CTGitPathList& list, CGitProgressList* instance)
{
	if (m_bCombine)
	{
		return SendAsCombinedMail(list, instance);
	}
	else
	{
		instance->SetItemCountTotal(list.GetCount() + 1);
		for (int i = 0; i < list.GetCount(); ++i)
		{
			instance->SetItemProgress(i);
			if (SendAsSingleMail((CTGitPath&)list[i], instance))
				return -1;
		}
		instance->SetItemProgress(list.GetCount() + 1);
	}

	return 0;
}
예제 #17
0
bool CHooks::PreCommit(const CTGitPathList& pathList, git_depth_t depth, const CString& message, DWORD& exitcode, CString& error)
{
	hookiterator it = FindItem(pre_commit_hook, pathList);
	if (it == end())
		return false;
	CString sCmd = it->second.commandline;
	AddPathParam(sCmd, pathList);
	AddDepthParam(sCmd, depth);
	AddMessageFileParam(sCmd, message);
	AddCWDParam(sCmd, pathList);
	exitcode = RunScript(sCmd, pathList.GetCommonRoot().GetDirectory().GetWinPath(), error, it->second.bWait, it->second.bShow);
	return true;
}
예제 #18
0
bool CHooks::PreUpdate(const CTGitPathList& pathList, git_depth_t depth, GitRev rev, DWORD& exitcode, CString& error)
{
	hookiterator it = FindItem(pre_update_hook, pathList);
	if (it == end())
		return false;
	CString sCmd = it->second.commandline;
	AddPathParam(sCmd, pathList);
	AddDepthParam(sCmd, depth);
	AddParam(sCmd, rev.m_CommitHash.ToString());
	AddCWDParam(sCmd, pathList);
	exitcode = RunScript(sCmd, pathList.GetCommonRoot().GetDirectory().GetWinPath(), error, it->second.bWait, it->second.bShow);
	return true;
}
예제 #19
0
void CSyncDlg::StashComplete()
{
	EnableControlButton(true);
	INT_PTR entry = m_ctrlStash.GetCurrentEntry();
	if (entry != 1 && entry != 2)
		return;

	SwitchToInput();
	if (m_GitCmdStatus)
	{
		CTGitPathList list;
		if (g_Git.ListConflictFile(list))
		{
			m_ctrlCmdOut.SetSel(-1, -1);
			m_ctrlCmdOut.ReplaceSel(_T("Get conflict files fail\n"));

			ShowTab(IDC_CMD_LOG);
			return;
		}

		if (!list.IsEmpty())
		{
			m_ConflictFileList.Clear();
			CTGitPathList list;
			CTGitPath path;
			list.AddPath(path);

			m_ConflictFileList.GetStatus(&list,true);
			m_ConflictFileList.Show(CTGitPath::LOGACTIONS_UNMERGED, CTGitPath::LOGACTIONS_UNMERGED);

			ShowTab(IDC_IN_CONFLICT);
		}
		else
			ShowTab(IDC_CMD_LOG);
	}
}
예제 #20
0
bool CHooks::StartCommit(const CTGitPathList& pathList, CString& message, DWORD& exitcode, CString& error)
{
	hookiterator it = FindItem(start_commit_hook, pathList);
	if (it == end())
		return false;
	CString sCmd = it->second.commandline;
	AddPathParam(sCmd, pathList);
	CTGitPath temppath = AddMessageFileParam(sCmd, message);
	AddCWDParam(sCmd, pathList);
	exitcode = RunScript(sCmd, pathList.GetCommonRoot().GetDirectory().GetWinPath(), error, it->second.bWait, it->second.bShow);
	if (!exitcode && !temppath.IsEmpty())
	{
		CStringUtils::ReadStringFromTextFile(temppath.GetWinPathString(), message);
	}
	return true;
}
예제 #21
0
int CGit::ListConflictFile(CTGitPathList &list,CTGitPath *path)
{
	BYTE_VECTOR vector;

	CString cmd;
	if(path)
		cmd.Format(_T("git.exe ls-files -u -t -z -- \"%s\""),path->GetGitPathString());
	else
		cmd=_T("git.exe ls-files -u -t -z");

	if (Run(cmd, &vector))
	{
		return -1;
	}

	list.ParserFromLsFile(vector);

	return 0;
}
예제 #22
0
static bool GetFilesToCleanUp(CTGitPathList& delList, const CString& baseCmd, CGit *pGit, const CString& path, const boolean quotepath, CSysProgressDlg& sysProgressDlg)
{
    CString cmd(baseCmd);
    if (!path.IsEmpty())
        cmd += _T(" -- \"") + path + _T("\"");

    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_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('"')));
            delList.AddPath(pGit->CombinePath(tempPath));
        }

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

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

    return true;
}
예제 #23
0
int CPatch::SendPatchesCombined(CTGitPathList &list,CString &To,CString &CC, CString &subject,bool bAttachment, bool useMAPI,CString *errortext)
{
	CStringArray attachments;
	CString body;
	for (int i = 0; i < list.GetCount(); ++i)
	{
		CPatch patch;
		patch.Parser((CString&)list[i].GetWinPathString());
		if(bAttachment)
		{
			attachments.Add(list[i].GetWinPathString());
			body+=patch.m_Subject;
			body+=_T("\r\n");
		}
		else
		{
			g_Git.StringAppend(&body, (BYTE*)patch.m_Body.GetBuffer(), CP_UTF8, patch.m_Body.GetLength());
		}

	}
	return SendMail(To, CC, subject, body, attachments, useMAPI, errortext);
}
예제 #24
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;
}
예제 #25
0
int CRebaseDlg::DoRebase()
{
	CString cmd,out;
	if(m_CurrentRebaseIndex <0)
		return 0;
	if(m_CurrentRebaseIndex >= m_CommitList.GetItemCount() )
		return 0;

	GitRev *pRev = (GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex];
	int mode=pRev->GetAction(&m_CommitList) & CTGitPath::LOGACTIONS_REBASE_MODE_MASK;
	CString nocommit;

	if( mode== CTGitPath::LOGACTIONS_REBASE_SKIP)
	{
		pRev->GetAction(&m_CommitList)|= CTGitPath::LOGACTIONS_REBASE_DONE;
		return 0;
	}

	if( mode != CTGitPath::LOGACTIONS_REBASE_PICK )
	{
		this->m_SquashMessage+= pRev->GetSubject();
		this->m_SquashMessage+= _T("\n");
		this->m_SquashMessage+= pRev->GetBody();
	}
	else
		this->m_SquashMessage.Empty();

	if(mode == CTGitPath::LOGACTIONS_REBASE_SQUASH)
		nocommit=_T(" --no-commit ");

	CString log;
	log.Format(_T("%s %d: %s"),CTGitPath::GetActionName(mode),this->GetCurrentCommitID(),pRev->m_CommitHash.ToString());
	AddLogString(log);
	AddLogString(pRev->GetSubject());
	if (pRev->GetSubject().IsEmpty())
	{
		CMessageBox::Show(m_hWnd, _T("Found an empty commit message. You have to enter one or rebase cannot proceed."), _T("TortoiseGit"), MB_OK | MB_ICONEXCLAMATION);
		mode = CTGitPath::LOGACTIONS_REBASE_EDIT;
	}

	cmd.Format(_T("git.exe cherry-pick %s %s"),nocommit,pRev->m_CommitHash.ToString());

	if(g_Git.Run(cmd,&out,CP_UTF8))
	{
		AddLogString(out);
		CTGitPathList list;
		if(g_Git.ListConflictFile(list))
		{
			AddLogString(_T("Get conflict files fail"));
			return -1;
		}
		if(list.GetCount() == 0 )
		{
			if(mode ==  CTGitPath::LOGACTIONS_REBASE_PICK)
			{
				pRev->GetAction(&m_CommitList)|= CTGitPath::LOGACTIONS_REBASE_DONE;
				return 0;
			}
			if(mode == CTGitPath::LOGACTIONS_REBASE_EDIT)
			{
				this->m_RebaseStage = REBASE_EDIT ;
				return -1; // Edit return -1 to stop rebase.
			}
			// Squash Case
			if(CheckNextCommitIsSquash())
			{   // no squash
				// let user edit last commmit message
				this->m_RebaseStage = REBASE_SQUASH_EDIT;
				return -1;
			}
		}
		if(mode == CTGitPath::LOGACTIONS_REBASE_SQUASH)
			m_RebaseStage = REBASE_SQUASH_CONFLICT;
		else
			m_RebaseStage = REBASE_CONFLICT;
		return -1;

	}
	else
	{
		AddLogString(out);
		if(mode ==  CTGitPath::LOGACTIONS_REBASE_PICK)
		{
			pRev->GetAction(&m_CommitList)|= CTGitPath::LOGACTIONS_REBASE_DONE;
			return 0;
		}
		if(mode == CTGitPath::LOGACTIONS_REBASE_EDIT)
		{
			this->m_RebaseStage = REBASE_EDIT ;
			return -1; // Edit return -1 to stop rebase.
		}

		// Squash Case
		if(CheckNextCommitIsSquash())
		{   // no squash
			// let user edit last commmit message
			this->m_RebaseStage = REBASE_SQUASH_EDIT;
			return -1;
		}
		else if(mode == CTGitPath::LOGACTIONS_REBASE_SQUASH)
			pRev->GetAction(&m_CommitList)|= CTGitPath::LOGACTIONS_REBASE_DONE;
	}

	return 0;
}
예제 #26
0
bool DiffCommand::Execute()
{
	bool bRet = false;
	CString path2 = CPathUtils::GetLongPathname(parser.GetVal(_T("path2")));
	bool bAlternativeTool = !!parser.HasKey(_T("alternative"));
//	bool bBlame = !!parser.HasKey(_T("blame"));
	if (path2.IsEmpty())
	{
		if (this->orgCmdLinePath.IsDirectory())
		{
			CChangedDlg dlg;
			dlg.m_pathList = CTGitPathList(cmdLinePath);
			dlg.DoModal();
			bRet = true;
		}
		else
		{
			if (cmdLinePath.IsEmpty())
				return false;
			CGitDiff diff;
			//diff.SetAlternativeTool(bAlternativeTool);
			if ( parser.HasKey(_T("startrev")) && parser.HasKey(_T("endrev")) )
			{
				if (parser.HasKey(_T("unified")))
					bRet = !!CAppUtils::StartShowUnifiedDiff(nullptr, cmdLinePath, git_revnum_t(parser.GetVal(_T("endrev"))), cmdLinePath, git_revnum_t(parser.GetVal(_T("startrev"))), bAlternativeTool);
				else
					bRet = !!diff.Diff(&cmdLinePath, &cmdLinePath, git_revnum_t(parser.GetVal(_T("startrev"))), git_revnum_t(parser.GetVal(_T("endrev"))), false, parser.HasKey(_T("unified")) == TRUE, parser.GetLongVal(_T("line")), bAlternativeTool);
			}
			else
			{
				// check if it is a newly added (but uncommitted) file
				git_wc_status_kind status = git_wc_status_none;
				CString topDir;
				if (orgCmdLinePath.HasAdminDir(&topDir))
				{
					CBlockCacheForPath cacheBlock(topDir);
					CAutoIndex index;
					CString adminDir;
					GitAdminDir::GetAdminDirPath(topDir, adminDir);
					if (!git_index_open(index.GetPointer(), CUnicodeUtils::GetUTF8(adminDir + _T("index"))))
						g_Git.Run(_T("git.exe update-index -- \"") + cmdLinePath.GetGitPathString() + _T("\""), nullptr); // make sure we get the right status
					GitStatus::GetFileStatus(topDir, cmdLinePath.GetWinPathString(), &status, true);
					if (index)
						git_index_write(index);
				}
				if (status == git_wc_status_added)
				{
					if (!g_Git.IsInitRepos())
					{
						// this might be a rename, try to find original name
						BYTE_VECTOR cmdout;
						g_Git.Run(_T("git.exe diff-index --raw HEAD -M -C -z --"), &cmdout);
						CTGitPathList changedFiles;
						changedFiles.ParserFromLog(cmdout);
						for (int i = 0; i < changedFiles.GetCount(); ++i)
						{
							if (changedFiles[i].GetGitPathString() == cmdLinePath.GetGitPathString())
							{
								if (!changedFiles[i].GetGitOldPathString().IsEmpty())
								{
									CTGitPath oldPath(changedFiles[i].GetGitOldPathString());
									if (parser.HasKey(_T("unified")))
										return !!CAppUtils::StartShowUnifiedDiff(nullptr, cmdLinePath, git_revnum_t(_T("HEAD")), cmdLinePath, git_revnum_t(GIT_REV_ZERO), bAlternativeTool);
									return !!diff.Diff(&cmdLinePath, &oldPath, git_revnum_t(GIT_REV_ZERO), git_revnum_t(_T("HEAD")), false, parser.HasKey(_T("unified")) == TRUE, parser.GetLongVal(_T("line")), bAlternativeTool);
								}
								break;
							}
						}
					}
					cmdLinePath.m_Action = cmdLinePath.LOGACTIONS_ADDED;
				}

				if (parser.HasKey(_T("unified")))
					bRet = !!CAppUtils::StartShowUnifiedDiff(nullptr, cmdLinePath, git_revnum_t(_T("HEAD")), cmdLinePath, git_revnum_t(GIT_REV_ZERO), bAlternativeTool);
				else
					bRet = !!diff.Diff(&cmdLinePath, &cmdLinePath, git_revnum_t(GIT_REV_ZERO), git_revnum_t(_T("HEAD")), false, parser.HasKey(_T("unified")) == TRUE, parser.GetLongVal(_T("line")), bAlternativeTool);
			}
		}
	}
	else
	{
		CGitDiff diff;
		if ( parser.HasKey(_T("startrev")) && parser.HasKey(_T("endrev")) && path2.Left(g_Git.m_CurrentDir.GetLength() + 1) == g_Git.m_CurrentDir + _T("\\"))
		{
			CTGitPath tgitPath2 = path2.Mid(g_Git.m_CurrentDir.GetLength() + 1);
			bRet = !!diff.Diff(&tgitPath2, &cmdLinePath, git_revnum_t(parser.GetVal(_T("startrev"))), git_revnum_t(parser.GetVal(_T("endrev"))), false, parser.HasKey(_T("unified")) == TRUE, parser.GetLongVal(_T("line")), bAlternativeTool);
		}
		else
		{
			bRet = CAppUtils::StartExtDiff(
				path2, orgCmdLinePath.GetWinPathString(), CString(), CString(),
				CString(), CString(), git_revnum_t(GIT_REV_ZERO), git_revnum_t(GIT_REV_ZERO),
				CAppUtils::DiffFlags().AlternativeTool(bAlternativeTool), parser.GetLongVal(_T("line")));
		}
	}

	return bRet;
}
예제 #27
0
bool CloneCommand::Execute()
{
	CTGitPath cloneDirectory;
	if (!parser.HasKey(_T("hasurlhandler")))
	{
		if (orgCmdLinePath.IsEmpty())
		{
			cloneDirectory.SetFromWin(sOrigCWD, true);
			DWORD len = ::GetTempPath(0, NULL);
			std::unique_ptr<TCHAR[]> tszPath(new TCHAR[len]);
			::GetTempPath(len, tszPath.get());
			if (_tcsncicmp(cloneDirectory.GetWinPath(), tszPath.get(), len-2 /* \\ and \0 */) == 0)
			{
				// if the current directory is set to a temp directory,
				// we don't use that but leave it empty instead.
				cloneDirectory.Reset();
			}
		}
		else
			cloneDirectory = orgCmdLinePath;
	}

	CCloneDlg dlg;
	dlg.m_Directory = cloneDirectory.GetWinPathString();

	if (parser.HasKey(_T("url")))
		dlg.m_URL = parser.GetVal(_T("url"));
	if (parser.HasKey(_T("exactpath")))
		dlg.m_bExactPath = TRUE;

	if(dlg.DoModal()==IDOK)
	{
		CString recursiveStr;
		if(dlg.m_bRecursive)
			recursiveStr = _T("--recursive");
		else
			recursiveStr = _T("");

		CString bareStr;
		if(dlg.m_bBare)
			bareStr = _T("--bare");
		else
			bareStr = _T("");

		CString nocheckoutStr;
		if (dlg.m_bNoCheckout)
			nocheckoutStr = _T("--no-checkout");

		CString branchStr;
		if (dlg.m_bBranch)
			branchStr = _T("--branch ") + dlg.m_strBranch;

		CString originStr;
		if (dlg.m_bOrigin)
			originStr = _T("--origin ") + dlg.m_strOrigin;

		if(dlg.m_bAutoloadPuttyKeyFile)
		{
			CAppUtils::LaunchPAgent(&dlg.m_strPuttyKeyFile);
		}

		CAppUtils::RemoveTrailSlash(dlg.m_Directory);
		if (!dlg.m_bSVN)
			CAppUtils::RemoveTrailSlash(dlg.m_URL);

		CString dir=dlg.m_Directory;
		CString url=dlg.m_URL;

		// is this a windows format UNC path, ie starts with \\?
		if (url.Find(_T("\\\\")) == 0)
		{
			// yes, change all \ to /
			// this should not be necessary but msysgit does not support the use \ here yet
			int atSign = url.Find(_T('@'));
			if (atSign > 0)
			{
				CString path = url.Mid(atSign);
				path.Replace(_T('\\'), _T('/'));
				url = url.Mid(0, atSign) + path;
			}
			else
				url.Replace( _T('\\'), _T('/'));
		}

		CString depth;
		if (dlg.m_bDepth)
		{
			depth.Format(_T(" --depth %d"),dlg.m_nDepth);
		}

		g_Git.m_CurrentDir = GetExistingDirectoryForClone(dlg.m_Directory);

		CString cmd;
		CString progressarg;

		int ver = CAppUtils::GetMsysgitVersion();

		if(ver >= 0x01070002) //above 1.7.0.2
			progressarg = _T("--progress");

		cmd.Format(_T("git.exe clone %s %s %s %s %s %s -v %s \"%s\" \"%s\""),
						nocheckoutStr,
						recursiveStr,
						bareStr,
						branchStr,
						originStr,
						progressarg,
						depth,
						url,
						dir);

		// Handle Git SVN-clone
		if(dlg.m_bSVN)
		{
			//g_Git.m_CurrentDir=dlg.m_Directory;
			cmd.Format(_T("git.exe svn clone \"%s\"  \"%s\""),
				url,dlg.m_Directory);

			if(dlg.m_bSVNTrunk)
				cmd+=_T(" -T ")+dlg.m_strSVNTrunk;

			if(dlg.m_bSVNBranch)
				cmd+=_T(" -b ")+dlg.m_strSVNBranchs;

			if(dlg.m_bSVNTags)
				cmd+=_T(" -t ")+dlg.m_strSVNTags;

			if(dlg.m_bSVNFrom)
			{
				CString str;
				str.Format(_T("%d:HEAD"),dlg.m_nSVNFrom);
				cmd+=_T(" -r ")+str;
			}

			if(dlg.m_bSVNUserName)
			{
				cmd+= _T(" --username ");
				cmd+=dlg.m_strUserName;
			}
		}
		else
		{
			if (g_Git.UsingLibGit2(CGit::GIT_CMD_CLONE))
			{
				CGitProgressDlg GitDlg;
				CTGitPathList list;
				g_Git.m_CurrentDir = dir;
				list.AddPath(CTGitPath(dir));
				GitDlg.SetCommand(CGitProgressList::GitProgress_Clone);
				GitDlg.SetUrl(url);
				GitDlg.SetPathList(list);
				GitDlg.SetIsBare(!!dlg.m_bBare);
				GitDlg.SetRefSpec(dlg.m_bBranch ? dlg.m_strBranch : CString());
				GitDlg.SetRemote(dlg.m_bOrigin ? dlg.m_strOrigin : CString());
				GitDlg.SetNoCheckout(!!dlg.m_bNoCheckout);
				GitDlg.DoModal();
				return !GitDlg.DidErrorsOccur();
			}
		}
		CProgressDlg progress;
		progress.m_GitCmd=cmd;
		progress.m_PostCmdList.Add(CString(MAKEINTRESOURCE(IDS_MENULOG)));
		progress.m_PostCmdList.Add(CString(MAKEINTRESOURCE(IDS_STATUSLIST_CONTEXT_EXPLORE)));
		INT_PTR ret = progress.DoModal();

		if (dlg.m_bSVN)
			::DeleteFile(g_Git.m_CurrentDir + _T("\\sys$command"));

		if( progress.m_GitStatus == 0)
		{
			if(dlg.m_bAutoloadPuttyKeyFile)
			{
				g_Git.m_CurrentDir = dlg.m_Directory;
				SetCurrentDirectory(g_Git.m_CurrentDir);

				if(g_Git.SetConfigValue(_T("remote.origin.puttykeyfile"), dlg.m_strPuttyKeyFile, CONFIG_LOCAL, CP_UTF8))
				{
					CMessageBox::Show(NULL,_T("Fail set config remote.origin.puttykeyfile"),_T("TortoiseGit"),MB_OK|MB_ICONERROR);
					return FALSE;
				}
			}
			if (ret == IDC_PROGRESS_BUTTON1)
			{
				CString cmd = _T("/command:log");
				cmd += _T(" /path:\"") + dlg.m_Directory + _T("\"");
				CAppUtils::RunTortoiseGitProc(cmd);
				return TRUE;
			}
			if (ret == IDC_PROGRESS_BUTTON1 + 1)
			{
				ShellExecute(nullptr, _T("explore"), dlg.m_Directory, nullptr, nullptr, SW_SHOW);
				return TRUE;
			}
		}
		if(ret == IDOK)
			return TRUE;

	}
	return FALSE;
}
예제 #28
0
bool CloneCommand::Execute()
{
	CTGitPath cloneDirectory;
	if (!parser.HasKey(_T("hasurlhandler")))
	{
		if (orgCmdLinePath.IsEmpty())
		{
			cloneDirectory.SetFromWin(sOrigCWD, true);
			DWORD len = ::GetTempPath(0, nullptr);
			auto tszPath = std::make_unique<TCHAR[]>(len);
			::GetTempPath(len, tszPath.get());
			if (_tcsncicmp(cloneDirectory.GetWinPath(), tszPath.get(), len-2 /* \\ and \0 */) == 0)
			{
				// if the current directory is set to a temp directory,
				// we don't use that but leave it empty instead.
				cloneDirectory.Reset();
			}
		}
		else
			cloneDirectory = orgCmdLinePath;
	}

	CCloneDlg dlg;
	dlg.m_Directory = cloneDirectory.GetWinPathString();

	if (parser.HasKey(_T("url")))
		dlg.m_URL = parser.GetVal(_T("url"));
	if (parser.HasKey(_T("exactpath")))
		dlg.m_bExactPath = TRUE;

	if(dlg.DoModal()==IDOK)
	{
		CString recursiveStr;
		if(dlg.m_bRecursive)
			recursiveStr = _T(" --recursive");

		CString bareStr;
		if(dlg.m_bBare)
			bareStr = _T(" --bare");

		CString nocheckoutStr;
		if (dlg.m_bNoCheckout)
			nocheckoutStr = _T(" --no-checkout");

		CString branchStr;
		if (dlg.m_bBranch)
			branchStr = _T(" --branch ") + dlg.m_strBranch;

		CString originStr;
		if (dlg.m_bOrigin && !dlg.m_bSVN)
			originStr = _T(" --origin ") + dlg.m_strOrigin;

		if(dlg.m_bAutoloadPuttyKeyFile)
		{
			CAppUtils::LaunchPAgent(&dlg.m_strPuttyKeyFile);
		}

		CAppUtils::RemoveTrailSlash(dlg.m_Directory);
		if (!dlg.m_bSVN)
			CAppUtils::RemoveTrailSlash(dlg.m_URL);

		CString dir=dlg.m_Directory;
		CString url=dlg.m_URL;

		// is this a windows format UNC path, ie starts with \\?
		if (url.Find(_T("\\\\")) == 0)
		{
			// yes, change all \ to /
			// this should not be necessary but msysgit does not support the use \ here yet
			int atSign = url.Find(_T('@'));
			if (atSign > 0)
			{
				CString path = url.Mid(atSign);
				path.Replace(_T('\\'), _T('/'));
				url = url.Mid(0, atSign) + path;
			}
			else
				url.Replace( _T('\\'), _T('/'));
		}

		CString depth;
		if (dlg.m_bDepth)
		{
			depth.Format(_T(" --depth %d"),dlg.m_nDepth);
		}

		CString cmd;
		cmd.Format(_T("git.exe clone --progress%s%s%s%s%s -v%s \"%s\" \"%s\""),
						(LPCTSTR)nocheckoutStr,
						(LPCTSTR)recursiveStr,
						(LPCTSTR)bareStr,
						(LPCTSTR)branchStr,
						(LPCTSTR)originStr,
						(LPCTSTR)depth,
						(LPCTSTR)url,
						(LPCTSTR)dir);

		bool retry = false;
		auto postCmdCallback = [&](DWORD status, PostCmdList& postCmdList)
		{
			if (status)
			{
				postCmdList.emplace_back(IDI_REFRESH, IDS_MSGBOX_RETRY, [&]{ retry = true; });
				return;
			}

			// After cloning, change current directory to the cloned directory
			g_Git.m_CurrentDir = dlg.m_Directory;
			if (dlg.m_bAutoloadPuttyKeyFile) // do this here, since it might be needed for actions performed in Log
				StorePuttyKey(dlg.m_Directory, dlg.m_bOrigin && !dlg.m_strOrigin.IsEmpty() ? dlg.m_strOrigin : _T("origin"), dlg.m_strPuttyKeyFile);

			postCmdList.emplace_back(IDI_LOG, IDS_MENULOG, [&]
			{
				CString cmd = _T("/command:log");
				cmd += _T(" /path:\"") + dlg.m_Directory + _T("\"");
				CAppUtils::RunTortoiseGitProc(cmd);
			});

			postCmdList.emplace_back(IDI_EXPLORER, IDS_STATUSLIST_CONTEXT_EXPLORE, [&]{ CAppUtils::ExploreTo(hWndExplorer, dlg.m_Directory); });
		};

		// Handle Git SVN-clone
		if(dlg.m_bSVN)
		{
			//g_Git.m_CurrentDir=dlg.m_Directory;
			cmd.Format(_T("git.exe svn clone \"%s\" \"%s\""),
				(LPCTSTR)url, (LPCTSTR)dlg.m_Directory);

			if (dlg.m_bOrigin)
			{
				CString str;
				if (dlg.m_strOrigin.IsEmpty())
					str = _T(" --prefix \"\"");
				else
					str.Format(_T(" --prefix \"%s/\""), (LPCTSTR)dlg.m_strOrigin);
				cmd += str;
			}

			if(dlg.m_bSVNTrunk)
				cmd+=_T(" -T ")+dlg.m_strSVNTrunk;

			if(dlg.m_bSVNBranch)
				cmd+=_T(" -b ")+dlg.m_strSVNBranchs;

			if(dlg.m_bSVNTags)
				cmd+=_T(" -t ")+dlg.m_strSVNTags;

			if(dlg.m_bSVNFrom)
			{
				CString str;
				str.Format(_T("%d:HEAD"),dlg.m_nSVNFrom);
				cmd+=_T(" -r ")+str;
			}

			if(dlg.m_bSVNUserName)
			{
				cmd+= _T(" --username ");
				cmd+=dlg.m_strUserName;
			}
		}
		else
		{
			if (g_Git.UsingLibGit2(CGit::GIT_CMD_CLONE))
			{
				while (true)
				{
					retry = false;
					CGitProgressDlg GitDlg;
					CTGitPathList list;
					g_Git.m_CurrentDir = GetExistingDirectoryForClone(dlg.m_Directory);
					list.AddPath(CTGitPath(dir));
					CloneProgressCommand cloneProgressCommand;
					GitDlg.SetCommand(&cloneProgressCommand);
					cloneProgressCommand.m_PostCmdCallback = postCmdCallback;
					cloneProgressCommand.SetUrl(url);
					cloneProgressCommand.SetPathList(list);
					cloneProgressCommand.SetIsBare(dlg.m_bBare == TRUE);
					if (dlg.m_bBranch)
						cloneProgressCommand.SetRefSpec(dlg.m_strBranch);
					if (dlg.m_bOrigin)
						cloneProgressCommand.SetRemote(dlg.m_strOrigin);
					cloneProgressCommand.SetNoCheckout(dlg.m_bNoCheckout == TRUE);
					GitDlg.DoModal();
					if (!retry)
						return !GitDlg.DidErrorsOccur();
				}
			}
		}

		while (true)
		{
			retry = false;
			g_Git.m_CurrentDir = GetExistingDirectoryForClone(dlg.m_Directory);
			CProgressDlg progress;
			progress.m_GitCmd=cmd;
			progress.m_PostCmdCallback = postCmdCallback;
			INT_PTR ret = progress.DoModal();

			if (!retry)
				return ret == IDOK;
		}
	}
	return FALSE;
}
예제 #29
0
void CSyncDlg::OnBnClickedButtonPush()
{
	this->UpdateData();
	UpdateCombox();
	m_ctrlCmdOut.SetWindowTextW(_T(""));
	m_LogText = "";

	if(this->m_strURL.IsEmpty())
	{
		CMessageBox::Show(NULL, IDS_PROC_GITCONFIG_URLEMPTY, IDS_APPNAME, MB_OK | MB_ICONERROR);
		return;
	}

	this->m_regPushButton=(DWORD)this->m_ctrlPush.GetCurrentEntry();
	this->SwitchToRun();
	this->m_bAbort=false;
	this->m_GitCmdList.clear();

	ShowTab(IDC_CMD_LOG);

	CString cmd;
	CString arg;

	CString error;
	DWORD exitcode;
	CTGitPathList list;
	list.AddPath(CTGitPath(g_Git.m_CurrentDir));

	if (CHooks::Instance().PrePush(list,exitcode, error))
	{
		if (exitcode)
		{
			CString temp;
			temp.Format(IDS_ERR_HOOKFAILED, (LPCTSTR)error);
			//ReportError(temp);
			CMessageBox::Show(NULL,temp,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
			return ;
		}
	}

	CString refName = g_Git.FixBranchName(m_strLocalBranch);
	switch (m_ctrlPush.GetCurrentEntry())
	{
	case 1:
		arg += _T(" --tags ");
		break;
	case 2:
		refName = _T("refs/notes/commits");	//default ref for notes
		break;
	}

	if(this->m_bForce)
		arg += _T(" --force ");

	if(m_Gitverion >= 0x01070203) //above 1.7.0.2
		arg += _T("--progress ");

	cmd.Format(_T("git.exe push -v %s \"%s\" %s"),
				arg,
				m_strURL,
				refName);

	if (!m_strRemoteBranch.IsEmpty() && m_ctrlPush.GetCurrentEntry() != 2)
	{
		cmd += _T(":") + m_strRemoteBranch;
	}

	m_GitCmdList.push_back(cmd);

	m_CurrentCmd = GIT_COMMAND_PUSH;

	if(this->m_bAutoLoadPuttyKey)
	{
		CAppUtils::LaunchPAgent(NULL,&this->m_strURL);
	}

	m_pThread = AfxBeginThread(ProgressThreadEntry, this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);
	if (m_pThread==NULL)
	{
//		ReportError(CString(MAKEINTRESOURCE(IDS_ERR_THREADSTARTFAILED)));
	}
	else
	{
		m_pThread->m_bAutoDelete = TRUE;
		m_pThread->ResumeThread();
	}
}
예제 #30
0
void CSyncDlg::PullComplete()
{
	EnableControlButton(true);
	SwitchToInput();
	this->FetchOutList(true);

	CGitHash newhash;
	if (g_Git.GetHash(newhash, _T("HEAD")))
		MessageBox(g_Git.GetGitLastErr(_T("Could not get HEAD hash after pulling.")), _T("TortoiseGit"), MB_ICONERROR);

	if( this ->m_GitCmdStatus )
	{
		CTGitPathList list;
		if(g_Git.ListConflictFile(list))
		{
			this->m_ctrlCmdOut.SetSel(-1,-1);
			this->m_ctrlCmdOut.ReplaceSel(_T("Get conflict files fail\n"));

			this->ShowTab(IDC_CMD_LOG);
			return;
		}

		if (!list.IsEmpty())
		{
			this->m_ConflictFileList.Clear();
			CTGitPathList list;
			CTGitPath path;
			list.AddPath(path);

			this->m_ConflictFileList.GetStatus(&list,true);
			this->m_ConflictFileList.Show(CTGitPath::LOGACTIONS_UNMERGED,
											CTGitPath::LOGACTIONS_UNMERGED);

			this->ShowTab(IDC_IN_CONFLICT);
		}
		else
			this->ShowTab(IDC_CMD_LOG);

	}
	else
	{
		if(newhash == this->m_oldHash)
		{
			this->m_ctrlTabCtrl.ShowTab(IDC_IN_CHANGELIST-1,false);
			this->m_InLogList.ShowText(CString(MAKEINTRESOURCE(IDS_UPTODATE)));
			this->m_ctrlTabCtrl.ShowTab(IDC_IN_LOGLIST-1,true);
			this->ShowTab(IDC_REFLIST);
		}
		else
		{
			this->m_ctrlTabCtrl.ShowTab(IDC_IN_CHANGELIST-1,true);
			this->m_ctrlTabCtrl.ShowTab(IDC_IN_LOGLIST-1,true);

			this->AddDiffFileList(&m_InChangeFileList, &m_arInChangeList, newhash.ToString(), m_oldHash.ToString());

			CString range;
			range.Format(_T("%s..%s"), m_oldHash.ToString(), newhash.ToString());
			m_InLogList.FillGitLog(nullptr, &range, CGit::LOG_INFO_STAT| CGit::LOG_INFO_FILESTATE | CGit::LOG_INFO_SHOW_MERGEDFILE);
			this->ShowTab(IDC_IN_LOGLIST);
		}
	}
}