2 #include "ATLComTime.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
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)
21 // fetch local machine timezone info
22 if ( GetTimeZoneInformation( &m_TimeZone
) == TIME_ZONE_ID_INVALID
)
33 GitRev::GitRev(GitRev
& rev
)
36 GitRev
& GitRev::operator=(GitRev
&rev
)
44 this->m_Files
.Clear();
46 this->m_ParentHash
.clear();
47 m_CommitterName
.Empty();
48 m_CommitterEmail
.Empty();
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
;
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
;
78 int GitRev::ParserFromLog(BYTE_VECTOR
&log
,int start
)
87 this->m_Files
.Clear();
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);
100 g_Git
.StringAppend(&text
,&log
[pos
+4],CGit::m_LogEncode
);
105 case LOG_REV_ITEM_BEGIN
:
112 case LOG_REV_AUTHOR_NAME
:
113 this->m_AuthorName
= text
;
115 case LOG_REV_AUTHOR_EMAIL
:
116 this->m_AuthorEmail
= text
;
118 case LOG_REV_AUTHOR_DATE
:
119 this->m_AuthorDate
=ConverFromString(text
);
121 case LOG_REV_COMMIT_NAME
:
122 this->m_CommitterName
= text
;
124 case LOG_REV_COMMIT_EMAIL
:
125 this->m_CommitterEmail
= text
;
127 case LOG_REV_COMMIT_DATE
:
128 this->m_CommitterDate
=ConverFromString(text
);
130 case LOG_REV_COMMIT_SUBJECT
:
131 this->m_Subject
= text
;
133 case LOG_REV_COMMIT_BODY
:
134 this->m_Body
= text
+_T("\n");
136 case LOG_REV_COMMIT_HASH
:
137 this->m_CommitHash
= text
.Right(40);
138 if(text
.GetLength()>40)
140 this->m_Mark
=text
[0];
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);
152 if(m_ParentHash
.size()>1)
157 case LOG_REV_COMMIT_FILE
:
164 // case LOG_REV_COMMIT_BODY:
165 // this->m_Body += one+_T("\n");
167 case LOG_REV_COMMIT_FILE
:
168 //filelist += one +_T("\n");
169 //filelist.append(log,pos,log.find(0,pos));
181 //find next string start
182 pos
=log
.findNextString(pos
);
188 filelist
.append(log
,filebegin
,pos
);
189 this->m_Files
.ParserFromLog(filelist
);
190 this->m_Action
=this->m_Files
.GetAction();
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
219 // we have to subtract this from the time given to get UTC
221 // get utc time as a SYSTEMTIME
223 tm
.GetAsSystemTime( sysTime
);
224 // and convert to users local time
226 if ( SystemTimeToTzSpecificLocalTime( &m_TimeZone
, &sysTime
, &local
) )
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 );;
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.
248 return CTime(); //Return an invalid time
251 int GitRev::SafeFetchFullInfo(CGit
*git
)
253 if(InterlockedExchange(&m_IsUpdateing
,TRUE
) == FALSE
)
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);
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
);