示例#1
0
文件: Git.cpp 项目: jrk/tortoisegit
int CGit::Revert(CTGitPath &path,bool keep)
{
	CString cmd, out;
	if(path.m_Action & CTGitPath::LOGACTIONS_ADDED)
	{	//To init git repository, there are not HEAD, so we can use git reset command
		cmd.Format(_T("git.exe rm --cache -- \"%s\""),path.GetGitPathString());
		if(g_Git.Run(cmd,&out,CP_OEMCP))
			return -1;
	}
	else if(path.m_Action & CTGitPath::LOGACTIONS_REPLACED )
	{
		cmd.Format(_T("git.exe mv \"%s\" \"%s\""),path.GetGitPathString(),path.GetGitOldPathString());
		if(g_Git.Run(cmd,&out,CP_OEMCP))
			return -1;
		
		cmd.Format(_T("git.exe checkout -f -- \"%s\""),path.GetGitOldPathString());
		if(g_Git.Run(cmd,&out,CP_OEMCP))
			return -1;
	}
	else
	{
		cmd.Format(_T("git.exe checkout -f -- \"%s\""),path.GetGitPathString());
		if(g_Git.Run(cmd,&out,CP_OEMCP))
			return -1;
	}
	return 0;
}
示例#2
0
int CGitDiff::SubmoduleDiffNull(const CTGitPath * pPath, const git_revnum_t &rev1)
{
	CString oldhash = GIT_REV_ZERO;
	CString oldsub ;
	CString newsub;
	CString newhash;

	CString cmd;
	if (rev1 != GIT_REV_ZERO)
		cmd.Format(_T("git.exe ls-tree \"%s\" -- \"%s\""), rev1, pPath->GetGitPathString());
	else
		cmd.Format(_T("git.exe ls-files -s -- \"%s\""), pPath->GetGitPathString());

	CString output, err;
	if (g_Git.Run(cmd, &output, &err, CP_UTF8))
	{
		CMessageBox::Show(NULL, output + L"\n" + err, _T("TortoiseGit"), MB_OK|MB_ICONERROR);
		return -1;
	}

	int start=0;
	start=output.Find(_T(' '),start);
	if(start>0)
	{
		if (rev1 != GIT_REV_ZERO) // in ls-files the hash is in the second column; in ls-tree it's in the third one
			start = output.Find(_T(' '), start + 1);
		if(start>0)
			newhash=output.Mid(start+1, 40);

		CGit subgit;
		subgit.m_CurrentDir=g_Git.m_CurrentDir+_T("\\")+pPath->GetWinPathString();
		int encode=CAppUtils::GetLogOutputEncode(&subgit);

		cmd.Format(_T("git.exe log -n1  --pretty=format:\"%%s\" %s --"), newhash);
		bool toOK = !subgit.Run(cmd,&newsub,encode);

		bool dirty = false;
		if (rev1 == GIT_REV_ZERO)
		{
			CString dirtyList;
			subgit.Run(_T("git.exe status --porcelain"), &dirtyList, encode);
			dirty = !dirtyList.IsEmpty();
		}

		CSubmoduleDiffDlg submoduleDiffDlg;
		submoduleDiffDlg.SetDiff(pPath->GetWinPath(), false, oldhash, oldsub, true, newhash, newsub, toOK, dirty, CSubmoduleDiffDlg::NewSubmodule);
		submoduleDiffDlg.DoModal();
		if (submoduleDiffDlg.IsRefresh())
			return 1;

		return 0;
	}

	if (rev1 != GIT_REV_ZERO)
		CMessageBox::Show(NULL, _T("ls-tree output format error"), _T("TortoiseGit"), MB_OK | MB_ICONERROR);
	else
		CMessageBox::Show(NULL, _T("ls-files output format error"), _T("TortoiseGit"), MB_OK | MB_ICONERROR);
	return -1;
}
示例#3
0
bool SubmoduleAddCommand::Execute()
{
	bool bRet = false;
	CSubmoduleAddDlg dlg;
	dlg.m_strPath = cmdLinePath.GetDirectory().GetWinPathString();
	dlg.m_strProject = g_Git.m_CurrentDir;
	if( dlg.DoModal() == IDOK )
	{
		if (dlg.m_bAutoloadPuttyKeyFile)
			CAppUtils::LaunchPAgent(&dlg.m_strPuttyKeyFile);

		CString cmd;
		if(dlg.m_strPath.Left(g_Git.m_CurrentDir.GetLength()) == g_Git.m_CurrentDir)
			dlg.m_strPath = dlg.m_strPath.Right(dlg.m_strPath.GetLength()-g_Git.m_CurrentDir.GetLength()-1);

		CString branch;
		if(dlg.m_bBranch)
			branch.Format(_T(" -b %s "), (LPCTSTR)dlg.m_strBranch);

		CString force;
		if (dlg.m_bForce)
			force = _T("--force");

		dlg.m_strPath.Replace(_T('\\'),_T('/'));
		dlg.m_strRepos.Replace(_T('\\'),_T('/'));

		cmd.Format(_T("git.exe submodule add %s %s -- \"%s\"  \"%s\""),
						(LPCTSTR)branch, (LPCTSTR)force,
						(LPCTSTR)dlg.m_strRepos, (LPCTSTR)dlg.m_strPath);

		CProgressDlg progress;
		progress.m_GitCmd=cmd;
		progress.DoModal();

		if (progress.m_GitStatus == 0)
		{
			if (dlg.m_bAutoloadPuttyKeyFile)
			{
				SetCurrentDirectory(g_Git.m_CurrentDir);
				CGit subgit;
				dlg.m_strPath.Replace(_T('/'), _T('\\'));
				subgit.m_CurrentDir = PathIsRelative(dlg.m_strPath) ? g_Git.CombinePath(dlg.m_strPath) : dlg.m_strPath;

				if (subgit.SetConfigValue(_T("remote.origin.puttykeyfile"), dlg.m_strPuttyKeyFile, CONFIG_LOCAL))
				{
					CMessageBox::Show(NULL, _T("Fail set config remote.origin.puttykeyfile"), _T("TortoiseGit"), MB_OK| MB_ICONERROR);
					return FALSE;
				}
			}
		}

		bRet = TRUE;
	}
	return bRet;
}
示例#4
0
文件: Git.cpp 项目: jrk/tortoisegit
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;
}
示例#5
0
文件: Git.cpp 项目: jrk/tortoisegit
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;
}
示例#6
0
int addto_map_each_ref_fn(const char *refname, const unsigned char *sha1, int /*flags*/, void *cb_data)
{
	MAP_HASH_NAME *map = (MAP_HASH_NAME*)cb_data;
	CString str;
	g_Git.StringAppend(&str, (BYTE*)refname, CP_UTF8);
	CGitHash hash((char*)sha1);

	(*map)[hash].push_back(str);

	if(strncmp(refname, "refs/tags", 9) == 0)
	{
		try
		{
			GIT_HASH refhash;
			if(!git_deref_tag(sha1, refhash))
			{
				(*map)[(char*)refhash].push_back(str+_T("^{}"));
			}
		}
		catch (char* msg)
		{
			CString err(msg);
			::MessageBox(NULL, _T("Could not get (readable) reference for hash ") + hash.ToString() + _T(".\nlibgit reports:\n") + err, _T("TortoiseGit"), MB_ICONERROR);
		}
	}
	return 0;
}
示例#7
0
int CGit::GetOneFile(CString Refname, CTGitPath &path, const CString &outputfile)
{
	if(g_Git.m_IsUseGitDLL)
	{
		CAutoLocker lock(g_Git.m_critGitDllSec);
		try
		{
			g_Git.CheckAndInitDll();
			CStringA ref, patha, outa;
			ref = CUnicodeUtils::GetMulti(Refname, CP_UTF8);
			patha = CUnicodeUtils::GetMulti(path.GetGitPathString(), CP_UTF8);
			outa = CUnicodeUtils::GetMulti(outputfile, CP_UTF8);
			::DeleteFile(outputfile);
			return git_checkout_file((const char*)ref.GetBuffer(),(const char*)patha.GetBuffer(),(const char*)outa.GetBuffer());

		}catch(...)
		{
			return -1;
		}
	}
	else
	{
		CString cmd;
		cmd.Format(_T("git.exe cat-file -p %s:\"%s\""), Refname, path.GetGitPathString());
		return RunLogFile(cmd,outputfile);
	}
}
示例#8
0
文件: Git.cpp 项目: jrk/tortoisegit
int CGit::GetMapHashToFriendName(MAP_HASH_NAME &map)
{
	int ret;
	CString cmd,output;
	cmd=_T("git show-ref -d");
	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 name;
				name=one.Right(one.GetLength()-start-1);

				CString hash;
				hash=one.Left(start);

				map[hash].push_back(name);
			}
		}
	}
	return ret;
}
示例#9
0
int CTGitPathList::FillUnRev(unsigned int action, CTGitPathList *list, CString *err)
{
	this->Clear();
	CTGitPath path;

	int count;
	if(list==NULL)
		count=1;
	else
		count=list->GetCount();
	for (int i = 0; i < count; ++i)
	{
		CString cmd;
		int pos = 0;

		CString ignored;
		if(action & CTGitPath::LOGACTIONS_IGNORE)
			ignored= _T(" -i");

		if(list==NULL)
		{
			cmd=_T("git.exe ls-files --exclude-standard --full-name --others -z");
			cmd+=ignored;

		}
		else
		{	cmd.Format(_T("git.exe ls-files --exclude-standard --full-name --others -z%s -- \"%s\""),
					(LPCTSTR)ignored,
					(*list)[i].GetWinPath());
		}

		BYTE_VECTOR out, errb;
		out.clear();
		if (g_Git.Run(cmd, &out, &errb))
		{
			if (err != nullptr)
				CGit::StringAppend(err, &errb[0], CP_UTF8, (int)errb.size());
			return -1;
		}

		pos=0;
		CString one;
		while (pos >= 0 && pos < (int)out.size())
		{
			one.Empty();
			CGit::StringAppend(&one, &out[pos], CP_UTF8);
			if(!one.IsEmpty())
			{
				//SetFromGit will clear all status
				path.SetFromGit(one);
				path.m_Action=action;
				AddPath(path);
			}
			pos=out.findNextString(pos);
		}

	}
	return 0;
}
示例#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;
}
示例#11
0
int CGitDiff::SubmoduleDiffNull(CTGitPath *pPath, git_revnum_t &/*rev1*/)
{
	CString oldhash = GIT_REV_ZERO;
	CString oldsub ;
	CString newsub;
	CString newhash;

	CString cmd;
	cmd.Format(_T("git.exe ls-tree  HEAD -- \"%s\""), pPath->GetGitPathString());
	CString output, err;
	if(g_Git.Run(cmd, &output, &err, CP_ACP))
	{
		CMessageBox::Show(NULL, output + L"\n" + err, _T("TortoiseGit"), MB_OK|MB_ICONERROR);
		return -1;
	}

	int start=0;
	start=output.Find(_T(' '),start);
	if(start>0)
	{
		start=output.Find(_T(' '),start+1);
		if(start>0)
			newhash=output.Mid(start+1, 40);

		CGit subgit;
		subgit.m_CurrentDir=g_Git.m_CurrentDir+_T("\\")+pPath->GetWinPathString();
		int encode=CAppUtils::GetLogOutputEncode(&subgit);

		cmd.Format(_T("git.exe log -n1  --pretty=format:\"%%s\" %s"),newhash);
		subgit.Run(cmd,&newsub,encode);

		CSubmoduleDiffDlg submoduleDiffDlg;
		submoduleDiffDlg.SetDiff(pPath->GetWinPath(), false, oldhash, oldsub, newhash, newsub);
		submoduleDiffDlg.DoModal();

		return 0;
	}

	CMessageBox::Show(NULL,_T("ls-tree output format error"),_T("TortoiseGit"),MB_OK|MB_ICONERROR);
	return -1;
}
bool CreateRepositoryCommand::Execute()
{
	CString folder = this->orgCmdLinePath.GetWinPath();
	CCreateRepoDlg dlg;
	dlg.m_folder = folder;
	if(dlg.DoModal() == IDOK)
	{
		CString message;
		message.Format(IDS_WARN_GITINIT_FOLDERNOTEMPTY, folder);
		if (!PathIsDirectoryEmpty(folder) && CMessageBox::Show(hwndExplorer, message, _T("TortoiseGit"), 1, IDI_ERROR, CString(MAKEINTRESOURCE(IDS_ABORTBUTTON)), CString(MAKEINTRESOURCE(IDS_PROCEEDBUTTON))) == 1)
		{
			return false;
		}

		CGit git;
		git.m_CurrentDir = this->orgCmdLinePath.GetWinPath();
		CString output;
		int ret;

		if (dlg.m_bBare)
			ret = git.Run(_T("git.exe init-db --bare"), &output, CP_UTF8);
		else
			ret = git.Run(_T("git.exe init-db"), &output, CP_UTF8);

		if (output.IsEmpty()) output = _T("git.Run() had no output");

		if (ret)
		{
			CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_ICONERROR);
			return false;
		}
		else
		{
			if (!dlg.m_bBare)
				CShellUpdater::Instance().AddPathForUpdate(orgCmdLinePath);
			CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION);
		}
		return true;
	}
	return false;
}
示例#13
0
文件: Git.cpp 项目: jrk/tortoisegit
BOOL CGit::CheckCleanWorkTree()
{
	CString out;
	CString cmd;
	cmd=_T("git.exe rev-parse --verify HEAD");

	if(g_Git.Run(cmd,&out,CP_UTF8))
		return FALSE;

	cmd=_T("git.exe update-index --ignore-submodules --refresh");
	if(g_Git.Run(cmd,&out,CP_UTF8))
		return FALSE;

	cmd=_T("git.exe diff-files --quiet --ignore-submodules");
	if(g_Git.Run(cmd,&out,CP_UTF8))
		return FALSE;

	cmd=_T("git diff-index --cached --quiet HEAD --ignore-submodules");
	if(g_Git.Run(cmd,&out,CP_UTF8))
		return FALSE;

	return TRUE;
}
示例#14
0
文件: Git.cpp 项目: jrk/tortoisegit
BOOL CGit::IsInitRepos()
{
	CString cmdout;
	cmdout.Empty();
	if(g_Git.Run(_T("git.exe rev-parse --revs-only HEAD"),&cmdout,CP_UTF8))
	{
	//	CMessageBox::Show(NULL,cmdout,_T("TortoiseGit"),MB_OK);
		return TRUE;
	}
	if(cmdout.IsEmpty())
		return TRUE;

	return FALSE;
}
示例#15
0
int CTGitPathList::FillBasedOnIndexFlags(unsigned short flag, CTGitPathList* list /*nullptr*/)
{
	Clear();
	CTGitPath path;

	CAutoRepository repository(g_Git.GetGitRepository());
	if (!repository)
		return -1;

	CAutoIndex index;
	if (git_repository_index(index.GetPointer(), repository))
		return -1;

	int count;
	if (list == nullptr)
		count = 1;
	else
		count = list->GetCount();
	for (int j = 0; j < count; ++j)
	{
		for (size_t i = 0, ecount = git_index_entrycount(index); i < ecount; ++i)
		{
			const git_index_entry *e = git_index_get_byindex(index, i);

			if (!e || !((e->flags | e->flags_extended) & flag) || !e->path)
				continue;

			CString one = CUnicodeUtils::GetUnicode(e->path);

			if (!(!list || (*list)[j].GetWinPathString().IsEmpty() || one == (*list)[j].GetGitPathString() || (PathIsDirectory(g_Git.CombinePath((*list)[j].GetWinPathString())) && one.Find((*list)[j].GetGitPathString() + _T("/")) == 0)))
				continue;

			//SetFromGit will clear all status
			path.SetFromGit(one);
			if ((e->flags | e->flags_extended) & GIT_IDXENTRY_SKIP_WORKTREE)
				path.m_Action = CTGitPath::LOGACTIONS_SKIPWORKTREE;
			else if ((e->flags | e->flags_extended) & GIT_IDXENTRY_VALID)
				path.m_Action = CTGitPath::LOGACTIONS_ASSUMEVALID;
			AddPath(path);
		}
	}
	RemoveDuplicates();
	return 0;
}
示例#16
0
文件: Git.cpp 项目: jrk/tortoisegit
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(g_Git.Run(cmd,&vector))
	{
		return -1;
	}

	list.ParserFromLsFile(vector);

	return 0;
}
示例#17
0
文件: Git.cpp 项目: jrk/tortoisegit
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;
}
示例#18
0
文件: Git.cpp 项目: jrk/tortoisegit
CString CGit::GetCurrentBranch(void)
{
	CString output;
	//Run(_T("git.exe branch"),&branch);

	int ret=g_Git.Run(_T("git.exe branch"),&output,CP_UTF8);
	if(!ret)
	{		
		int pos=0;
		CString one;
		while( pos>=0 )
		{
			//i++;
			one=output.Tokenize(_T("\n"),pos);
			//list.push_back(one.Right(one.GetLength()-2));
			if(one[0] == _T('*'))
				return one.Right(one.GetLength()-2);
		}
	}
	return CString("");
}
示例#19
0
CString CGit::GetGitGlobalConfig()
{
	return g_Git.GetHomeDirectory() + _T("\\.gitconfig");
}
示例#20
0
int CGitDiff::SubmoduleDiff(const CTGitPath * pPath, const CTGitPath * /*pPath2*/, const git_revnum_t &rev1, const git_revnum_t &rev2, bool /*blame*/, bool /*unified*/)
{
	CString oldhash;
	CString newhash;
	bool dirty = false;
	CString cmd;
	bool isWorkingCopy = false;
	if( rev2 == GIT_REV_ZERO || rev1 == GIT_REV_ZERO )
	{
		oldhash = GIT_REV_ZERO;
		newhash = GIT_REV_ZERO;

		CString rev;
		if( rev2 != GIT_REV_ZERO )
			rev = rev2;
		if( rev1 != GIT_REV_ZERO )
			rev = rev1;

		isWorkingCopy = true;

		cmd.Format(_T("git.exe diff %s -- \"%s\""),
		rev,pPath->GetGitPathString());

		CString output, err;
		if (g_Git.Run(cmd, &output, &err, CP_UTF8))
		{
			CMessageBox::Show(NULL, output + L"\n" + err, _T("TortoiseGit"), MB_OK|MB_ICONERROR);
			return -1;
		}

		if (output.IsEmpty())
		{
			output.Empty();
			err.Empty();
			// also compare against index
			cmd.Format(_T("git.exe diff -- \"%s\""), pPath->GetGitPathString());
			if (g_Git.Run(cmd, &output, &err, CP_UTF8))
			{
				CMessageBox::Show(NULL, output + _T("\n") + err, _T("TortoiseGit"), MB_OK | MB_ICONERROR);
				return -1;
			}

			if (output.IsEmpty())
			{
				CMessageBox::Show(NULL, CString(MAKEINTRESOURCE(IDS_ERR_EMPTYDIFF)), _T("TortoiseGit"), MB_OK | MB_ICONERROR);
				return -1;
			}
			else if (CMessageBox::Show(NULL, CString(MAKEINTRESOURCE(IDS_SUBMODULE_EMPTYDIFF)), _T("TortoiseGit"), 1, IDI_QUESTION, CString(MAKEINTRESOURCE(IDS_MSGBOX_YES)), CString(MAKEINTRESOURCE(IDS_MSGBOX_NO))) == 1)
			{
				CString sCmd;
				sCmd.Format(_T("/command:subupdate /bkpath:\"%s\""), g_Git.m_CurrentDir);
				CAppUtils::RunTortoiseGitProc(sCmd);
			}
			return -1;
		}

		int start =0;
		int oldstart = output.Find(_T("-Subproject commit"),start);
		if(oldstart<0)
		{
			CMessageBox::Show(NULL,_T("Subproject Diff Format error") ,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
			return -1;
		}
		oldhash = output.Mid(oldstart+ CString(_T("-Subproject commit")).GetLength()+1,40);
		start = 0;
		int newstart = output.Find(_T("+Subproject commit"),start);
		if(oldstart<0)
		{
			CMessageBox::Show(NULL,_T("Subproject Diff Format error") ,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
			return -1;
		}
		newhash = output.Mid(newstart+ CString(_T("+Subproject commit")).GetLength()+1,40);
		dirty = output.Mid(newstart + CString(_T("+Subproject commit")).GetLength() + 41) == _T("-dirty\n");
	}
	else
	{
		cmd.Format(_T("git.exe diff-tree -r -z %s %s -- \"%s\""),
		rev2,rev1,pPath->GetGitPathString());

		BYTE_VECTOR bytes, errBytes;
		if(g_Git.Run(cmd, &bytes, &errBytes))
		{
			CString err;
			g_Git.StringAppend(&err, &errBytes[0], CP_UTF8);
			CMessageBox::Show(NULL,err,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
			return -1;
		}

		g_Git.StringAppend(&oldhash, &bytes[15], CP_UTF8, 40);
		g_Git.StringAppend(&newhash, &bytes[15+41], CP_UTF8, 40);

	}

	CString oldsub;
	CString newsub;
	bool oldOK = false, newOK = false;

	CGit subgit;
	subgit.m_CurrentDir=g_Git.m_CurrentDir+_T("\\")+pPath->GetWinPathString();
	CSubmoduleDiffDlg::ChangeType changeType = CSubmoduleDiffDlg::Unknown;

	if(pPath->HasAdminDir())
	{
		int encode=CAppUtils::GetLogOutputEncode(&subgit);
		int oldTime = 0, newTime = 0;

		if(oldhash != GIT_REV_ZERO)
		{
			CString cmdout, cmderr;
			cmd.Format(_T("git.exe log -n1 --pretty=format:\"%%ct %%s\" %s --"), oldhash);
			oldOK = !subgit.Run(cmd, &cmdout, &cmderr, encode);
			if (oldOK)
			{
				int pos = cmdout.Find(_T(" "));
				oldTime = _ttoi(cmdout.Left(pos));
				oldsub = cmdout.Mid(pos + 1);
			}
			else
				oldsub = cmderr;
		}
		if (newhash != GIT_REV_ZERO)
		{
			CString cmdout, cmderr;
			cmd.Format(_T("git.exe log -n1 --pretty=format:\"%%ct %%s\" %s --"), newhash);
			newOK = !subgit.Run(cmd, &cmdout, &cmderr, encode);
			if (newOK)
			{
				int pos = cmdout.Find(_T(" "));
				newTime = _ttoi(cmdout.Left(pos));
				newsub = cmdout.Mid(pos + 1);
			}
			else
				newsub = cmderr;
		}

		if (oldhash == GIT_REV_ZERO)
		{
			oldOK = true;
			changeType = CSubmoduleDiffDlg::NewSubmodule;
		}
		else if (newhash == GIT_REV_ZERO)
		{
			newOK = true;
			changeType = CSubmoduleDiffDlg::DeleteSubmodule;
		}
		else if (oldhash != newhash)
		{
			bool ffNewer = false, ffOlder = false;
			ffNewer = subgit.IsFastForward(oldhash, newhash);
			if (!ffNewer)
			{
				ffOlder = subgit.IsFastForward(newhash, oldhash);
				if (!ffOlder)
				{
					if (newTime > oldTime)
						changeType = CSubmoduleDiffDlg::NewerTime;
					else if (newTime < oldTime)
						changeType = CSubmoduleDiffDlg::OlderTime;
					else
						changeType = CSubmoduleDiffDlg::SameTime;
				}
				else
					changeType = CSubmoduleDiffDlg::Rewind;
			}
			else
				changeType = CSubmoduleDiffDlg::FastForward;
		}
	}

	if (!oldOK || !newOK)
		changeType = CSubmoduleDiffDlg::Unknown;

	CSubmoduleDiffDlg submoduleDiffDlg;
	submoduleDiffDlg.SetDiff(pPath->GetWinPath(), isWorkingCopy, oldhash, oldsub, oldOK, newhash, newsub, newOK, dirty, changeType);
	submoduleDiffDlg.DoModal();
	if (submoduleDiffDlg.IsRefresh())
		return 1;

	return 0;
}
示例#21
0
void CGitDiff::GetSubmoduleChangeType(CGit& subgit, const CString& oldhash, const CString& newhash, bool& oldOK, bool& newOK, ChangeType& changeType, CString& oldsub, CString& newsub)
{
	CString cmd;
	int encode = CAppUtils::GetLogOutputEncode(&subgit);
	int oldTime = 0, newTime = 0;

	if (oldhash != GIT_REV_ZERO)
	{
		CString cmdout, cmderr;
		cmd.Format(_T("git.exe log -n1 --pretty=format:\"%%ct %%s\" %s --"), (LPCTSTR)oldhash);
		oldOK = !subgit.Run(cmd, &cmdout, &cmderr, encode);
		if (oldOK)
		{
			int pos = cmdout.Find(_T(" "));
			oldTime = _ttoi(cmdout.Left(pos));
			oldsub = cmdout.Mid(pos + 1);
		}
		else
			oldsub = cmderr;
	}
	if (newhash != GIT_REV_ZERO)
	{
		CString cmdout, cmderr;
		cmd.Format(_T("git.exe log -n1 --pretty=format:\"%%ct %%s\" %s --"), (LPCTSTR)newhash);
		newOK = !subgit.Run(cmd, &cmdout, &cmderr, encode);
		if (newOK)
		{
			int pos = cmdout.Find(_T(" "));
			newTime = _ttoi(cmdout.Left(pos));
			newsub = cmdout.Mid(pos + 1);
		}
		else
			newsub = cmderr;
	}

	if (oldhash == GIT_REV_ZERO)
	{
		oldOK = true;
		changeType = NewSubmodule;
	}
	else if (newhash == GIT_REV_ZERO)
	{
		newOK = true;
		changeType = DeleteSubmodule;
	}
	else if (oldhash != newhash)
	{
		bool ffNewer = false, ffOlder = false;
		ffNewer = subgit.IsFastForward(oldhash, newhash);
		if (!ffNewer)
		{
			ffOlder = subgit.IsFastForward(newhash, oldhash);
			if (!ffOlder)
			{
				if (newTime > oldTime)
					changeType = NewerTime;
				else if (newTime < oldTime)
					changeType = OlderTime;
				else
					changeType = SameTime;
			}
			else
				changeType = Rewind;
		}
		else
			changeType = FastForward;
	}
	else if (oldhash == newhash)
		changeType = Identical;

	if (!oldOK || !newOK)
		changeType = Unknown;
}
示例#22
0
int CGitDiff::SubmoduleDiff(CTGitPath * pPath,CTGitPath * /*pPath2*/, git_revnum_t rev1, git_revnum_t rev2, bool /*blame*/, bool /*unified*/)
{
	CString oldhash;
	CString newhash;
	CString cmd;
	bool isWorkingCopy = false;
	if( rev2 == GIT_REV_ZERO || rev1 == GIT_REV_ZERO )
	{
		oldhash = GIT_REV_ZERO;
		newhash = GIT_REV_ZERO;

		CString rev;
		if( rev2 != GIT_REV_ZERO )
			rev = rev2;
		if( rev1 != GIT_REV_ZERO )
			rev = rev1;

		isWorkingCopy = true;

		cmd.Format(_T("git.exe diff %s -- \"%s\""),
		rev,pPath->GetGitPathString());

		CString output, err;
		if (g_Git.Run(cmd, &output, &err, CP_ACP))
		{
			CMessageBox::Show(NULL, output + L"\n" + err, _T("TortoiseGit"), MB_OK|MB_ICONERROR);
			return -1;
		}
		int start =0;
		int oldstart = output.Find(_T("-Subproject commit"),start);
		if(oldstart<0)
		{
			CMessageBox::Show(NULL,_T("Subproject Diff Format error") ,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
			return -1;
		}
		oldhash = output.Mid(oldstart+ CString(_T("-Subproject commit")).GetLength()+1,40);
		start = 0;
		int newstart = output.Find(_T("+Subproject commit"),start);
		if(oldstart<0)
		{
			CMessageBox::Show(NULL,_T("Subproject Diff Format error") ,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
			return -1;
		}
		newhash = output.Mid(newstart+ CString(_T("+Subproject commit")).GetLength()+1,40);

	}
	else
	{
		cmd.Format(_T("git.exe diff-tree -r -z %s %s -- \"%s\""),
		rev2,rev1,pPath->GetGitPathString());

		BYTE_VECTOR bytes, errBytes;
		if(g_Git.Run(cmd, &bytes, &errBytes))
		{
			CString err;
			g_Git.StringAppend(&err,&errBytes[0],CP_ACP);
			CMessageBox::Show(NULL,err,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
			return -1;
		}

		g_Git.StringAppend(&oldhash,&bytes[15],CP_ACP,40);
		g_Git.StringAppend(&newhash,&bytes[15+41],CP_ACP,40);

	}

	CString oldsub;
	CString newsub;

	CGit subgit;
	subgit.m_CurrentDir=g_Git.m_CurrentDir+_T("\\")+pPath->GetWinPathString();

	if(pPath->HasAdminDir())
	{
		int encode=CAppUtils::GetLogOutputEncode(&subgit);

		if(oldhash != GIT_REV_ZERO)
		{
			cmd.Format(_T("git log -n1  --pretty=format:\"%%s\" %s"),oldhash);
			subgit.Run(cmd,&oldsub,encode);
		}
		if(newsub != GIT_REV_ZERO)
		{
			cmd.Format(_T("git log -n1  --pretty=format:\"%%s\" %s"),newhash);
			subgit.Run(cmd,&newsub,encode);
		}
	}

	CSubmoduleDiffDlg submoduleDiffDlg;
	submoduleDiffDlg.SetDiff(pPath->GetWinPath(), isWorkingCopy, oldhash, oldsub, newhash, newsub);
	submoduleDiffDlg.DoModal();

	return 0;
}
示例#23
0
CString CGit::GetGitGlobalXDGConfig()
{
	return g_Git.GetGitGlobalXDGConfigPath() + _T("\\config");
}
示例#24
0
CString CGit::GetGitGlobalXDGConfigPath()
{
	return g_Git.GetHomeDirectory() + _T("\\.config\\git");
}
示例#25
0
int CGitDiff::SubmoduleDiffNull(const CTGitPath * pPath, const git_revnum_t &rev1)
{
	CString oldhash = GIT_REV_ZERO;
	CString oldsub ;
	CString newsub;
	CString newhash;

	CString cmd;
	if (rev1 != GIT_REV_ZERO)
		cmd.Format(L"git.exe ls-tree \"%s\" -- \"%s\"", (LPCTSTR)rev1, (LPCTSTR)pPath->GetGitPathString());
	else
		cmd.Format(L"git.exe ls-files -s -- \"%s\"", (LPCTSTR)pPath->GetGitPathString());

	CString output, err;
	if (g_Git.Run(cmd, &output, &err, CP_UTF8))
	{
		CMessageBox::Show(nullptr, output + L'\n' + err, L"TortoiseGit", MB_OK | MB_ICONERROR);
		return -1;
	}

	int start = output.Find(L' ');
	if(start>0)
	{
		if (rev1 != GIT_REV_ZERO) // in ls-files the hash is in the second column; in ls-tree it's in the third one
			start = output.Find(L' ', start + 1);
		if(start>0)
			newhash=output.Mid(start+1, 40);

		CGit subgit;
		subgit.m_CurrentDir = g_Git.CombinePath(pPath);
		int encode=CAppUtils::GetLogOutputEncode(&subgit);

		cmd.Format(L"git.exe log -n1 --pretty=format:\"%%s\" %s --", (LPCTSTR)newhash);
		bool toOK = !subgit.Run(cmd,&newsub,encode);

		bool dirty = false;
		if (rev1 == GIT_REV_ZERO && !(pPath->m_Action & CTGitPath::LOGACTIONS_DELETED))
		{
			CString dirtyList;
			subgit.Run(L"git.exe status --porcelain", &dirtyList, encode);
			dirty = !dirtyList.IsEmpty();
		}

		CSubmoduleDiffDlg submoduleDiffDlg;
		if (pPath->m_Action & CTGitPath::LOGACTIONS_DELETED)
			submoduleDiffDlg.SetDiff(pPath->GetWinPath(), false, newhash, newsub, toOK, oldhash, oldsub, false, dirty, DeleteSubmodule);
		else
			submoduleDiffDlg.SetDiff(pPath->GetWinPath(), false, oldhash, oldsub, true, newhash, newsub, toOK, dirty, NewSubmodule);
		submoduleDiffDlg.DoModal();
		if (submoduleDiffDlg.IsRefresh())
			return 1;

		return 0;
	}

	if (rev1 != GIT_REV_ZERO)
		CMessageBox::Show(nullptr, L"ls-tree output format error", L"TortoiseGit", MB_OK | MB_ICONERROR);
	else
		CMessageBox::Show(nullptr, L"ls-files output format error", L"TortoiseGit", MB_OK | MB_ICONERROR);
	return -1;
}
示例#26
0
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;
}