Fixed issue #2488: BrowseRefsDlg: Option to hide nested refs
[TortoiseGit.git] / src / Git / TGitPath.h
blob7485f93aec8920d31cc26c7cc7209a7f7b93b9bf
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2015 - TortoiseGit
4 // Copyright (C) 2003-2008, 2014 - 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.
21 #pragma once
22 #include "gittype.h"
24 #define PARENT_MASK 0xFFFFFF
25 #define MERGE_MASK (0x1000000)
27 class CTGitPath
29 public:
30 CTGitPath(void);
31 ~CTGitPath(void);
32 CTGitPath(const CString& sUnknownPath);
33 int m_Stage;
34 int m_ParentNo;
35 public:
36 #pragma warning(push)
37 #pragma warning(disable: 4480) // nonstandard extension used: specifying underlying type for enum 'enum'
38 enum : unsigned int
40 LOGACTIONS_ADDED = 0x00000001,
41 LOGACTIONS_MODIFIED = 0x00000002,
42 LOGACTIONS_REPLACED = 0x00000004,
43 LOGACTIONS_DELETED = 0x00000008,
44 LOGACTIONS_UNMERGED = 0x00000010,
45 LOGACTIONS_COPY = 0x00000040,
46 LOGACTIONS_MERGED = 0x00000080,
47 LOGACTIONS_ASSUMEVALID = 0x00000200,
48 LOGACTIONS_SKIPWORKTREE = 0x00000400,
49 LOGACTIONS_UNVER = 0x80000000,
50 LOGACTIONS_IGNORE = 0x40000000,
52 // For log filter only
53 LOGACTIONS_HIDE = 0x20000000,
54 LOGACTIONS_GRAY = 0x10000000,
56 #pragma warning(pop)
58 CString m_StatAdd;
59 CString m_StatDel;
60 unsigned int m_Action;
61 bool m_Checked;
62 int ParserAction(BYTE action);
63 int ParserAction(git_delta_t action);
64 CString GetActionName();
65 static CString GetActionName(int action);
66 /**
67 * Set the path as an UTF8 string with forward slashes
69 void SetFromGit(const char* pPath);
70 void SetFromGit(const char* pPath, bool bIsDirectory);
71 void SetFromGit(const TCHAR* pPath, bool bIsDirectory);
72 void SetFromGit(const CString& sPath,CString *OldPath=NULL);
74 /**
75 * Set the path as UNICODE with backslashes
77 void SetFromWin(LPCTSTR pPath);
78 void SetFromWin(const CString& sPath);
79 void SetFromWin(LPCTSTR pPath, bool bIsDirectory);
80 void SetFromWin(const CString& sPath, bool bIsDirectory);
81 /**
82 * Set the path from an unknown source.
84 void SetFromUnknown(const CString& sPath);
85 /**
86 * Returns the path in Windows format, i.e. with backslashes
88 LPCTSTR GetWinPath() const;
89 /**
90 * Returns the path in Windows format, i.e. with backslashes
92 const CString& GetWinPathString() const;
93 /**
94 * Returns the path with forward slashes.
96 const CString& GetGitPathString() const;
98 const CString& GetGitOldPathString() const;
101 * Returns the path for showing in an UI.
103 * URL's are returned with forward slashes, unescaped if necessary
104 * Paths are returned with backward slashes
106 const CString& GetUIPathString() const;
108 * Returns true if the path points to a directory
110 bool IsDirectory() const;
112 CTGitPath GetSubPath(const CTGitPath &root);
115 * Returns the directory. If the path points to a directory, then the path
116 * is returned unchanged. If the path points to a file, the path to the
117 * parent directory is returned.
119 CTGitPath GetDirectory() const;
121 * Returns the the directory which contains the item the path refers to.
122 * If the path is a directory, then this returns the directory above it.
123 * If the path is to a file, then this returns the directory which contains the path
124 * parent directory is returned.
126 CTGitPath GetContainingDirectory() const;
128 * Get the 'root path' (e.g. "c:\") - Used to pass to GetDriveType
130 CString GetRootPathString() const;
132 * Returns the filename part of the full path.
133 * \remark don't call this for directories.
135 CString GetFilename() const;
136 CString GetBaseFilename() const;
138 * Returns the item's name without the full path.
140 CString GetFileOrDirectoryName() const;
142 * Returns the item's name without the full path, unescaped if necessary.
144 CString GetUIFileOrDirectoryName() const;
146 * Returns the file extension, including the dot.
147 * \remark Returns an empty string for directories
149 CString GetFileExtension() const;
151 bool IsEmpty() const;
152 void Reset();
154 * Checks if two paths are equal. The slashes are taken care of.
156 bool IsEquivalentTo(const CTGitPath& rhs) const;
157 bool IsEquivalentToWithoutCase(const CTGitPath& rhs) const;
158 bool operator==(const CTGitPath& x) const {return IsEquivalentTo(x);}
161 * Checks if \c possibleDescendant is a child of this path.
163 bool IsAncestorOf(const CTGitPath& possibleDescendant) const;
165 * Get a string representing the file path, optionally with a base
166 * section stripped off the front
167 * Returns a string with fwdslash paths
169 CString GetDisplayString(const CTGitPath* pOptionalBasePath = NULL) const;
171 * Compares two paths. Slash format is irrelevant.
173 static int Compare(const CTGitPath& left, const CTGitPath& right);
175 /** As PredLeftLessThanRight, but for checking if paths are equivalent
177 static bool PredLeftEquivalentToRight(const CTGitPath& left, const CTGitPath& right);
179 /** Checks if the left path is pointing to the same working copy path as the right.
180 * The same wc path means the paths are equivalent once all the admin dir path parts
181 * are removed. This is used in the TGitCache crawler to filter out all the 'duplicate'
182 * paths to crawl.
184 static bool PredLeftSameWCPathAsRight(const CTGitPath& left, const CTGitPath& right);
186 static bool CheckChild(const CTGitPath &parent, const CTGitPath& child);
189 * appends a string to this path.
190 *\remark - missing slashes are not added - this is just a string concatenation, but with
191 * preservation of the proper caching behavior.
192 * If you want to join a file- or directory-name onto the path, you should use AppendPathString
194 void AppendRawString(const CString& sAppend);
197 * appends a part of a path to this path.
198 *\remark - missing slashes are dealt with properly. Don't use this to append a file extension, for example
201 void AppendPathString(const CString& sAppend);
204 * Get the file modification time - returns zero for files which don't exist
205 * Returns a FILETIME structure cast to an __int64, for easy comparisons
207 __int64 GetLastWriteTime() const;
210 * Get the file size. Returns zero for directories or files that don't exist.
212 __int64 GetFileSize() const;
214 bool IsReadOnly() const;
217 * Checks if the path really exists.
219 bool Exists() const;
222 * Deletes the file/folder
223 * \param bTrash if true, uses the Windows trash bin when deleting.
225 bool Delete(bool bTrash, bool bShowErrorUI) const;
228 * Checks if a git admin directory is present. For files, the check
229 * is done in the same directory. For folders, it checks if the folder itself
230 * contains an admin directory.
232 bool HasAdminDir() const;
233 bool HasAdminDir(CString *ProjectTopDir) const;
234 bool HasSubmodules() const;
235 bool HasGitSVNDir() const;
236 bool IsBisectActive() const;
237 bool IsMergeActive() const;
238 bool HasStashDir() const;
239 bool HasRebaseApply() const;
241 bool IsWCRoot() const;
243 int GetAdminDirMask() const;
246 * Checks if the path point to or below a git admin directory (.Git).
248 bool IsAdminDir() const;
250 void SetCustomData(LPARAM lp) {m_customData = lp;}
251 LPARAM GetCustomData() const {return m_customData;}
254 * Checks if the path or URL is valid on Windows.
255 * A path is valid if conforms to the specs in the windows API.
256 * An URL is valid if the path checked out from it is valid
257 * on windows. That means an URL which is valid according to the WWW specs
258 * isn't necessarily valid as a windows path (e.g. http://myserver.com/repos/file:name
259 * is a valid URL, but the path is illegal on windows ("file:name" is illegal), so
260 * this function would return \c false for that URL).
262 bool IsValidOnWindows() const;
264 private:
265 // All these functions are const, and all the data
266 // is mutable, in order that the hidden caching operations
267 // can be carried out on a const CTGitPath object, which is what's
268 // likely to be passed between functions
269 // The public 'SetFromxxx' functions are not const, and so the proper
270 // const-correctness semantics are preserved
271 void SetFwdslashPath(const CString& sPath) const;
272 void SetBackslashPath(const CString& sPath) const;
273 void SetUTF8FwdslashPath(const CString& sPath) const;
274 void EnsureBackslashPathSet() const;
275 void EnsureFwdslashPathSet() const;
277 * Checks if two path strings are equal. No conversion of slashes is done!
278 * \remark for slash-independent comparison, use IsEquivalentTo()
280 static bool ArePathStringsEqual(const CString& sP1, const CString& sP2);
281 static bool ArePathStringsEqualWithCase(const CString& sP1, const CString& sP2);
284 * Adds the required trailing slash to local root paths such as 'C:'
286 void SanitizeRootPath(CString& sPath, bool bIsForwardPath) const;
288 void UpdateAttributes() const;
292 private:
293 mutable CString m_sBackslashPath;
294 mutable CString m_sLongBackslashPath;
295 mutable CString m_sFwdslashPath;
296 mutable CString m_sUIPath;
297 mutable CStringA m_sUTF8FwdslashPath;
298 mutable CStringA m_sUTF8FwdslashPathEscaped;
299 mutable CString m_sProjectRoot;
301 //used for rename case
302 mutable CString m_sOldFwdslashPath;
304 // Have we yet determined if this is a directory or not?
305 mutable bool m_bDirectoryKnown;
306 mutable bool m_bIsDirectory;
307 mutable bool m_bLastWriteTimeKnown;
308 mutable bool m_bURLKnown;
309 mutable __int64 m_lastWriteTime;
310 mutable __int64 m_fileSize;
311 mutable bool m_bIsReadOnly;
312 mutable bool m_bHasAdminDirKnown;
313 mutable bool m_bHasAdminDir;
314 mutable bool m_bIsValidOnWindowsKnown;
315 mutable bool m_bIsValidOnWindows;
316 mutable bool m_bIsAdminDirKnown;
317 mutable bool m_bIsAdminDir;
318 mutable bool m_bIsWCRootKnown;
319 mutable bool m_bIsWCRoot;
320 mutable bool m_bExists;
321 mutable bool m_bExistsKnown;
322 mutable LPARAM m_customData;
323 mutable bool m_bIsSpecialDirectoryKnown;
324 mutable bool m_bIsSpecialDirectory;
326 friend bool operator<(const CTGitPath& left, const CTGitPath& right);
329 * Compares two paths and return true if left is earlier in sort order than right
330 * (Uses CTGitPath::Compare logic, but is suitable for std::sort and similar)
332 bool operator<(const CTGitPath& left, const CTGitPath& right);
335 //////////////////////////////////////////////////////////////////////////
338 * \ingroup Utils
339 * This class represents a list of paths
341 class CTGitPathList
343 public:
344 CTGitPathList();
345 // A constructor which allows a path list to be easily built with one initial entry in
346 explicit CTGitPathList(const CTGitPath& firstEntry);
347 int m_Action;
349 public:
350 void AddPath(const CTGitPath& newPath);
351 bool LoadFromFile(const CTGitPath& filename);
352 bool WriteToFile(const CString& sFilename, bool bANSI = false) const;
353 CTGitPath * LookForGitPath(CString path);
354 int ParserFromLog(BYTE_VECTOR &log, bool parseDeletes = false);
355 int ParserFromLsFile(BYTE_VECTOR &out,bool staged=true);
356 int FillUnRev(unsigned int Action, CTGitPathList *list = nullptr, CString *err = nullptr);
357 int FillBasedOnIndexFlags(unsigned short flag, CTGitPathList* list = nullptr);
358 int GetAction();
360 * Load from the path argument string, when the 'path' parameter is used
361 * This is a list of paths, with '*' between them
363 void LoadFromAsteriskSeparatedString(const CString& sPathString);
364 CString CreateAsteriskSeparatedString() const;
366 int GetCount() const;
367 bool IsEmpty() const;
368 void Clear();
369 const CTGitPath& operator[](INT_PTR index) const;
370 bool AreAllPathsFiles() const;
371 bool AreAllPathsFilesInOneDirectory() const;
372 CTGitPath GetCommonDirectory() const;
373 CTGitPath GetCommonRoot() const;
374 void SortByPathname(bool bReverse = false);
376 * Delete all the files in the list, then clear the list.
377 * \param bTrash if true, the items are deleted using the Windows trash bin
378 * \param bShowErrorUI if true, show error dialog box when error occurs.
380 void DeleteAllFiles(bool bTrash, bool bFilesOnly = true, bool bShowErrorUI = false);
381 static bool DeleteViaShell(LPCTSTR path, bool useTrashbin, bool bShowErrorUI);
382 /** Remove duplicate entries from the list (sorts the list as a side-effect */
383 void RemoveDuplicates();
384 /** Removes all paths which are on or in a git admin directory */
385 void RemoveAdminPaths();
386 void RemovePath(const CTGitPath& path);
387 void RemoveItem(CTGitPath &path);
389 * Removes all child items and leaves only the top folders. Useful if you
390 * create the list to remove them (i.e. if you remove a parent folder, the
391 * child files and folders don't have to be deleted anymore)
393 void RemoveChildren();
395 /** Checks if two CTGitPathLists are the same */
396 bool IsEqual(const CTGitPathList& list);
398 typedef std::vector<CTGitPath> PathVector;
399 PathVector m_paths;
400 // If the list contains just files in one directory, then
401 // this contains the directory name
402 mutable CTGitPath m_commonBaseDirectory;