OSDN Git Service

First pass at relative times in log. This version shows both local and relative time...
[tortoisegit/TortoiseGitJp.git] / src / Git / GitRev.cpp
1 #include "StdAfx.h"\r
2 #include "GitRev.h"\r
3 #include "Git.h"\r
4 \r
5 GitRev::GitRev(void)\r
6 {\r
7         m_Action=0;\r
8         m_IsFull = 0;\r
9         m_IsUpdateing = 0;\r
10 }\r
11 \r
12 GitRev::~GitRev(void)\r
13 {\r
14 }\r
15 \r
16 #if 0\r
17 GitRev::GitRev(GitRev & rev)\r
18 {\r
19 }\r
20 GitRev& GitRev::operator=(GitRev &rev)\r
21 {\r
22         return *this;\r
23 }\r
24 #endif\r
25 void GitRev::Clear()\r
26 {\r
27         this->m_Action=0;\r
28         this->m_Files.Clear();\r
29         this->m_Action=0;\r
30         this->m_ParentHash.clear();\r
31         m_CommitterName.Empty();\r
32         m_CommitterEmail.Empty();\r
33         m_Body.Empty();\r
34         m_Subject.Empty();\r
35         m_CommitHash.Empty();\r
36         m_Mark=0;\r
37 \r
38 }\r
39 int GitRev::CopyFrom(GitRev &rev,bool OmitParentAndMark)\r
40 {\r
41         m_AuthorName    =rev.m_AuthorName       ;\r
42         m_AuthorEmail   =rev.m_AuthorEmail      ;\r
43         m_AuthorDate    =rev.m_AuthorDate       ;\r
44         m_CommitterName =rev.m_CommitterName    ;\r
45         m_CommitterEmail=rev.m_CommitterEmail;\r
46         m_CommitterDate =rev.m_CommitterDate    ;\r
47         m_Subject               =rev.m_Subject          ;\r
48         m_Body                  =rev.m_Body                     ;\r
49         m_CommitHash    =rev.m_CommitHash       ;\r
50         m_Files                 =rev.m_Files                    ;       \r
51         m_Action                =rev.m_Action           ;\r
52 \r
53         if(!OmitParentAndMark)\r
54         {\r
55                 m_ParentHash    =rev.m_ParentHash       ;\r
56                 m_Mark                  =rev.m_Mark;\r
57         }\r
58         return 0;\r
59 }\r
60 int GitRev::ParserFromLog(BYTE_VECTOR &log,int start)\r
61 {\r
62         int pos=start;\r
63         CString one;\r
64         CString key;\r
65         CString text;\r
66         BYTE_VECTOR filelist;\r
67         BYTE mode=0;\r
68         CTGitPath  path;\r
69         this->m_Files.Clear();\r
70     m_Action=0;\r
71         int begintime=0;\r
72         BYTE *p=&log[0];\r
73         int filebegin=-1;\r
74 \r
75         while( pos < log.size() && pos>=0)\r
76         {\r
77                 \r
78                 //one=log.Tokenize(_T("\n"),pos);\r
79                 if(log[pos]==_T('#') && log[pos+1] == _T('<') && log[pos+3] == _T('>'))\r
80                 {\r
81                         //text = one.Right(one.GetLength()-4);\r
82                         text.Empty();\r
83                         g_Git.StringAppend(&text,&log[pos+4],CP_UTF8);\r
84                         mode = log[pos+2];\r
85                         \r
86                         switch(mode)\r
87                         {\r
88                         case LOG_REV_ITEM_BEGIN:\r
89                                 begintime++;\r
90                                 if(begintime>1)\r
91                                         break;\r
92                                 else\r
93                                         this->Clear();\r
94                                 break;\r
95                         case LOG_REV_AUTHOR_NAME:\r
96                                 this->m_AuthorName = text;\r
97                                 break;\r
98                         case LOG_REV_AUTHOR_EMAIL:\r
99                                 this->m_AuthorEmail = text;\r
100                                 break;\r
101                         case LOG_REV_AUTHOR_DATE:\r
102                                 this->m_AuthorDate =ConverFromString(text);\r
103                                 break;\r
104                         case LOG_REV_COMMIT_NAME:\r
105                                 this->m_CommitterName = text;\r
106                                 break;\r
107                         case LOG_REV_COMMIT_EMAIL:\r
108                                 this->m_CommitterEmail = text;\r
109                                 break;\r
110                         case LOG_REV_COMMIT_DATE:\r
111                                 this->m_CommitterDate =ConverFromString(text);\r
112                                 break;\r
113                         case LOG_REV_COMMIT_SUBJECT:\r
114                                 this->m_Subject = text;\r
115                                 break;\r
116                         case LOG_REV_COMMIT_BODY:\r
117                                 this->m_Body = text +_T("\n");\r
118                                 break;\r
119                         case LOG_REV_COMMIT_HASH:\r
120                                 this->m_CommitHash = text.Right(40);\r
121                                 if(text.GetLength()>40)\r
122                                 {\r
123                                         this->m_Mark=text[0];\r
124                                 }\r
125                                 break;\r
126                         case LOG_REV_COMMIT_PARENT:\r
127                                 while(text.GetLength()>0)\r
128                                 {\r
129                                         this->m_ParentHash.insert(this->m_ParentHash.end(),text.Left(40));\r
130                                         if(text.GetLength()>40)\r
131                                                 text=text.Right(text.GetLength()-41);\r
132                                         else\r
133                                                 break;\r
134                                 }\r
135                                 break;\r
136                         case LOG_REV_COMMIT_FILE:\r
137                                 break;\r
138                         }\r
139                 }else\r
140                 {\r
141                         switch(mode)\r
142                         {\r
143 //                      case LOG_REV_COMMIT_BODY:\r
144 //                              this->m_Body += one+_T("\n");\r
145 //                              break;\r
146                         case LOG_REV_COMMIT_FILE:\r
147                                 //filelist += one +_T("\n");\r
148                                 //filelist.append(log,pos,log.find(0,pos));\r
149                                 if(filebegin<0)\r
150                                         filebegin=pos;\r
151                                 break;\r
152                         }\r
153                 }\r
154                 \r
155                 if(begintime>1)\r
156                 {\r
157                         break;\r
158                 }\r
159 \r
160                 //find next string start \r
161                 pos=log.findNextString(pos);\r
162         }\r
163         \r
164         if(filebegin>=0)\r
165         {\r
166                 filelist.append(log,filebegin,pos);     \r
167                 this->m_Files.ParserFromLog(filelist);\r
168                 this->m_Action=this->m_Files.GetAction();\r
169         }\r
170         return pos;\r
171 }\r
172 \r
173 CTime GitRev::ConverFromString(CString input)\r
174 {\r
175         // pick up date from string\r
176         CTime tm(_wtoi(input.Mid(0,4)),\r
177                          _wtoi(input.Mid(5,2)),\r
178                          _wtoi(input.Mid(8,2)),\r
179                          _wtoi(input.Mid(11,2)),\r
180                          _wtoi(input.Mid(14,2)),\r
181                          _wtoi(input.Mid(17,2)),\r
182                          0);\r
183         // pick up utc offset\r
184         CString sign = input.Mid(20,1);         // + or -\r
185         int hoursOffset =  _wtoi(input.Mid(21,2));\r
186         int minsOffset = _wtoi(input.Mid(23,2));\r
187         if ( sign == "-" )\r
188         {\r
189                 hoursOffset = -hoursOffset;\r
190                 minsOffset = -minsOffset;\r
191         }\r
192         // make a timespan object with this value\r
193         CTimeSpan offset( 0, hoursOffset, minsOffset, 0 );\r
194         // we have to subtract this from the time given to get UTC\r
195         tm -= offset;\r
196         // get local timezone\r
197         SYSTEMTIME sysTime;\r
198         tm.GetAsSystemTime( sysTime );\r
199         TIME_ZONE_INFORMATION timeZone;\r
200         if ( GetTimeZoneInformation( &timeZone ) == TIME_ZONE_ID_UNKNOWN )\r
201         {\r
202                 ASSERT(false);\r
203         }\r
204         else\r
205         {\r
206                 SYSTEMTIME local;\r
207                 if ( SystemTimeToTzSpecificLocalTime( &timeZone, &sysTime, &local ) )\r
208                 {\r
209                         sysTime = local;\r
210                 }\r
211                 else\r
212                 {\r
213                         ASSERT(false);\r
214                 }\r
215         }\r
216         tm = CTime( sysTime, 0 );\r
217         return tm;\r
218 }\r
219 \r
220 int GitRev::SafeFetchFullInfo(CGit *git)\r
221 {\r
222         if(InterlockedExchange(&m_IsUpdateing,TRUE) == FALSE)\r
223         {\r
224                 //GitRev rev;\r
225                 BYTE_VECTOR onelog;\r
226                 TCHAR oldmark=this->m_Mark;\r
227         \r
228                 git->GetLog(onelog,m_CommitHash,NULL,1,CGit::LOG_INFO_STAT|CGit::LOG_INFO_FILESTATE|CGit::LOG_INFO_DETECT_COPYRENAME);\r
229                 CString oldhash=m_CommitHash;\r
230                 GIT_REV_LIST oldlist=this->m_ParentHash;\r
231                 ParserFromLog(onelog);\r
232                 \r
233                 //ASSERT(oldhash==m_CommitHash);\r
234                 if(oldmark!=0)\r
235                         this->m_Mark=oldmark;  //parser full log will cause old mark overwrited. \r
236                                                                //So we need keep old bound mark.\r
237                 this->m_ParentHash=oldlist;\r
238                 InterlockedExchange(&m_IsUpdateing,FALSE);\r
239                 InterlockedExchange(&m_IsFull,TRUE);\r
240                 return 0;\r
241         }\r
242         return -1;\r
243 }