CTGitPath CTempFiles::GetTempFilePath(bool bRemoveAtEnd, const CTGitPath& path /* = CTGitPath() */, const GitRev revision /* = GitRev() */) { DWORD len = ::GetTempPath(0, NULL); TCHAR * temppath = new TCHAR[len+1]; TCHAR * tempF = new TCHAR[len+50]; ::GetTempPath (len+1, temppath); CTGitPath tempfile; CString possibletempfile; if (path.IsEmpty()) { ::GetTempFileName (temppath, TEXT("git"), 0, tempF); tempfile = CTGitPath(tempF); } else { int i=0; do { if (!((GitRev&)revision).m_CommitHash.IsEmpty()) { possibletempfile.Format(_T("%s%s-rev%s.git%3.3x.tmp%s"), temppath, (LPCTSTR)path.GetFileOrDirectoryName(), (LPCTSTR)((GitRev&)revision).m_CommitHash.ToString().Left(7), i, (LPCTSTR)path.GetFileExtension()); } else { possibletempfile.Format(_T("%s%s.git%3.3x.tmp%s"), temppath, (LPCTSTR)path.GetFileOrDirectoryName(), i, (LPCTSTR)path.GetFileExtension()); } tempfile.SetFromWin(possibletempfile); i++; } while (PathFileExists(tempfile.GetWinPath())); } //now create the temp file, so that subsequent calls to GetTempFile() return //different filenames. HANDLE hFile = CreateFile(tempfile.GetWinPath(), GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL); CloseHandle(hFile); delete [] temppath; delete [] tempF; if (bRemoveAtEnd) m_TempFileList.AddPath(tempfile); return tempfile; }
int CGitDiff::Diff(const CTGitPath * pPath, const CTGitPath * pPath2, git_revnum_t rev1, git_revnum_t rev2, bool /*blame*/, bool /*unified*/, int jumpToLine) { CString temppath; GetTempPath(temppath); // make sure we have HASHes here, otherwise filenames might be invalid if (rev1 != GIT_REV_ZERO) { CGitHash rev1Hash; if (g_Git.GetHash(rev1Hash, rev1)) { MessageBox(NULL, g_Git.GetGitLastErr(_T("Could not get hash of \"") + rev1 + _T("\".")), _T("TortoiseGit"), MB_ICONERROR); return -1; } rev1 = rev1Hash.ToString(); } if (rev2 != GIT_REV_ZERO) { CGitHash rev2Hash; if (g_Git.GetHash(rev2Hash, rev2)) { MessageBox(NULL, g_Git.GetGitLastErr(_T("Could not get hash of \"") + rev2 + _T("\".")), _T("TortoiseGit"), MB_ICONERROR); return -1; } rev2 = rev2Hash.ToString(); } CString file1; CString title1; CString cmd; if(pPath->IsDirectory() || pPath2->IsDirectory()) { int result; // refresh if result = 1 CTGitPath path = *pPath; CTGitPath path2 = *pPath2; while ((result = SubmoduleDiff(&path, &path2, rev1, rev2)) == 1) { path.SetFromGit(pPath->GetGitPathString()); path2.SetFromGit(pPath2->GetGitPathString()); } return result; } if(rev1 != GIT_REV_ZERO ) { TCHAR szTempName[MAX_PATH] = {0}; GetTempFileName(temppath, pPath->GetBaseFilename(), 0, szTempName); CString temp(szTempName); DeleteFile(szTempName); CreateDirectory(szTempName, NULL); // use original file extension, an external diff tool might need it file1.Format(_T("%s\\%s-%s-right%s"), temp, pPath->GetBaseFilename(), rev1.Left(g_Git.GetShortHASHLength()), pPath->GetFileExtension()); title1 = pPath->GetFileOrDirectoryName() + _T(":") + rev1.Left(g_Git.GetShortHASHLength()); g_Git.GetOneFile(rev1,*pPath,file1); ::SetFileAttributes(file1, FILE_ATTRIBUTE_READONLY); } else { file1=g_Git.m_CurrentDir+_T("\\")+pPath->GetWinPathString(); title1.Format( IDS_DIFF_WCNAME, pPath->GetFileOrDirectoryName() ); if (!PathFileExists(file1)) { CString sMsg; sMsg.Format(IDS_PROC_DIFFERROR_FILENOTINWORKINGTREE, file1); if (MessageBox(NULL, sMsg, _T("TortoiseGit"), MB_ICONEXCLAMATION | MB_YESNO) == IDNO) return 1; if (!CCommonAppUtils::FileOpenSave(file1, NULL, IDS_DIFF_WCNAME, IDS_COMMONFILEFILTER, true)) return 1; title1.Format(IDS_DIFF_WCNAME, CTGitPath(file1).GetUIFileOrDirectoryName()); } } CString file2; CString title2; if(rev2 != GIT_REV_ZERO) { TCHAR szTempName[MAX_PATH] = {0}; GetTempFileName(temppath, pPath2->GetBaseFilename(), 0, szTempName); CString temp(szTempName); DeleteFile(szTempName); CreateDirectory(szTempName, NULL); CTGitPath fileName = *pPath2; if (pPath2->m_Action & CTGitPath::LOGACTIONS_REPLACED) fileName = CTGitPath(pPath2->GetGitOldPathString()); // use original file extension, an external diff tool might need it file2.Format(_T("%s\\%s-%s-left%s"), temp, fileName.GetBaseFilename(), rev2.Left(g_Git.GetShortHASHLength()), fileName.GetFileExtension()); title2 = fileName.GetFileOrDirectoryName() + _T(":") + rev2.Left(g_Git.GetShortHASHLength()); g_Git.GetOneFile(rev2, fileName, file2); ::SetFileAttributes(file2, FILE_ATTRIBUTE_READONLY); } else { file2=g_Git.m_CurrentDir+_T("\\")+pPath2->GetWinPathString(); title2.Format( IDS_DIFF_WCNAME, pPath2->GetFileOrDirectoryName() ); } if (pPath->m_Action == pPath->LOGACTIONS_ADDED) { CGitDiff::DiffNull(pPath, rev1, true, jumpToLine); } else if (pPath->m_Action == pPath->LOGACTIONS_DELETED) { CGitDiff::DiffNull(pPath, rev2, false, jumpToLine); } else { CAppUtils::DiffFlags flags; CAppUtils::StartExtDiff(file2,file1, title2, title1, g_Git.m_CurrentDir + _T("\\") + pPath2->GetWinPathString(), g_Git.m_CurrentDir + _T("\\") + pPath->GetWinPathString(), rev2, rev1, flags, jumpToLine); } return 0; }
int CGitDiff::Diff(CTGitPath * pPath,CTGitPath * pPath2, git_revnum_t rev1, git_revnum_t rev2, bool /*blame*/, bool /*unified*/) { CString temppath; GetTempPath(temppath); Parser(rev1); Parser(rev2); CString file1; CString title1; CString cmd; if(pPath->IsDirectory() || pPath2->IsDirectory()) { return SubmoduleDiff(pPath,pPath2,rev1,rev2); } if(rev1 != GIT_REV_ZERO ) { TCHAR szTempName[MAX_PATH]; GetTempFileName(temppath, pPath->GetBaseFilename(), 0, szTempName); CString temp(szTempName); DeleteFile(szTempName); CreateDirectory(szTempName, NULL); // use original file extension, an external diff tool might need it file1.Format(_T("%s\\%s-%s-right%s"), temp, pPath->GetBaseFilename(), rev1.Left(6), pPath->GetFileExtension()); title1 = pPath->GetFileOrDirectoryName()+_T(":")+rev1.Left(6); g_Git.GetOneFile(rev1,*pPath,file1); ::SetFileAttributes(file1, FILE_ATTRIBUTE_READONLY); } else { file1=g_Git.m_CurrentDir+_T("\\")+pPath->GetWinPathString(); title1.Format( IDS_DIFF_WCNAME, pPath->GetFileOrDirectoryName() ); } CString file2; CString title2; if(rev2 != GIT_REV_ZERO) { TCHAR szTempName[MAX_PATH]; GetTempFileName(temppath, pPath2->GetBaseFilename(), 0, szTempName); CString temp(szTempName); DeleteFile(szTempName); CreateDirectory(szTempName, NULL); CTGitPath fileName = *pPath2; if (rev1 == GIT_REV_ZERO && pPath2->m_Action & CTGitPath::LOGACTIONS_REPLACED) fileName = CTGitPath(pPath2->GetGitOldPathString()); // use original file extension, an external diff tool might need it file2.Format(_T("%s\\%s-%s-left%s"), temp, fileName.GetBaseFilename(), rev2.Left(6), fileName.GetFileExtension()); title2 = fileName.GetFileOrDirectoryName() + _T(":") + rev2.Left(6); g_Git.GetOneFile(rev2, fileName, file2); ::SetFileAttributes(file2, FILE_ATTRIBUTE_READONLY); } else { file2=g_Git.m_CurrentDir+_T("\\")+pPath2->GetWinPathString(); title2.Format( IDS_DIFF_WCNAME, pPath2->GetFileOrDirectoryName() ); } if (pPath->m_Action == pPath->LOGACTIONS_ADDED) { CGitDiff::DiffNull(pPath, rev1, true); } else if (pPath->m_Action == pPath->LOGACTIONS_DELETED) { CGitDiff::DiffNull(pPath, rev2, false); } else { CAppUtils::DiffFlags flags; CAppUtils::StartExtDiff(file2,file1, title2, title1 ,flags); } return 0; }