Fixed issue #440: Don't enable 'Apply' button until the data are ok in Settings/Git...
[TortoiseGit.git] / src / TortoiseProc / GitDiff.cpp
blob7214435bfc11e698fac51c42ed27d53c11f0ac3a
1 #include "StdAfx.h"
2 #include "GitDiff.h"
3 #include "AppUtils.h"
4 #include "git.h"
5 #include "gittype.h"
6 #include "resource.h"
7 #include "MessageBox.h"
8 #include "FileDiffDlg.h"
10 CGitDiff::CGitDiff(void)
14 CGitDiff::~CGitDiff(void)
17 int CGitDiff::Parser(git_revnum_t &rev)
19 if(rev == GIT_REV_ZERO)
20 return 0;
21 if(rev.GetLength() > 40)
23 CString cmd;
24 cmd.Format(_T("git.exe rev-parse %s"),rev);
25 CString output;
26 if(!g_Git.Run(cmd,&output,CP_UTF8))
28 //int start=output.Find(_T('\n'));
29 rev=output.Left(40);
32 return 0;
34 int CGitDiff::DiffNull(CTGitPath *pPath, git_revnum_t &rev1,bool bIsAdd)
36 CString temppath;
37 GetTempPath(temppath);
38 Parser(rev1);
39 CString file1;
40 CString nullfile;
41 CString cmd;
42 if(rev1 != GIT_REV_ZERO )
44 file1.Format(_T("%s%s_%s%s"),
45 temppath,
46 pPath->GetBaseFilename(),
47 rev1.Left(6),
48 pPath->GetFileExtension());
49 cmd.Format(_T("git.exe cat-file -p %s:\"%s\""),rev1,pPath->GetGitPathString());
50 g_Git.RunLogFile(cmd,file1);
51 }else
53 file1=g_Git.m_CurrentDir+_T("\\")+pPath->GetWinPathString();
56 CString tempfile=::GetTempFile();
57 CStdioFile file(tempfile,CFile::modeReadWrite|CFile::modeCreate );
58 //file.WriteString();
59 file.Close();
61 CAppUtils::DiffFlags flags;
63 if(bIsAdd)
64 CAppUtils::StartExtDiff(tempfile,file1,
65 _T("NULL"),
66 pPath->GetGitPathString()+_T(":")+rev1.Left(6)
67 ,flags);
68 else
69 CAppUtils::StartExtDiff(file1,tempfile,
70 pPath->GetGitPathString()+_T(":")+rev1.Left(6)
71 ,_T("NULL"),flags);
73 return 0;
76 int CGitDiff::SubmoduleDiff(CTGitPath * pPath,CTGitPath * pPath2, git_revnum_t & rev1, git_revnum_t & rev2, bool /*blame*/, bool /*unified*/)
78 CString oldhash;
79 CString newhash;
80 CString cmd,err;
81 CString workingcopy;
83 if( rev2 == GIT_REV_ZERO || rev1 == GIT_REV_ZERO )
85 oldhash = GIT_REV_ZERO;
86 newhash = GIT_REV_ZERO;
88 CString rev;
89 if( rev2 != GIT_REV_ZERO )
90 rev = rev2;
91 if( rev1 != GIT_REV_ZERO )
92 rev = rev1;
94 workingcopy = _T("(Work Copy)");
96 cmd.Format(_T("git.exe diff %s -- \"%s\""),
97 rev,pPath->GetGitPathString());
99 CString output;
100 if(g_Git.Run(cmd,&output,CP_ACP))
102 CMessageBox::Show(NULL,output,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
103 return -1;
105 int start =0;
106 int oldstart = output.Find(_T("-Subproject commit"),start);
107 if(oldstart<0)
109 CMessageBox::Show(NULL,_T("Subproject Diff Format error") ,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
110 return -1;
112 oldhash = output.Mid(oldstart+ CString(_T("-Subproject commit")).GetLength()+1,40);
113 start = 0;
114 int newstart = output.Find(_T("+Subproject commit"),start);
115 if(oldstart<0)
117 CMessageBox::Show(NULL,_T("Subproject Diff Format error") ,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
118 return -1;
120 newhash = output.Mid(newstart+ CString(_T("+Subproject commit")).GetLength()+1,40);
122 }else
124 cmd.Format(_T("git.exe diff-tree -r -z %s %s -- \"%s\""),
125 rev2,rev1,pPath->GetGitPathString());
127 BYTE_VECTOR bytes;
128 if(g_Git.Run(cmd,&bytes))
130 CString err;
131 g_Git.StringAppend(&err,&bytes[0],CP_ACP);
132 CMessageBox::Show(NULL,err,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
133 return -1;
136 g_Git.StringAppend(&oldhash,&bytes[15],CP_ACP,40);
137 g_Git.StringAppend(&newhash,&bytes[15+41],CP_ACP,40);
141 CString oldsub;
142 CString newsub;
144 CGit subgit;
145 subgit.m_CurrentDir=g_Git.m_CurrentDir+_T("\\")+pPath->GetWinPathString();
147 if(pPath->HasAdminDir())
149 int encode=CAppUtils::GetLogOutputEncode(&subgit);
151 if(oldhash != GIT_REV_ZERO)
153 cmd.Format(_T("git log -n1 --pretty=format:\"%%s\" %s"),oldhash);
154 subgit.Run(cmd,&oldsub,encode);
156 if(newsub != GIT_REV_ZERO)
158 cmd.Format(_T("git log -n1 --pretty=format:\"%%s\" %s"),newhash);
159 subgit.Run(cmd,&newsub,encode);
162 CString msg;
163 msg.Format(_T("Submodule <b>%s</b> Change\r\n\r\n<b>From:</b> %s\r\n\t%s\r\n\r\n<b>To%s:</b> %s\r\n\t\t%s"),
164 pPath->GetWinPath(),
165 oldhash,
166 oldsub ,
167 workingcopy,
168 newhash,
169 newsub);
170 CMessageBox::Show(NULL,msg,_T("TortoiseGit"),MB_OK);
172 return 0;
175 int CGitDiff::Diff(CTGitPath * pPath,CTGitPath * pPath2, git_revnum_t & rev1, git_revnum_t & rev2, bool /*blame*/, bool /*unified*/)
177 CString temppath;
178 GetTempPath(temppath);
179 Parser(rev1);
180 Parser(rev2);
181 CString file1;
182 CString title1;
183 CString cmd;
185 if(pPath->IsDirectory() || pPath2->IsDirectory())
187 return SubmoduleDiff(pPath,pPath2,rev1,rev2);
190 if(rev1 != GIT_REV_ZERO )
192 file1.Format(_T("%s%s_%s%s"),
193 temppath,
194 pPath->GetBaseFilename(),
195 rev1.Left(6),
196 pPath->GetFileExtension());
197 title1 = pPath->GetFileOrDirectoryName()+_T(":")+rev1.Left(6);
198 cmd.Format(_T("git.exe cat-file -p %s:\"%s\""),rev1,pPath->GetGitPathString());
199 g_Git.RunLogFile(cmd,file1);
200 }else
202 file1=g_Git.m_CurrentDir+_T("\\")+pPath->GetWinPathString();
203 title1.Format( IDS_DIFF_WCNAME, pPath->GetFileOrDirectoryName() );
206 CString file2;
207 CString title2;
208 if(rev2 != GIT_REV_ZERO)
211 file2.Format(_T("%s%s_%s%s"),
212 temppath,
213 pPath2->GetBaseFilename(),
214 rev2.Left(6),
215 pPath2->GetFileExtension());
216 title2 = pPath2->GetFileOrDirectoryName()+_T(":")+rev2.Left(6);
217 cmd.Format(_T("git.exe cat-file -p %s:\"%s\""),rev2,pPath2->GetGitPathString());
218 g_Git.RunLogFile(cmd,file2);
219 }else
221 file2=g_Git.m_CurrentDir+_T("\\")+pPath2->GetWinPathString();
222 title2.Format( IDS_DIFF_WCNAME, pPath2->GetFileOrDirectoryName() );
225 CAppUtils::DiffFlags flags;
226 CAppUtils::StartExtDiff(file2,file1,
227 title2,
228 title1
229 ,flags);
231 return 0;
234 int CGitDiff::DiffCommit(CTGitPath &path, GitRev *r1, GitRev *r2)
236 if( path.GetWinPathString().IsEmpty() || path.IsDirectory() )
238 CFileDiffDlg dlg;
239 dlg.SetDiff(NULL,*r1,*r2);
240 dlg.DoModal();
241 }else
243 Diff(&path,&path,r1->m_CommitHash.ToString(),r2->m_CommitHash.ToString());
245 return 0;
248 int CGitDiff::DiffCommit(CTGitPath &path, CString &r1, CString &r2)
250 if( path.GetWinPathString().IsEmpty() || path.IsDirectory() )
252 CFileDiffDlg dlg;
253 dlg.SetDiff(NULL,r1,r2);
254 dlg.DoModal();
255 }else
257 Diff(&path,&path,r1,r2);
259 return 0;