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 { CGitDiff diff; //diff.SetAlternativeTool(bAlternativeTool); if ( parser.HasKey(_T("startrev")) && parser.HasKey(_T("endrev")) ) { bRet = !!diff.Diff(&cmdLinePath,&cmdLinePath,git_revnum_t(parser.GetVal(_T("startrev"))),git_revnum_t(parser.GetVal(_T("endrev")))); } 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)) GitStatus::GetFileStatus(topDir, cmdLinePath.GetWinPathString(), &status, true); if (status == git_wc_status_added) cmdLinePath.m_Action = cmdLinePath.LOGACTIONS_ADDED; bRet = !!diff.Diff(&cmdLinePath,&cmdLinePath,git_revnum_t(GIT_REV_ZERO),git_revnum_t(_T("HEAD"))); } } } 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)); return bRet; }
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 (cmdLinePath.IsDirectory()) { CChangedDlg dlg; dlg.m_pathList = CTGitPathList(cmdLinePath); dlg.DoModal(); bRet = true; } else { CGitDiff diff; //diff.SetAlternativeTool(bAlternativeTool); #if 0 if ( parser.HasKey(_T("startrev")) && parser.HasKey(_T("endrev")) ) { //SVNRev StartRevision = SVNRev(parser.GetLongVal(_T("startrev"))); //SVNRev EndRevision = SVNRev(parser.GetLongVal(_T("endrev"))); //bRet = diff.ShowCompare(cmdLinePath, StartRevision, cmdLinePath, EndRevision, SVNRev(), false, bBlame); } else #endif { //git_revnum_t baseRev = 0; bRet = diff.Diff(&cmdLinePath,&cmdLinePath,git_revnum_t(GIT_REV_ZERO),git_revnum_t(_T("HEAD"))); } } } else bRet = CAppUtils::StartExtDiff( path2, orgCmdLinePath.GetWinPathString(), CString(), CString(), CAppUtils::DiffFlags().AlternativeTool(bAlternativeTool)); return bRet; }
int CGitDiff::DiffNull(const CTGitPath *pPath, git_revnum_t rev1, bool bIsAdd, int jumpToLine) { CString temppath; GetTempPath(temppath); if (rev1 != GIT_REV_ZERO) { CGitHash rev1Hash; if (g_Git.GetHash(rev1Hash, rev1)) // make sure we have a HASH here, otherwise filenames might be invalid { MessageBox(NULL, g_Git.GetGitLastErr(_T("Could not get hash of \"") + rev1 + _T("\".")), _T("TortoiseGit"), MB_ICONERROR); return -1; } rev1 = rev1Hash.ToString(); } CString file1; CString nullfile; CString cmd; if(pPath->IsDirectory()) { int result; // refresh if result = 1 CTGitPath path = *pPath; while ((result = SubmoduleDiffNull(&path, rev1)) == 1) { path.SetFromGit(pPath->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); file1.Format(_T("%s\\%s-%s%s"), temp, pPath->GetBaseFilename(), rev1.Left(g_Git.GetShortHASHLength()), pPath->GetFileExtension()); g_Git.GetOneFile(rev1,*pPath,file1); } else { file1=g_Git.m_CurrentDir+_T("\\")+pPath->GetWinPathString(); } // preserve FileExtension, needed especially for diffing deleted images (detection on new filename extension) CString tempfile=::GetTempFile() + pPath->GetFileExtension(); CStdioFile file(tempfile,CFile::modeReadWrite|CFile::modeCreate ); //file.WriteString(); file.Close(); ::SetFileAttributes(tempfile, FILE_ATTRIBUTE_READONLY); CAppUtils::DiffFlags flags; if(bIsAdd) CAppUtils::StartExtDiff(tempfile,file1, pPath->GetGitPathString(), pPath->GetGitPathString() + _T(":") + rev1.Left(g_Git.GetShortHASHLength()), g_Git.m_CurrentDir + _T("\\") + pPath->GetWinPathString(), g_Git.m_CurrentDir + _T("\\") + pPath->GetWinPathString(), git_revnum_t(GIT_REV_ZERO), rev1 , flags, jumpToLine); else CAppUtils::StartExtDiff(file1,tempfile, pPath->GetGitPathString() + _T(":") + rev1.Left(g_Git.GetShortHASHLength()), pPath->GetGitPathString(), g_Git.m_CurrentDir + _T("\\") + pPath->GetWinPathString(), g_Git.m_CurrentDir + _T("\\") + pPath->GetWinPathString(), rev1, git_revnum_t(GIT_REV_ZERO) , flags, jumpToLine); return 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; }
int CGitDiff::DiffNull(const CTGitPath *pPath, git_revnum_t rev1, bool bIsAdd, int jumpToLine, bool bAlternative) { if (rev1 != GIT_REV_ZERO) { CGitHash rev1Hash; if (g_Git.GetHash(rev1Hash, rev1)) // make sure we have a HASH here, otherwise filenames might be invalid { MessageBox(nullptr, g_Git.GetGitLastErr(L"Could not get hash of \"" + rev1 + L"\"."), L"TortoiseGit", MB_ICONERROR); return -1; } rev1 = rev1Hash.ToString(); } CString file1; CString nullfile; CString cmd; if(pPath->IsDirectory()) { int result; // refresh if result = 1 CTGitPath path = *pPath; while ((result = SubmoduleDiffNull(&path, rev1)) == 1) path.SetFromGit(pPath->GetGitPathString()); return result; } if(rev1 != GIT_REV_ZERO ) { file1 = CTempFiles::Instance().GetTempFilePath(false, *pPath, rev1).GetWinPathString(); if (g_Git.GetOneFile(rev1, *pPath, file1)) { CString out; out.Format(IDS_STATUSLIST_CHECKOUTFILEFAILED, (LPCTSTR)pPath->GetGitPathString(), (LPCTSTR)rev1, (LPCTSTR)file1); CMessageBox::Show(nullptr, g_Git.GetGitLastErr(out, CGit::GIT_CMD_GETONEFILE), L"TortoiseGit", MB_OK); return -1; } ::SetFileAttributes(file1, FILE_ATTRIBUTE_READONLY); } else file1 = g_Git.CombinePath(pPath); CString tempfile = CTempFiles::Instance().GetTempFilePath(false, *pPath, rev1).GetWinPathString(); ::SetFileAttributes(tempfile, FILE_ATTRIBUTE_READONLY); CAppUtils::DiffFlags flags; flags.bAlternativeTool = bAlternative; if(bIsAdd) CAppUtils::StartExtDiff(tempfile,file1, pPath->GetGitPathString(), pPath->GetGitPathString() + L':' + rev1.Left(g_Git.GetShortHASHLength()), g_Git.CombinePath(pPath), g_Git.CombinePath(pPath), git_revnum_t(GIT_REV_ZERO), rev1 , flags, jumpToLine); else CAppUtils::StartExtDiff(file1,tempfile, pPath->GetGitPathString() + L':' + rev1.Left(g_Git.GetShortHASHLength()), pPath->GetGitPathString(), g_Git.CombinePath(pPath), g_Git.CombinePath(pPath), rev1, git_revnum_t(GIT_REV_ZERO) , flags, jumpToLine); return 0; }