OSDN Git Service

Add auto load putty key option at clone, pull and push dialog.
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / GitLogCache.cpp
1 #include "stdafx.h"\r
2 #include "GitLogCache.h"\r
3 \r
4 CLogCache::CLogCache()\r
5 {\r
6 \r
7 }\r
8 \r
9 CLogCache::~CLogCache()\r
10 {\r
11         //this->m_IndexFile.Close();\r
12         //this->m_DataFile.Close();\r
13 }\r
14 int CLogCache::AddCacheEntry(GitRev &Rev)\r
15 {\r
16         this->m_NewCacheEntry.push_back(Rev);\r
17         return 0;\r
18 }\r
19 \r
20 int CLogCache::GetCacheData(GitRev &Rev)\r
21 {\r
22         if(this->m_HashMapIndex.find(Rev.m_CommitHash)==m_HashMapIndex.end())\r
23         {\r
24                 for(int i=0;i<this->m_NewCacheEntry.size();i++)\r
25                 {\r
26                         if(m_NewCacheEntry[i].m_CommitHash==Rev.m_CommitHash)\r
27                         {\r
28                                 Rev.CopyFrom(m_NewCacheEntry[i],true);\r
29                                 return 0;\r
30                         }\r
31                 }\r
32                 return -1;\r
33         }\r
34         else\r
35         {\r
36                 return LoadOneItem(Rev,m_HashMapIndex[Rev.m_CommitHash]);\r
37         }\r
38         return 0;\r
39 }\r
40 int CLogCache::FetchCacheIndex(CString GitDir)\r
41 {\r
42 \r
43         if(this->m_IndexFile.m_hFile == CFile::hFileNull)\r
44         {\r
45                 BOOL b=m_IndexFile.Open(GitDir+_T("\\.git\\")+INDEX_FILE_NAME,\r
46                         CFile::modeRead|CFile::shareDenyNone|\r
47                         CFile::modeNoTruncate|CFile::modeCreate);\r
48                 if(!b)\r
49                         return -1;\r
50         }\r
51         //Cache has been fetched.\r
52         //if(m_GitDir == GitDir)\r
53         //      return 0;\r
54 \r
55         m_GitDir=GitDir;\r
56         m_IndexFile.SeekToBegin();\r
57 \r
58         SLogCacheIndexHeader header;\r
59         UINT count=m_IndexFile.Read(&header,sizeof(SLogCacheIndexHeader));\r
60         if(count != sizeof(SLogCacheIndexHeader))\r
61                 return -2;\r
62 \r
63         if( header.m_Magic != LOG_INDEX_MAGIC )\r
64                 return -3;\r
65 \r
66         if( header.m_Version != LOG_INDEX_VERSION )\r
67                 return -4;\r
68 \r
69 \r
70         SLogCacheItem Item;\r
71 \r
72         //for(int i=0;i<header.m_ItemCount;i++)\r
73         this->m_HashMapIndex.clear();\r
74 \r
75         while(1)\r
76         {\r
77                 count=m_IndexFile.Read(&Item,sizeof(SLogCacheItem));    \r
78                 if( count != sizeof(SLogCacheItem) )\r
79                         break;\r
80 \r
81                 CString str;\r
82                 g_Git.StringAppend(&str,Item.m_Hash,CP_UTF8,40);\r
83                 this->m_HashMapIndex[str]=Item.m_Offset;\r
84         }\r
85 \r
86         return 0;\r
87 }\r
88 \r
89 int CLogCache::SaveOneItem(GitRev &Rev,ULONGLONG offset)\r
90 {\r
91         \r
92         SLogCacheRevItemHeader header;\r
93         m_DataFile.Seek(offset,CFile::begin);\r
94 \r
95         if(this->m_DataFile.m_hFile == CFile::hFileNull)\r
96         {\r
97                 BOOL b=m_DataFile.Open(m_GitDir+_T("\\.git\\")+INDEX_FILE_NAME,\r
98                         CFile::modeRead|CFile::shareDenyNone|\r
99                         CFile::modeNoTruncate|CFile::modeCreate);\r
100                 if(!b)\r
101                         return -1;\r
102         }\r
103 \r
104         header.m_Magic=LOG_DATA_ITEM_MAGIC;\r
105         header.m_Version=LOG_INDEX_VERSION;\r
106         header.m_FileCount=Rev.m_Files.GetCount();\r
107 \r
108         m_DataFile.Write(&header,sizeof(SLogCacheRevItemHeader));\r
109         \r
110         CArchive ar(&m_DataFile, CArchive::store);\r
111 \r
112         ar<<Rev.m_AuthorName;\r
113         ar<<Rev.m_AuthorEmail;\r
114         ar<<Rev.m_AuthorDate;\r
115         ar<<Rev.m_CommitterName;\r
116         ar<<Rev.m_CommitterEmail;\r
117         ar<<Rev.m_CommitterDate;\r
118         ar<<Rev.m_Subject;\r
119         ar<<Rev.m_Body;\r
120         ar<<Rev.m_CommitHash;\r
121         ar<<Rev.m_Action;\r
122 \r
123         for(int i=0;i<Rev.m_Files.GetCount();i++)\r
124         {\r
125                 SLogCacheRevFileHeader header;\r
126                 header.m_Magic=LOG_DATA_FILE_MAGIC;\r
127                 header.m_Version=LOG_INDEX_VERSION;\r
128 \r
129                 ar<<header.m_Magic;\r
130                 ar<<header.m_Version;\r
131                 ar<<Rev.m_Files[i].GetGitPathString();\r
132                 ar<<Rev.m_Files[i].GetGitOldPathString();\r
133                 ar<<Rev.m_Files[i].m_Action;\r
134                 ar<<Rev.m_Files[i].m_Stage;\r
135                 ar<<Rev.m_Files[i].m_StatAdd;\r
136                 ar<<Rev.m_Files[i].m_StatDel;\r
137                 \r
138         }\r
139         return 0;\r
140 }\r
141 \r
142 int CLogCache::LoadOneItem(GitRev &Rev,ULONGLONG offset)\r
143 {\r
144         SLogCacheRevItemHeader header;\r
145 \r
146         if(this->m_DataFile.m_hFile == CFile::hFileNull)\r
147         {\r
148                 BOOL b=m_DataFile.Open(m_GitDir+_T("\\.git\\")+DATA_FILE_NAME,\r
149                         CFile::modeRead|CFile::shareDenyNone|\r
150                         CFile::modeNoTruncate|CFile::modeCreate);\r
151                 if(!b)\r
152                         return -1;\r
153         }\r
154         m_DataFile.Seek(offset,CFile::begin);\r
155 \r
156         UINT count=m_DataFile.Read(&header,sizeof(SLogCacheRevItemHeader));\r
157         if( count != sizeof(SLogCacheRevItemHeader))\r
158                 return -1;\r
159         if( !CheckHeader(header))\r
160                 return -2;\r
161 \r
162 \r
163         CArchive ar(&m_DataFile, CArchive::load);\r
164 \r
165         ar>>Rev.m_AuthorName;\r
166         ar>>Rev.m_AuthorEmail;\r
167         ar>>Rev.m_AuthorDate;\r
168         ar>>Rev.m_CommitterName;\r
169         ar>>Rev.m_CommitterEmail;\r
170         ar>>Rev.m_CommitterDate;\r
171         ar>>Rev.m_Subject;\r
172         ar>>Rev.m_Body;\r
173         ar>>Rev.m_CommitHash;\r
174         ar>>Rev.m_Action;\r
175 \r
176         Rev.m_Files.Clear();\r
177 \r
178         for(int i=0;i<header.m_FileCount;i++)\r
179         {\r
180                 CTGitPath path;\r
181                 CString file,oldfile;\r
182                 path.Reset();\r
183                 SLogCacheRevFileHeader header;\r
184 \r
185                 ar>>header.m_Magic;\r
186                 ar>>header.m_Version;\r
187 \r
188                 if( this->CheckHeader(header) )\r
189                         return -1;\r
190                 ar>>file;\r
191                 ar>>oldfile;\r
192                 path.SetFromGit(file,&oldfile);\r
193 \r
194                 ar>>path.m_Action;\r
195                 ar>>path.m_Stage;\r
196                 ar>>path.m_StatAdd;\r
197                 ar>>path.m_StatDel;\r
198                 \r
199                 \r
200                 Rev.m_Files.AddPath(path);\r
201         }\r
202         return 0;\r
203 }\r
204 int CLogCache::RebuildCacheFile()\r
205 {\r
206         m_IndexFile.SetLength(0);\r
207         m_DataFile.SetLength(0);\r
208         {\r
209                 SLogCacheIndexHeader header;\r
210                 header.m_Magic=LOG_INDEX_MAGIC;\r
211                 header.m_Version=LOG_INDEX_VERSION;\r
212                 m_IndexFile.SeekToBegin();\r
213                 m_IndexFile.Write(&header,sizeof(SLogCacheIndexHeader));\r
214         }\r
215         \r
216         {\r
217                 SLogCacheRevFileHeader header;\r
218                 header.m_Magic=LOG_DATA_MAGIC;\r
219                 header.m_Version=LOG_INDEX_VERSION;\r
220 \r
221                 m_DataFile.SeekToBegin();\r
222                 m_DataFile.Write(&header,sizeof(SLogCacheRevFileHeader));\r
223         }\r
224         return 0;\r
225 }\r
226 int CLogCache::SaveCache()\r
227 {\r
228         if( this->m_NewCacheEntry.size() == 0 )\r
229                 return 0;\r
230 \r
231         bool bIsRebuild=false;\r
232         if(this->m_DataFile.m_hFile != CFile::hFileNull)\r
233                 m_DataFile.Close();\r
234         if(this->m_IndexFile.m_hFile!=CFile::hFileNull)\r
235                 m_IndexFile.Close();\r
236 \r
237         if(this->m_IndexFile.m_hFile == CFile::hFileNull)\r
238         {\r
239                 BOOL b=m_IndexFile.Open(m_GitDir+_T("\\.git\\")+INDEX_FILE_NAME,\r
240                         CFile::modeReadWrite|CFile::shareDenyWrite|\r
241                         CFile::modeNoTruncate|CFile::modeCreate);\r
242                 if(!b)\r
243                         return -1;\r
244         }\r
245 \r
246         if(this->m_DataFile.m_hFile == CFile::hFileNull)\r
247         {\r
248                 BOOL b=m_DataFile.Open(m_GitDir+_T("\\.git\\")+DATA_FILE_NAME,\r
249                         CFile::modeReadWrite|CFile::shareDenyWrite|\r
250                         CFile::modeNoTruncate|CFile::modeCreate);\r
251 \r
252                 \r
253                 if(!b)\r
254                 {\r
255                         m_IndexFile.Close();\r
256                         return -1;\r
257                 }\r
258         }\r
259 \r
260         {\r
261                 SLogCacheIndexHeader header;\r
262                 memset(&header,0,sizeof(SLogCacheIndexHeader));\r
263                 UINT count=m_IndexFile.Read(&header,sizeof(SLogCacheIndexHeader));\r
264                 if(count != sizeof(SLogCacheIndexHeader) || !this->CheckHeader(header))\r
265                 {// new file\r
266                         RebuildCacheFile();\r
267                         bIsRebuild=true;\r
268                 }\r
269         }\r
270 \r
271         {\r
272 \r
273                 SLogCacheRevFileHeader header;\r
274         \r
275                 UINT count=m_DataFile.Read(&header,sizeof(SLogCacheRevFileHeader));\r
276                 if( count != sizeof(SLogCacheRevFileHeader) || !CheckHeader(header))\r
277                 {\r
278                         RebuildCacheFile();\r
279                         bIsRebuild=true;\r
280                 }\r
281         \r
282         }\r
283 \r
284         m_DataFile.SeekToEnd();\r
285         m_IndexFile.SeekToEnd();\r
286         for(int i=0;i<this->m_NewCacheEntry.size();i++)\r
287         {\r
288                 if(this->m_HashMapIndex.find(m_NewCacheEntry[i].m_CommitHash) == m_HashMapIndex.end() || bIsRebuild)\r
289                 {\r
290                         ULONGLONG offset = m_DataFile.GetPosition();\r
291                         this->SaveOneItem(m_NewCacheEntry[i],offset);\r
292 \r
293                         SLogCacheItem item;\r
294                         for(int j=0; j<40;j++)\r
295                                 item.m_Hash[j]=(BYTE)m_NewCacheEntry[i].m_CommitHash[j];\r
296                         item.m_Offset=offset;\r
297 \r
298                         m_IndexFile.Write(&item,sizeof(SLogCacheItem));\r
299                 }\r
300         }\r
301         m_IndexFile.Close();\r
302         m_DataFile.Close();\r
303         return 0;\r
304 }