Example #1
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;
}
Example #2
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;
}