1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2013 - TortoiseGit
4 // Copyright (C) 2003-2008 - TortoiseSVN
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.
24 #define PARENT_MASK 0xFFFFFF
25 #define MERGE_MASK (0x1000000)
32 CTGitPath(const CString
& sUnknownPath
);
37 #pragma warning(disable: 4480) // nonstandard extension used: specifying underlying type for enum 'enum'
40 LOGACTIONS_ADDED
= 0x00000001,
41 LOGACTIONS_MODIFIED
= 0x00000002,
42 LOGACTIONS_REPLACED
= 0x00000004,
43 LOGACTIONS_DELETED
= 0x00000008,
44 LOGACTIONS_UNMERGED
= 0x00000010,
45 LOGACTIONS_CACHE
= 0x00000020,
46 LOGACTIONS_COPY
= 0x00000040,
47 LOGACTIONS_MERGED
= 0x00000080,
48 LOGACTIONS_FORWORD
= 0x00000100,
49 LOGACTIONS_ASSUMEVALID
= 0x00000200,
50 LOGACTIONS_SKIPWORKTREE
= 0x00000400,
51 LOGACTIONS_UNVER
= 0x80000000,
52 LOGACTIONS_IGNORE
= 0x40000000,
53 //LOGACTIONS_CONFLICT = 0x20000000,
55 // For log filter only
56 LOGACTIONS_HIDE
= 0x20000000,
57 LOGACTIONS_GRAY
= 0x10000000,
60 LOGACTIONS_REBASE_CURRENT
= 0x08000000,
61 LOGACTIONS_REBASE_PICK
= 0x04000000,
62 LOGACTIONS_REBASE_SQUASH
= 0x02000000,
63 LOGACTIONS_REBASE_EDIT
= 0x01000000,
64 LOGACTIONS_REBASE_DONE
= 0x00800000,
65 LOGACTIONS_REBASE_SKIP
= 0x00400000,
66 LOGACTIONS_REBASE_MASK
= 0x0FC00000,
67 LOGACTIONS_REBASE_MODE_MASK
=0x07C00000,
73 unsigned int m_Action
;
75 int ParserAction(BYTE action
);
76 CString
GetActionName();
77 static CString
GetActionName(int action
);
79 * Set the path as an UTF8 string with forward slashes
81 void SetFromGit(const char* pPath
);
82 void SetFromGit(const char* pPath
, bool bIsDirectory
);
83 void SetFromGit(const TCHAR
* pPath
, bool bIsDirectory
);
84 void SetFromGit(const CString
& sPath
,CString
*OldPath
=NULL
);
87 * Set the path as UNICODE with backslashes
89 void SetFromWin(LPCTSTR pPath
);
90 void SetFromWin(const CString
& sPath
);
91 void SetFromWin(LPCTSTR pPath
, bool bIsDirectory
);
92 void SetFromWin(const CString
& sPath
, bool bIsDirectory
);
94 * Set the path from an unknown source.
96 void SetFromUnknown(const CString
& sPath
);
98 * Returns the path in Windows format, i.e. with backslashes
100 LPCTSTR
GetWinPath() const;
102 * Returns the path in Windows format, i.e. with backslashes
104 const CString
& GetWinPathString() const;
106 * Returns the path with forward slashes.
108 const CString
& GetGitPathString() const;
110 const CString
& GetGitOldPathString() const;
112 * Returns the path completely prepared to be fed the the Git APIs
113 * It will be in UTF8, with URLs escaped, if necessary
115 // const char* GetGitApiPath(apr_pool_t *pool) const;
117 * Returns the path for showing in an UI.
119 * URL's are returned with forward slashes, unescaped if necessary
120 * Paths are returned with backward slashes
122 const CString
& GetUIPathString() const;
124 * Returns true if the path points to a directory
126 bool IsDirectory() const;
128 CTGitPath
GetSubPath(const CTGitPath
&root
);
131 * Returns the directory. If the path points to a directory, then the path
132 * is returned unchanged. If the path points to a file, the path to the
133 * parent directory is returned.
135 CTGitPath
GetDirectory() const;
137 * Returns the the directory which contains the item the path refers to.
138 * If the path is a directory, then this returns the directory above it.
139 * If the path is to a file, then this returns the directory which contains the path
140 * parent directory is returned.
142 CTGitPath
GetContainingDirectory() const;
144 * Get the 'root path' (e.g. "c:\") - Used to pass to GetDriveType
146 CString
GetRootPathString() const;
148 * Returns the filename part of the full path.
149 * \remark don't call this for directories.
151 CString
GetFilename() const;
152 CString
GetBaseFilename() const;
154 * Returns the item's name without the full path.
156 CString
GetFileOrDirectoryName() const;
158 * Returns the item's name without the full path, unescaped if necessary.
160 CString
GetUIFileOrDirectoryName() const;
162 * Returns the file extension, including the dot.
163 * \remark Returns an empty string for directories
165 CString
GetFileExtension() const;
167 bool IsEmpty() const;
170 * Checks if two paths are equal. The slashes are taken care of.
172 bool IsEquivalentTo(const CTGitPath
& rhs
) const;
173 bool IsEquivalentToWithoutCase(const CTGitPath
& rhs
) const;
174 bool operator==(const CTGitPath
& x
) const {return IsEquivalentTo(x
);}
177 * Checks if \c possibleDescendant is a child of this path.
179 bool IsAncestorOf(const CTGitPath
& possibleDescendant
) const;
181 * Get a string representing the file path, optionally with a base
182 * section stripped off the front
183 * Returns a string with fwdslash paths
185 CString
GetDisplayString(const CTGitPath
* pOptionalBasePath
= NULL
) const;
187 * Compares two paths. Slash format is irrelevant.
189 static int Compare(const CTGitPath
& left
, const CTGitPath
& right
);
191 /** As PredLeftLessThanRight, but for checking if paths are equivalent
193 static bool PredLeftEquivalentToRight(const CTGitPath
& left
, const CTGitPath
& right
);
195 /** Checks if the left path is pointing to the same working copy path as the right.
196 * The same wc path means the paths are equivalent once all the admin dir path parts
197 * are removed. This is used in the TGitCache crawler to filter out all the 'duplicate'
200 static bool PredLeftSameWCPathAsRight(const CTGitPath
& left
, const CTGitPath
& right
);
202 static bool CheckChild(const CTGitPath
&parent
, const CTGitPath
& child
);
205 * appends a string to this path.
206 *\remark - missing slashes are not added - this is just a string concatenation, but with
207 * preservation of the proper caching behavior.
208 * If you want to join a file- or directory-name onto the path, you should use AppendPathString
210 void AppendRawString(const CString
& sAppend
);
213 * appends a part of a path to this path.
214 *\remark - missing slashes are dealt with properly. Don't use this to append a file extension, for example
217 void AppendPathString(const CString
& sAppend
);
220 * Get the file modification time - returns zero for files which don't exist
221 * Returns a FILETIME structure cast to an __int64, for easy comparisons
223 __int64
GetLastWriteTime() const;
226 * Get the file size. Returns zero for directories or files that don't exist.
228 __int64
GetFileSize() const;
230 bool IsReadOnly() const;
233 * Checks if the path really exists.
238 * Deletes the file/folder
239 * \param bTrash if true, uses the Windows trash bin when deleting.
241 bool Delete(bool bTrash
) const;
244 * Checks if a Subversion admin directory is present. For files, the check
245 * is done in the same directory. For folders, it checks if the folder itself
246 * contains an admin directory.
248 bool HasAdminDir() const;
249 bool HasAdminDir(CString
*ProjectTopDir
) const;
250 bool HasSubmodules() const;
251 bool HasGitSVNDir() const;
252 bool IsBisectActive() const;
253 bool IsMergeActive() const;
254 bool HasStashDir() const;
255 bool HasRebaseApply() const;
257 bool IsWCRoot() const;
259 int GetAdminDirMask() const;
262 * Checks if the path point to or below a Subversion admin directory (.Git).
264 bool IsAdminDir() const;
266 void SetCustomData(LPARAM lp
) {m_customData
= lp
;}
267 LPARAM
GetCustomData() {return m_customData
;}
270 * Checks if the path or URL is valid on Windows.
271 * A path is valid if conforms to the specs in the windows API.
272 * An URL is valid if the path checked out from it is valid
273 * on windows. That means an URL which is valid according to the WWW specs
274 * isn't necessarily valid as a windows path (e.g. http://myserver.com/repos/file:name
275 * is a valid URL, but the path is illegal on windows ("file:name" is illegal), so
276 * this function would return \c false for that URL).
278 bool IsValidOnWindows() const;
281 // All these functions are const, and all the data
282 // is mutable, in order that the hidden caching operations
283 // can be carried out on a const CTGitPath object, which is what's
284 // likely to be passed between functions
285 // The public 'SetFromxxx' functions are not const, and so the proper
286 // const-correctness semantics are preserved
287 void SetFwdslashPath(const CString
& sPath
) const;
288 void SetBackslashPath(const CString
& sPath
) const;
289 void SetUTF8FwdslashPath(const CString
& sPath
) const;
290 void EnsureBackslashPathSet() const;
291 void EnsureFwdslashPathSet() const;
293 * Checks if two path strings are equal. No conversion of slashes is done!
294 * \remark for slash-independent comparison, use IsEquivalentTo()
296 static bool ArePathStringsEqual(const CString
& sP1
, const CString
& sP2
);
297 static bool ArePathStringsEqualWithCase(const CString
& sP1
, const CString
& sP2
);
300 * Adds the required trailing slash to local root paths such as 'C:'
302 void SanitizeRootPath(CString
& sPath
, bool bIsForwardPath
) const;
304 void UpdateAttributes() const;
309 mutable CString m_sBackslashPath
;
310 mutable CString m_sLongBackslashPath
;
311 mutable CString m_sFwdslashPath
;
312 mutable CString m_sUIPath
;
313 mutable CStringA m_sUTF8FwdslashPath
;
314 mutable CStringA m_sUTF8FwdslashPathEscaped
;
315 mutable CString m_sProjectRoot
;
317 //used for rename case
318 mutable CString m_sOldFwdslashPath
;
320 // Have we yet determined if this is a directory or not?
321 mutable bool m_bDirectoryKnown
;
322 mutable bool m_bIsDirectory
;
323 mutable bool m_bLastWriteTimeKnown
;
324 mutable bool m_bURLKnown
;
325 mutable __int64 m_lastWriteTime
;
326 mutable __int64 m_fileSize
;
327 mutable bool m_bIsReadOnly
;
328 mutable bool m_bHasAdminDirKnown
;
329 mutable bool m_bHasAdminDir
;
330 mutable bool m_bIsValidOnWindowsKnown
;
331 mutable bool m_bIsValidOnWindows
;
332 mutable bool m_bIsAdminDirKnown
;
333 mutable bool m_bIsAdminDir
;
334 mutable bool m_bIsWCRootKnown
;
335 mutable bool m_bIsWCRoot
;
336 mutable bool m_bExists
;
337 mutable bool m_bExistsKnown
;
338 mutable LPARAM m_customData
;
339 mutable bool m_bIsSpecialDirectoryKnown
;
340 mutable bool m_bIsSpecialDirectory
;
342 friend bool operator<(const CTGitPath
& left
, const CTGitPath
& right
);
345 * Compares two paths and return true if left is earlier in sort order than right
346 * (Uses CTGitPath::Compare logic, but is suitable for std::sort and similar)
348 bool operator<(const CTGitPath
& left
, const CTGitPath
& right
);
351 //////////////////////////////////////////////////////////////////////////
355 * This class represents a list of paths
361 // A constructor which allows a path list to be easily built with one initial entry in
362 explicit CTGitPathList(const CTGitPath
& firstEntry
);
366 void AddPath(const CTGitPath
& newPath
);
367 bool LoadFromFile(const CTGitPath
& filename
);
368 bool WriteToFile(const CString
& sFilename
, bool bANSI
= false) const;
369 CTGitPath
* LookForGitPath(CString path
);
370 int ParserFromLog(BYTE_VECTOR
&log
, bool parseDeletes
= false);
371 int ParserFromLsFile(BYTE_VECTOR
&out
,bool staged
=true);
372 int FillUnRev(unsigned int Action
,CTGitPathList
*list
=NULL
);
373 int FillBasedOnIndexFlags(unsigned short flag
, CTGitPathList
* list
= nullptr);
376 * Load from the path argument string, when the 'path' parameter is used
377 * This is a list of paths, with '*' between them
379 void LoadFromAsteriskSeparatedString(const CString
& sPathString
);
380 CString
CreateAsteriskSeparatedString() const;
382 int GetCount() const;
383 bool IsEmpty() const;
385 const CTGitPath
& operator[](INT_PTR index
) const;
386 bool AreAllPathsFiles() const;
387 bool AreAllPathsFilesInOneDirectory() const;
388 CTGitPath
GetCommonDirectory() const;
389 CTGitPath
GetCommonRoot() const;
390 void SortByPathname(bool bReverse
= false);
392 * Delete all the files in the list, then clear the list.
393 * \param bTrash if true, the items are deleted using the Windows trash bin
395 void DeleteAllFiles(bool bTrash
, bool bFilesOnly
= true);
396 static bool DeleteViaShell(LPCTSTR path
, bool useTrashbin
);
397 /** Remove duplicate entries from the list (sorts the list as a side-effect */
398 void RemoveDuplicates();
399 /** Removes all paths which are on or in a Subversion admin directory */
400 void RemoveAdminPaths();
401 void RemovePath(const CTGitPath
& path
);
402 void RemoveItem(CTGitPath
&path
);
404 * Removes all child items and leaves only the top folders. Useful if you
405 * create the list to remove them (i.e. if you remove a parent folder, the
406 * child files and folders don't have to be deleted anymore)
408 void RemoveChildren();
410 /** Checks if two CTGitPathLists are the same */
411 bool IsEqual(const CTGitPathList
& list
);
413 /** Convert into the Git API parameter format */
414 // apr_array_header_t * MakePathArray (apr_pool_t *pool) const;
416 typedef std::vector
<CTGitPath
> PathVector
;
418 // If the list contains just files in one directory, then
419 // this contains the directory name
420 mutable CTGitPath m_commonBaseDirectory
;