5 class CException; //Just in case afx.h is not included (cannot be included in every project which uses this file)
\r
7 // provide an ASSERT macro for when compiled without MFC
\r
9 // Don't use _asm here, it isn't supported by x64 version of compiler. In fact, MFC's ASSERT() is the same with _ASSERTE().
\r
10 #define ASSERT(x) _ASSERTE(x)
\r
14 GitRev::GitRev(void)
\r
19 // fetch local machine timezone info
\r
20 if ( GetTimeZoneInformation( &m_TimeZone ) == TIME_ZONE_ID_INVALID )
\r
26 GitRev::~GitRev(void)
\r
31 GitRev::GitRev(GitRev & rev)
\r
34 GitRev& GitRev::operator=(GitRev &rev)
\r
39 void GitRev::Clear()
\r
42 this->m_Files.Clear();
\r
44 this->m_ParentHash.clear();
\r
45 m_CommitterName.Empty();
\r
46 m_CommitterEmail.Empty();
\r
49 m_CommitHash.Empty();
\r
53 int GitRev::CopyFrom(GitRev &rev,bool OmitParentAndMark)
\r
55 m_AuthorName =rev.m_AuthorName ;
\r
56 m_AuthorEmail =rev.m_AuthorEmail ;
\r
57 m_AuthorDate =rev.m_AuthorDate ;
\r
58 m_CommitterName =rev.m_CommitterName ;
\r
59 m_CommitterEmail=rev.m_CommitterEmail;
\r
60 m_CommitterDate =rev.m_CommitterDate ;
\r
61 m_Subject =rev.m_Subject ;
\r
62 m_Body =rev.m_Body ;
\r
63 m_CommitHash =rev.m_CommitHash ;
\r
64 m_Files =rev.m_Files ;
\r
65 m_Action =rev.m_Action ;
\r
67 if(!OmitParentAndMark)
\r
69 m_ParentHash =rev.m_ParentHash ;
\r
74 int GitRev::ParserFromLog(BYTE_VECTOR &log,int start)
\r
80 BYTE_VECTOR filelist;
\r
83 this->m_Files.Clear();
\r
88 while( pos < log.size() && pos>=0)
\r
91 //one=log.Tokenize(_T("\n"),pos);
\r
92 if(log[pos]==_T('#') && log[pos+1] == _T('<') && log[pos+3] == _T('>'))
\r
94 //text = one.Right(one.GetLength()-4);
\r
96 g_Git.StringAppend(&text,&log[pos+4],CP_UTF8);
\r
101 case LOG_REV_ITEM_BEGIN:
\r
108 case LOG_REV_AUTHOR_NAME:
\r
109 this->m_AuthorName = text;
\r
111 case LOG_REV_AUTHOR_EMAIL:
\r
112 this->m_AuthorEmail = text;
\r
114 case LOG_REV_AUTHOR_DATE:
\r
115 this->m_AuthorDate =ConverFromString(text);
\r
117 case LOG_REV_COMMIT_NAME:
\r
118 this->m_CommitterName = text;
\r
120 case LOG_REV_COMMIT_EMAIL:
\r
121 this->m_CommitterEmail = text;
\r
123 case LOG_REV_COMMIT_DATE:
\r
124 this->m_CommitterDate =ConverFromString(text);
\r
126 case LOG_REV_COMMIT_SUBJECT:
\r
127 this->m_Subject = text;
\r
129 case LOG_REV_COMMIT_BODY:
\r
130 this->m_Body = text +_T("\n");
\r
132 case LOG_REV_COMMIT_HASH:
\r
133 this->m_CommitHash = text.Right(40);
\r
134 if(text.GetLength()>40)
\r
136 this->m_Mark=text[0];
\r
139 case LOG_REV_COMMIT_PARENT:
\r
140 while(text.GetLength()>0)
\r
142 this->m_ParentHash.insert(this->m_ParentHash.end(),text.Left(40));
\r
143 if(text.GetLength()>40)
\r
144 text=text.Right(text.GetLength()-41);
\r
148 if(m_ParentHash.size()>1)
\r
153 case LOG_REV_COMMIT_FILE:
\r
160 // case LOG_REV_COMMIT_BODY:
\r
161 // this->m_Body += one+_T("\n");
\r
163 case LOG_REV_COMMIT_FILE:
\r
164 //filelist += one +_T("\n");
\r
165 //filelist.append(log,pos,log.find(0,pos));
\r
177 //find next string start
\r
178 pos=log.findNextString(pos);
\r
184 filelist.append(log,filebegin,pos);
\r
185 this->m_Files.ParserFromLog(filelist);
\r
186 this->m_Action=this->m_Files.GetAction();
\r
191 CTime GitRev::ConverFromString(CString input)
\r
193 // pick up date from string
\r
196 CTime tm(_wtoi(input.Mid(0,4)),
\r
197 _wtoi(input.Mid(5,2)),
\r
198 _wtoi(input.Mid(8,2)),
\r
199 _wtoi(input.Mid(11,2)),
\r
200 _wtoi(input.Mid(14,2)),
\r
201 _wtoi(input.Mid(17,2)),
\r
203 if(tm.GetTime()<=1)
\r
204 return CTime();//Error parsing time-string
\r
206 // pick up utc offset
\r
207 CString sign = input.Mid(20,1); // + or -
\r
208 int hoursOffset = _wtoi(input.Mid(21,2));
\r
209 int minsOffset = _wtoi(input.Mid(23,2));
\r
212 hoursOffset = -hoursOffset;
\r
213 minsOffset = -minsOffset;
\r
215 // make a timespan object with this value
\r
216 CTimeSpan offset( 0, hoursOffset, minsOffset, 0 );
\r
217 // we have to subtract this from the time given to get UTC
\r
219 // get local timezone
\r
220 SYSTEMTIME sysTime;
\r
221 tm.GetAsSystemTime( sysTime );
\r
223 if ( SystemTimeToTzSpecificLocalTime( &m_TimeZone, &sysTime, &local ) )
\r
231 tm = CTime( sysTime, 0 );
\r
234 catch(CException* e)
\r
236 //Probably the date was something like 1970-01-01 00:00:00. _mktime64() doesnt like this.
\r
237 //Dont let the application crash on this exception
\r
239 #ifdef _AFX //CException classes are only defined when afx.h is included.
\r
240 //When afx.h is not included, the exception is leaked.
\r
241 //This will probably never happen because when CException is not defined, it cannot be thrown.
\r
243 #endif //ifdef _AFX
\r
245 return CTime(); //Return an invalid time
\r
248 int GitRev::SafeFetchFullInfo(CGit *git)
\r
250 if(InterlockedExchange(&m_IsUpdateing,TRUE) == FALSE)
\r
253 BYTE_VECTOR onelog;
\r
254 TCHAR oldmark=this->m_Mark;
\r
256 git->GetLog(onelog,m_CommitHash,NULL,1,CGit::LOG_INFO_STAT|CGit::LOG_INFO_FILESTATE|CGit::LOG_INFO_DETECT_COPYRENAME|CGit::LOG_INFO_SHOW_MERGEDFILE);
\r
257 CString oldhash=m_CommitHash;
\r
258 GIT_REV_LIST oldlist=this->m_ParentHash;
\r
259 ParserFromLog(onelog);
\r
261 //ASSERT(oldhash==m_CommitHash);
\r
263 this->m_Mark=oldmark; //parser full log will cause old mark overwrited.
\r
264 //So we need keep old bound mark.
\r
265 this->m_ParentHash=oldlist;
\r
266 InterlockedExchange(&m_IsUpdateing,FALSE);
\r
267 InterlockedExchange(&m_IsFull,TRUE);
\r