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.
21 #include "DiffCommand.h"
22 #include "PathUtils.h"
24 #include "ChangedDlg.h"
26 #include "GitStatus.h"
27 #include "../TGitCache/CacheInterface.h"
28 #include "../Utils/UnicodeUtils.h"
30 bool DiffCommand::Execute()
33 CString path2
= CPathUtils::GetLongPathname(parser
.GetVal(_T("path2")));
34 bool bAlternativeTool
= !!parser
.HasKey(_T("alternative"));
35 // bool bBlame = !!parser.HasKey(_T("blame"));
38 if (this->orgCmdLinePath
.IsDirectory())
41 dlg
.m_pathList
= CTGitPathList(cmdLinePath
);
47 if (cmdLinePath
.IsEmpty())
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"))));
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")));
60 // check if it is a newly added (but uncommitted) file
61 git_wc_status_kind status
= git_wc_status_none
;
63 if (orgCmdLinePath
.HasAdminDir(&topDir
))
65 CBlockCacheForPath
cacheBlock(topDir
);
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);
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
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")));
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
));
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")));
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")));
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")));