TortoiseGitBlame: Diff shown in wrong order
[TortoiseGit.git] / src / TGitCache / StatusCacheEntry.cpp
blobb77b026f14582f6891fd56c9d856bbedd92dc59d
1 // TortoiseGit - a Windows shell extension for easy version control
3 // External Cache Copyright (C) 2005-2006,2008,2014 - TortoiseSVN
4 // Copyright (C) 2008-2014, 2016-2017 - TortoiseGit
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
21 #include "StatusCacheEntry.h"
22 #include "GitStatus.h"
23 #include "CacheInterface.h"
24 #include "registry.h"
26 #define CACHEVERION 8
28 ULONGLONG cachetimeout = (ULONGLONG)CRegStdDWORD(L"Software\\TortoiseGit\\Cachetimeout", LONG_MAX);
30 CStatusCacheEntry::CStatusCacheEntry()
31 : m_bSet(false)
32 , m_highestPriorityLocalStatus(git_wc_status_none)
33 , m_bAssumeValid(false)
34 , m_bSkipWorktree(false)
36 SetAsUnversioned();
39 CStatusCacheEntry::CStatusCacheEntry(const git_wc_status_kind status)
40 : m_bSet(true)
41 , m_highestPriorityLocalStatus(status)
42 , m_bAssumeValid(false)
43 , m_bSkipWorktree(false)
44 , m_lastWriteTime(0)
46 m_GitStatus.status = status;
47 m_GitStatus.assumeValid = m_GitStatus.skipWorktree = false;
48 m_discardAtTime = GetTickCount64() + cachetimeout;
51 CStatusCacheEntry::CStatusCacheEntry(const git_wc_status2_t* pGitStatus, __int64 lastWriteTime, LONGLONG validuntil /* = 0*/)
52 : m_bSet(false)
53 , m_highestPriorityLocalStatus(git_wc_status_none)
55 SetStatus(pGitStatus);
56 m_lastWriteTime = lastWriteTime;
57 if (validuntil)
58 m_discardAtTime = validuntil;
59 else
60 m_discardAtTime = GetTickCount64() + cachetimeout;
63 bool CStatusCacheEntry::SaveToDisk(FILE* pFile) const
65 #define WRITEVALUETOFILE(x) if (fwrite(&x, sizeof(x), 1, pFile)!=1) return false;
66 #define WRITESTRINGTOFILE(x) if (x.IsEmpty()) {value=0;WRITEVALUETOFILE(value);}else{value=x.GetLength();WRITEVALUETOFILE(value);if (fwrite((LPCSTR)x, sizeof(char), value, pFile)!=value) return false;}
68 unsigned int value = CACHEVERION;
69 WRITEVALUETOFILE(value); // 'version' of this save-format
70 WRITEVALUETOFILE(m_highestPriorityLocalStatus);
71 WRITEVALUETOFILE(m_lastWriteTime);
72 WRITEVALUETOFILE(m_bSet);
74 // now save the status struct (without the entry field, because we don't use that)
75 WRITEVALUETOFILE(m_GitStatus.status);
76 WRITEVALUETOFILE(m_GitStatus.assumeValid);
77 WRITEVALUETOFILE(m_GitStatus.skipWorktree);
78 return true;
81 bool CStatusCacheEntry::LoadFromDisk(FILE * pFile)
83 #define LOADVALUEFROMFILE(x) if (fread(&x, sizeof(x), 1, pFile)!=1) return false;
84 try
86 unsigned int value = 0;
87 LOADVALUEFROMFILE(value);
88 if (value != CACHEVERION)
89 return false; // not the correct version
90 LOADVALUEFROMFILE(m_highestPriorityLocalStatus);
91 LOADVALUEFROMFILE(m_lastWriteTime);
92 LOADVALUEFROMFILE(m_bSet);
93 SecureZeroMemory(&m_GitStatus, sizeof(m_GitStatus));
94 LOADVALUEFROMFILE(m_GitStatus.status);
95 LOADVALUEFROMFILE(m_GitStatus.assumeValid);
96 LOADVALUEFROMFILE(m_GitStatus.skipWorktree);
97 m_discardAtTime = GetTickCount64() + cachetimeout;
99 catch ( CAtlException )
101 return false;
103 return true;
106 void CStatusCacheEntry::SetStatus(const git_wc_status2_t* pGitStatus)
108 if (!pGitStatus)
110 SetAsUnversioned();
112 else
114 m_highestPriorityLocalStatus = pGitStatus->status;
115 m_GitStatus = *pGitStatus;
116 m_bAssumeValid = pGitStatus->assumeValid;
117 m_bSkipWorktree = pGitStatus->skipWorktree;
119 m_discardAtTime = GetTickCount64() + cachetimeout;
120 m_bSet = true;
124 void CStatusCacheEntry::SetAsUnversioned()
126 SecureZeroMemory(&m_GitStatus, sizeof(m_GitStatus));
127 m_discardAtTime = GetTickCount64() + cachetimeout;
128 git_wc_status_kind status = git_wc_status_none;
129 if (m_highestPriorityLocalStatus == git_wc_status_unversioned)
130 status = git_wc_status_unversioned;
131 m_highestPriorityLocalStatus = status;
132 m_GitStatus.status = git_wc_status_none;
133 m_lastWriteTime = 0;
134 m_bAssumeValid = false;
135 m_bSkipWorktree = false;
138 bool CStatusCacheEntry::HasExpired(LONGLONG now) const
140 return m_discardAtTime != 0 && (now - m_discardAtTime) >= 0;
143 void CStatusCacheEntry::BuildCacheResponse(TGITCacheResponse& response, DWORD& responseLength) const
145 SecureZeroMemory(&response, sizeof(response));
146 response.m_status = (INT8)m_GitStatus.status;
147 response.m_bAssumeValid = m_bAssumeValid;
148 response.m_bSkipWorktree = m_bSkipWorktree;
149 responseLength = sizeof(response);
152 bool CStatusCacheEntry::IsVersioned() const
154 return m_highestPriorityLocalStatus > git_wc_status_unversioned;
157 bool CStatusCacheEntry::DoesFileTimeMatch(__int64 testTime) const
159 return m_lastWriteTime == testTime;
163 bool CStatusCacheEntry::ForceStatus(git_wc_status_kind forcedStatus)
165 git_wc_status_kind newStatus = forcedStatus;
167 if(newStatus != m_highestPriorityLocalStatus)
169 // We've had a status change
170 m_highestPriorityLocalStatus = newStatus;
171 m_GitStatus.status = newStatus;
172 m_discardAtTime = GetTickCount64() + cachetimeout;
173 return true;
175 return false;
178 bool
179 CStatusCacheEntry::HasBeenSet() const
181 return m_bSet;
184 void CStatusCacheEntry::Invalidate()
186 m_bSet = false;