Do not use GitAdminDir objects
[TortoiseGit.git] / src / TortoiseProc / Commands / DiffCommand.cpp
blobe7978a8d766cbc36a1013e66aa1dc44ae4f93465
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2007-2008 - TortoiseSVN
4 // Copyright (C) 2007-2011, 2013-2015 - TortoiseGit
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
21 #include "DiffCommand.h"
22 #include "PathUtils.h"
23 #include "AppUtils.h"
24 #include "ChangedDlg.h"
25 #include "GitDiff.h"
26 #include "GitStatus.h"
27 #include "../TGitCache/CacheInterface.h"
28 #include "../Utils/UnicodeUtils.h"
30 bool DiffCommand::Execute()
32 bool bRet = false;
33 CString path2 = CPathUtils::GetLongPathname(parser.GetVal(_T("path2")));
34 bool bAlternativeTool = !!parser.HasKey(_T("alternative"));
35 // bool bBlame = !!parser.HasKey(_T("blame"));
36 if (path2.IsEmpty())
38 if (this->orgCmdLinePath.IsDirectory())
40 CChangedDlg dlg;
41 dlg.m_pathList = CTGitPathList(cmdLinePath);
42 dlg.DoModal();
43 bRet = true;
45 else
47 if (cmdLinePath.IsEmpty())
48 return false;
49 CGitDiff diff;
50 //diff.SetAlternativeTool(bAlternativeTool);
51 if ( parser.HasKey(_T("startrev")) && parser.HasKey(_T("endrev")) )
53 if (parser.HasKey(_T("unified")))
54 bRet = !!CAppUtils::StartShowUnifiedDiff(nullptr, cmdLinePath, git_revnum_t(parser.GetVal(_T("endrev"))), cmdLinePath, git_revnum_t(parser.GetVal(_T("startrev"))));
55 else
56 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")));
58 else
60 // check if it is a newly added (but uncommitted) file
61 git_wc_status_kind status = git_wc_status_none;
62 CString topDir;
63 if (orgCmdLinePath.HasAdminDir(&topDir))
65 CBlockCacheForPath cacheBlock(topDir);
66 CAutoIndex index;
67 CString adminDir;
68 GitAdminDir::GetAdminDirPath(topDir, adminDir);
69 if (!git_index_open(index.GetPointer(), CUnicodeUtils::GetUTF8(adminDir + _T("index"))))
70 g_Git.Run(_T("git.exe update-index -- \"") + cmdLinePath.GetGitPathString() + _T("\""), nullptr); // make sure we get the right status
71 GitStatus::GetFileStatus(topDir, cmdLinePath.GetWinPathString(), &status, true);
72 if (index)
73 git_index_write(index);
75 if (status == git_wc_status_added)
77 if (!g_Git.IsInitRepos())
79 // this might be a rename, try to find original name
80 BYTE_VECTOR cmdout;
81 g_Git.Run(_T("git.exe diff-index --raw HEAD -M -C -z --"), &cmdout);
82 CTGitPathList changedFiles;
83 changedFiles.ParserFromLog(cmdout);
84 for (int i = 0; i < changedFiles.GetCount(); ++i)
86 if (changedFiles[i].GetGitPathString() == cmdLinePath.GetGitPathString())
88 if (!changedFiles[i].GetGitOldPathString().IsEmpty())
90 CTGitPath oldPath(changedFiles[i].GetGitOldPathString());
91 if (parser.HasKey(_T("unified")))
92 return !!CAppUtils::StartShowUnifiedDiff(nullptr, cmdLinePath, git_revnum_t(_T("HEAD")), cmdLinePath, git_revnum_t(GIT_REV_ZERO));
93 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")));
95 break;
99 cmdLinePath.m_Action = cmdLinePath.LOGACTIONS_ADDED;
102 if (parser.HasKey(_T("unified")))
103 bRet = !!CAppUtils::StartShowUnifiedDiff(nullptr, cmdLinePath, git_revnum_t(_T("HEAD")), cmdLinePath, git_revnum_t(GIT_REV_ZERO));
104 else
105 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")));
109 else
111 CGitDiff diff;
112 if ( parser.HasKey(_T("startrev")) && parser.HasKey(_T("endrev")) && path2.Left(g_Git.m_CurrentDir.GetLength() + 1) == g_Git.m_CurrentDir + _T("\\"))
114 CTGitPath tgitPath2 = path2.Mid(g_Git.m_CurrentDir.GetLength() + 1);
115 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")));
117 else
119 bRet = CAppUtils::StartExtDiff(
120 path2, orgCmdLinePath.GetWinPathString(), CString(), CString(),
121 CString(), CString(), git_revnum_t(GIT_REV_ZERO), git_revnum_t(GIT_REV_ZERO),
122 CAppUtils::DiffFlags().AlternativeTool(bAlternativeTool), parser.GetLongVal(_T("line")));
126 return bRet;