Change Log Code structure Unfinished
[TortoiseGit.git] / src / Git / GitRev.cpp
blob145dbe9bf0df7fdfe6d0f5725d87546c2d033ccc
1 #include "StdAfx.h"
2 #include "ATLComTime.h"
3 #include "GitRev.h"
4 #include "Git.h"
5 #include "GitDLL.h"
7 class CException; //Just in case afx.h is not included (cannot be included in every project which uses this file)
9 // provide an ASSERT macro for when compiled without MFC
10 #if !defined ASSERT
11 // Don't use _asm here, it isn't supported by x64 version of compiler. In fact, MFC's ASSERT() is the same with _ASSERTE().
12 #define ASSERT(x) _ASSERTE(x)
13 #endif
16 GitRev::GitRev(void)
18 m_Action=0;
19 m_IsFull = 0;
20 m_IsUpdateing = 0;
21 // fetch local machine timezone info
22 if ( GetTimeZoneInformation( &m_TimeZone ) == TIME_ZONE_ID_INVALID )
24 ASSERT(false);
28 GitRev::~GitRev(void)
32 #if 0
33 GitRev::GitRev(GitRev & rev)
36 GitRev& GitRev::operator=(GitRev &rev)
38 return *this;
40 #endif
41 void GitRev::Clear()
43 this->m_Action=0;
44 this->m_Files.Clear();
45 this->m_Action=0;
46 this->m_ParentHash.clear();
47 m_CommitterName.Empty();
48 m_CommitterEmail.Empty();
49 m_Body.Empty();
50 m_Subject.Empty();
51 m_CommitHash.Empty();
52 m_Ref.Empty();
53 m_RefAction.Empty();
54 m_Mark=0;
57 int GitRev::CopyFrom(GitRev &rev,bool OmitParentAndMark)
59 m_AuthorName =rev.m_AuthorName ;
60 m_AuthorEmail =rev.m_AuthorEmail ;
61 m_AuthorDate =rev.m_AuthorDate ;
62 m_CommitterName =rev.m_CommitterName ;
63 m_CommitterEmail=rev.m_CommitterEmail;
64 m_CommitterDate =rev.m_CommitterDate ;
65 m_Subject =rev.m_Subject ;
66 m_Body =rev.m_Body ;
67 m_CommitHash =rev.m_CommitHash ;
68 m_Files =rev.m_Files ;
69 m_Action =rev.m_Action ;
71 if(!OmitParentAndMark)
73 m_ParentHash =rev.m_ParentHash ;
74 m_Mark =rev.m_Mark;
76 return 0;
78 int GitRev::ParserFromLog(BYTE_VECTOR &log,int start)
80 int pos=start;
81 CString one;
82 CString key;
83 CString text;
84 BYTE_VECTOR filelist;
85 BYTE mode=0;
86 CTGitPath path;
87 this->m_Files.Clear();
88 m_Action=0;
89 int begintime=0;
90 int filebegin=-1;
92 while( pos < log.size() && pos>=0)
95 //one=log.Tokenize(_T("\n"),pos);
96 if(log[pos]==_T('#') && log[pos+1] == _T('<') && log[pos+3] == _T('>'))
98 //text = one.Right(one.GetLength()-4);
99 text.Empty();
100 g_Git.StringAppend(&text,&log[pos+4],CGit::m_LogEncode);
101 mode = log[pos+2];
103 switch(mode)
105 case LOG_REV_ITEM_BEGIN:
106 begintime++;
107 if(begintime>1)
108 break;
109 else
110 this->Clear();
111 break;
112 case LOG_REV_AUTHOR_NAME:
113 this->m_AuthorName = text;
114 break;
115 case LOG_REV_AUTHOR_EMAIL:
116 this->m_AuthorEmail = text;
117 break;
118 case LOG_REV_AUTHOR_DATE:
119 this->m_AuthorDate =ConverFromString(text);
120 break;
121 case LOG_REV_COMMIT_NAME:
122 this->m_CommitterName = text;
123 break;
124 case LOG_REV_COMMIT_EMAIL:
125 this->m_CommitterEmail = text;
126 break;
127 case LOG_REV_COMMIT_DATE:
128 this->m_CommitterDate =ConverFromString(text);
129 break;
130 case LOG_REV_COMMIT_SUBJECT:
131 this->m_Subject = text;
132 break;
133 case LOG_REV_COMMIT_BODY:
134 this->m_Body = text +_T("\n");
135 break;
136 case LOG_REV_COMMIT_HASH:
137 this->m_CommitHash = text.Right(40);
138 if(text.GetLength()>40)
140 this->m_Mark=text[0];
142 break;
143 case LOG_REV_COMMIT_PARENT:
144 while(text.GetLength()>0)
146 this->m_ParentHash.insert(this->m_ParentHash.end(),text.Left(40));
147 if(text.GetLength()>40)
148 text=text.Right(text.GetLength()-41);
149 else
150 break;
152 if(m_ParentHash.size()>1)
154 int a=1;
156 break;
157 case LOG_REV_COMMIT_FILE:
158 break;
160 }else
162 switch(mode)
164 // case LOG_REV_COMMIT_BODY:
165 // this->m_Body += one+_T("\n");
166 // break;
167 case LOG_REV_COMMIT_FILE:
168 //filelist += one +_T("\n");
169 //filelist.append(log,pos,log.find(0,pos));
170 if(filebegin<0)
171 filebegin=pos;
172 break;
176 if(begintime>1)
178 break;
181 //find next string start
182 pos=log.findNextString(pos);
185 if(filebegin>=0)
188 filelist.append(log,filebegin,pos);
189 this->m_Files.ParserFromLog(filelist);
190 this->m_Action=this->m_Files.GetAction();
192 return pos;
195 CTime GitRev::ConverFromString(CString input)
197 // pick up date from string
200 COleDateTime tm(_wtoi(input.Mid(0,4)),
201 _wtoi(input.Mid(5,2)),
202 _wtoi(input.Mid(8,2)),
203 _wtoi(input.Mid(11,2)),
204 _wtoi(input.Mid(14,2)),
205 _wtoi(input.Mid(17,2)));
206 if( tm.GetStatus() != COleDateTime::valid )
207 return CTime();//Error parsing time-string
209 // pick up utc offset
210 CString sign = input.Mid(20,1); // + or -
211 int hoursOffset = _wtoi(input.Mid(21,2));
212 int minsOffset = _wtoi(input.Mid(23,2));
213 // convert to a fraction of a day
214 double offset = (hoursOffset*60 + minsOffset) / 1440.0; // 1440 mins = 1 day
215 if ( sign == "-" )
217 offset = -offset;
219 // we have to subtract this from the time given to get UTC
220 tm -= offset;
221 // get utc time as a SYSTEMTIME
222 SYSTEMTIME sysTime;
223 tm.GetAsSystemTime( sysTime );
224 // and convert to users local time
225 SYSTEMTIME local;
226 if ( SystemTimeToTzSpecificLocalTime( &m_TimeZone, &sysTime, &local ) )
228 sysTime = local;
230 else
232 ASSERT(false); // this should not happen but leave time in utc if it does
234 // convert to CTime and return
235 return CTime( sysTime, -1 );;
237 catch(CException* e)
239 //Probably the date was something like 1970-01-01 00:00:00. _mktime64() doesnt like this.
240 //Dont let the application crash on this exception
242 #ifdef _AFX //CException classes are only defined when afx.h is included.
243 //When afx.h is not included, the exception is leaked.
244 //This will probably never happen because when CException is not defined, it cannot be thrown.
245 e->Delete();
246 #endif //ifdef _AFX
248 return CTime(); //Return an invalid time
251 int GitRev::SafeFetchFullInfo(CGit *git)
253 if(InterlockedExchange(&m_IsUpdateing,TRUE) == FALSE)
255 //GitRev rev;
256 BYTE_VECTOR onelog;
257 TCHAR oldmark=this->m_Mark;
258 CString commithash = m_CommitHash;
259 git->GetLog(onelog,commithash,NULL,1,CGit::LOG_INFO_FULL_DIFF|CGit::LOG_INFO_STAT|CGit::LOG_INFO_FILESTATE|CGit::LOG_INFO_DETECT_COPYRENAME|CGit::LOG_INFO_SHOW_MERGEDFILE);
260 CString oldhash=m_CommitHash;
261 GIT_REV_LIST oldlist=this->m_ParentHash;
262 ParserFromLog(onelog);
264 //ASSERT(oldhash==m_CommitHash);
265 if(oldmark!=0)
266 this->m_Mark=oldmark; //parser full log will cause old mark overwrited.
267 //So we need keep old bound mark.
268 this->m_ParentHash=oldlist;
269 InterlockedExchange(&m_IsUpdateing,FALSE);
270 InterlockedExchange(&m_IsFull,TRUE);
271 return 0;
273 return -1;