OSDN Git Service

Merge remove x86 build
[tortoisegit/TortoiseGitJp.git] / src / Git / GitStatus.h
1 #pragma once\r
2 \r
3 #ifdef _MFC_VER\r
4 //#     include "SVNPrompt.h"\r
5 #endif\r
6 #include "TGitPath.h"\r
7 \r
8 #pragma warning (push,1)\r
9 typedef std::basic_string<wchar_t> wide_string;\r
10 #ifdef UNICODE\r
11 #       define stdstring wide_string\r
12 #else\r
13 #       define stdstring std::string\r
14 #endif\r
15 #pragma warning (pop)\r
16 \r
17 #include "TGitPath.h"\r
18 \r
19 typedef enum type_git_wc_status_kind\r
20 {\r
21         git_wc_status_none,\r
22         git_wc_status_unversioned,\r
23         git_wc_status_ignored,\r
24         git_wc_status_normal,\r
25         git_wc_status_external,\r
26         git_wc_status_incomplete,\r
27         git_wc_status_missing,\r
28         git_wc_status_deleted,\r
29         git_wc_status_replaced,\r
30         git_wc_status_modified,\r
31         git_wc_status_merged,\r
32         git_wc_status_added,\r
33         git_wc_status_conflicted,\r
34         git_wc_status_obstructed,\r
35 \r
36 }git_wc_status_kind;\r
37 \r
38 typedef enum\r
39 {\r
40         git_depth_empty,\r
41         git_depth_infinity,\r
42         git_depth_unknown,\r
43         git_depth_files,\r
44         git_depth_immediates,\r
45 }git_depth_t;\r
46 \r
47 \r
48 #define GIT_REV_ZERO _T("0000000000000000000000000000000000000000")\r
49 #define GIT_INVALID_REVNUM _T("")\r
50 typedef CString git_revnum_t;\r
51 typedef int git_error_t;\r
52 \r
53 typedef struct git_wc_entry_t\r
54 {\r
55         // url in repository\r
56         const char *url;\r
57 \r
58         TCHAR cmt_rev[41];\r
59 } git_wc_entry_t;\r
60 \r
61 \r
62 typedef struct git_wc_status2_t\r
63\r
64   /** The status of the entries text. */\r
65   git_wc_status_kind text_status;\r
66 \r
67   /** The status of the entries properties. */\r
68   git_wc_status_kind prop_status;\r
69 \r
70   //git_wc_entry_t *entry;\r
71 }git_wc_status2;\r
72 \r
73 #define MAX_STATUS_STRING_LENGTH                256\r
74 \r
75 \r
76 /////////////////////////////////////////////////////////////////////\r
77 // WINGIT API (replaced by commandline tool, but defs and data types kept so old code still works)\r
78 \r
79 // Flags for wgEnumFiles\r
80 enum WGENUMFILEFLAGS\r
81 {\r
82         WGEFF_NoRecurse         = (1<<0),       // only enumerate files directly in the specified path\r
83         WGEFF_FullPath          = (1<<1),       // enumerated filenames are specified with full path (instead of relative to proj root)\r
84         WGEFF_DirStatusDelta= (1<<2),   // include directories, in enumeration, that have a recursive status != WGFS_Normal (may have a slightly better performance than WGEFF_DirStatusAll)\r
85         WGEFF_DirStatusAll      = (1<<3),       // include directories, in enumeration, with recursive status\r
86         WGEFF_EmptyAsNormal     = (1<<4),       // report sub-directories, with no versioned files, as WGFS_Normal instead of WGFS_Empty\r
87         WGEFF_SingleFile        = (1<<5)        // indicates that the status of a single file or dir, specified by pszSubPath, is wanted\r
88 };\r
89 \r
90 // File status\r
91 enum WGFILESTATUS\r
92 {\r
93         WGFS_Normal,\r
94         WGFS_Modified,\r
95         WGFS_Staged,\r
96         WGFS_Added,\r
97         WGFS_Conflicted,\r
98         WGFS_Deleted,\r
99 \r
100         WGFS_Ignored = -1,\r
101         WGFS_Unversioned = -2,\r
102         WGFS_Empty = -3,\r
103         WGFS_Unknown = -4\r
104 };\r
105 \r
106 // File flags\r
107 enum WGFILEFLAGS\r
108 {\r
109         WGFF_Directory          = (1<<0)        // enumerated file is a directory\r
110 };\r
111 \r
112 struct wgFile_s\r
113 {\r
114         const char *sFileName;                  // filename or directory relative to project root (using forward slashes)\r
115         int nStatus;                                    // the WGFILESTATUS of the file\r
116         int nFlags;                                             // a combination of WGFILEFLAGS\r
117 \r
118         const BYTE* sha1;                               // points to the BYTE[20] sha1 (NULL for directories, WGFF_Directory)\r
119 };\r
120 \r
121 // Application-defined callback function for wgEnumFiles, returns TRUE to abort enumeration\r
122 // NOTE: do NOT store the pFile pointer or any pointers in wgFile_s for later use, the data is only valid for a single callback call\r
123 typedef BOOL (__cdecl WGENUMFILECB)(const struct wgFile_s *pFile, void *pUserData);\r
124 \r
125 //\r
126 /////////////////////////////////////////////////////////////////////\r
127 \r
128 \r
129 // convert wingit.dll status to git_wc_status_kind\r
130 inline static git_wc_status_kind GitStatusFromWingit(int nStatus)\r
131 {\r
132         switch (nStatus)\r
133         {\r
134         case WGFS_Normal: return git_wc_status_normal;\r
135         case WGFS_Modified: return git_wc_status_modified;\r
136         case WGFS_Staged: return git_wc_status_modified;\r
137         case WGFS_Added: return git_wc_status_added;\r
138         case WGFS_Conflicted: return git_wc_status_conflicted;\r
139         case WGFS_Deleted: return git_wc_status_deleted;\r
140 \r
141         case WGFS_Ignored: return git_wc_status_ignored;\r
142         case WGFS_Unversioned: return git_wc_status_unversioned;\r
143         case WGFS_Empty: return git_wc_status_unversioned;\r
144         }\r
145 \r
146         return git_wc_status_none;\r
147 }\r
148 \r
149 // convert 20 byte sha1 hash to the git_revnum_t type\r
150 inline static git_revnum_t ConvertHashToRevnum(const BYTE *sha1)\r
151 {\r
152         if (!sha1)\r
153                 return GIT_INVALID_REVNUM;\r
154 \r
155         char s[41];\r
156         char *p = s;\r
157         for (int i=0; i<20; i++)\r
158         {\r
159 #pragma warning(push)\r
160 #pragma warning(disable: 4996)\r
161                 sprintf(p, "%02x", (UINT)*sha1);\r
162 #pragma warning(pop)\r
163                 p += 2;\r
164                 sha1++;\r
165         }\r
166 \r
167         return CString(s);\r
168 }\r
169 \r
170 \r
171 /**\r
172  * \ingroup Git\r
173  * Handles Subversion status of working copies.\r
174  */\r
175 class GitStatus\r
176 {\r
177 public:\r
178         GitStatus(bool * pbCanceled = NULL);\r
179         ~GitStatus(void);\r
180 \r
181 \r
182         /**\r
183          * Reads the Subversion status of the working copy entry. No\r
184          * recurse is done, even if the entry is a directory.\r
185          * If the status of the text and property part are different\r
186          * then the more important status is returned.\r
187          */\r
188         static git_wc_status_kind GetAllStatus(const CTGitPath& path, git_depth_t depth = git_depth_empty);\r
189 \r
190         /**\r
191          * Reads the Subversion status of the working copy entry and all its\r
192          * subitems. The resulting status is determined by using priorities for\r
193          * each status. The status with the highest priority is then returned.\r
194          * If the status of the text and property part are different then\r
195          * the more important status is returned.\r
196          */\r
197         static git_wc_status_kind GetAllStatusRecursive(const CTGitPath& path);\r
198 \r
199         /**\r
200          * Returns the status which is more "important" of the two statuses specified.\r
201          * This is used for the "recursive" status functions on folders - i.e. which status\r
202          * should be returned for a folder which has several files with different statuses\r
203          * in it.\r
204          */                                     \r
205         static git_wc_status_kind GetMoreImportant(git_wc_status_kind status1, git_wc_status_kind status2);\r
206         \r
207         /**\r
208          * Checks if a status is "important", i.e. if the status indicates that the user should know about it.\r
209          * E.g. a "normal" status is not important, but "modified" is.\r
210          * \param status the status to check\r
211          */\r
212         static BOOL IsImportant(git_wc_status_kind status) {return (GetMoreImportant(git_wc_status_added, status)==status);}\r
213 \r
214         /**\r
215          * Reads the Subversion text status of the working copy entry. No\r
216          * recurse is done, even if the entry is a directory.\r
217          * The result is stored in the public member variable status.\r
218          * Use this method if you need detailed information about a file/folder, not just the raw status (like "normal", "modified").\r
219          * \r
220          * \param path the pathname of the entry\r
221          * \param update true if the status should be updated with the repository. Default is false.\r
222          * \return If update is set to true the HEAD revision of the repository is returned. If update is false then -1 is returned.\r
223          * \remark If the return value is -2 then the status could not be obtained.\r
224          */\r
225         git_revnum_t GetStatus(const CTGitPath& path, bool update = false, bool noignore = false, bool noexternals = false);\r
226 \r
227         /**\r
228          * Returns a string representation of a Subversion status.\r
229          * \param status the status enum\r
230          * \param string a string representation\r
231          */\r
232         static void GetStatusString(git_wc_status_kind status, size_t buflen, TCHAR * string);\r
233         static void GetStatusString(HINSTANCE hInst, git_wc_status_kind status, TCHAR * string, int size, WORD lang);\r
234 \r
235         /**\r
236          * Returns the string representation of a depth.\r
237          */\r
238 #ifdef _MFC_VER\r
239         static CString GetDepthString(git_depth_t depth);\r
240 #endif\r
241         static void GetDepthString(HINSTANCE hInst, git_depth_t depth, TCHAR * string, int size, WORD lang);\r
242 \r
243         /**\r
244          * Returns the status of the first file of the given path. Use GetNextFileStatus() to obtain\r
245          * the status of the next file in the list.\r
246          * \param path the path of the folder from where the status list should be obtained\r
247          * \param retPath the path of the file for which the status was returned\r
248          * \param update set this to true if you want the status to be updated with the repository (needs network access)\r
249          * \param recurse true to fetch the status recursively\r
250          * \param bNoIgnore true to not fetch the ignored files\r
251          * \param bNoExternals true to not fetch the status of included Git:externals\r
252          * \return the status\r
253          */\r
254         git_wc_status2_t * GetFirstFileStatus(const CTGitPath& path, CTGitPath& retPath, bool update = false, git_depth_t depth = git_depth_infinity, bool bNoIgnore = true, bool bNoExternals = false);\r
255         unsigned int GetFileCount() const {return /*apr_hash_count(m_statushash);*/0;}\r
256         unsigned int GetVersionedCount() const;\r
257         /**\r
258          * Returns the status of the next file in the file list. If no more files are in the list then NULL is returned.\r
259          * See GetFirstFileStatus() for details.\r
260          */\r
261         git_wc_status2_t * GetNextFileStatus(CTGitPath& retPath);\r
262         /**\r
263          * Checks if a path is an external folder.\r
264          * This is necessary since Subversion returns two entries for external folders: one with the status Git_wc_status_external\r
265          * and one with the 'real' status of that folder. GetFirstFileStatus() and GetNextFileStatus() only return the 'real'\r
266          * status, so with this method it's possible to check if the status also is Git_wc_status_external.\r
267          */\r
268         bool IsExternal(const CTGitPath& path) const;\r
269         /**\r
270          * Checks if a path is in an external folder.\r
271          */\r
272         bool IsInExternal(const CTGitPath& path) const;\r
273 \r
274         /**\r
275          * Clears the memory pool.\r
276          */\r
277         void ClearPool();\r
278 \r
279         /**\r
280          * This member variable hold the status of the last call to GetStatus().\r
281          */\r
282         git_wc_status2_t *                      status;                         ///< the status result of GetStatus()\r
283 \r
284         git_revnum_t                            headrev;                        ///< the head revision fetched with GetFirstStatus()\r
285 \r
286         bool *                                          m_pbCanceled;\r
287 #ifdef _MFC_VER\r
288 friend class Git;       // So that Git can get to our m_err\r
289         /**\r
290          * Returns the last error message as a CString object.\r
291          */\r
292         CString GetLastErrorMsg() const;\r
293 \r
294         /** \r
295          * Set a list of paths which will be considered when calling GetFirstFileStatus.\r
296          * If a filter is set, then GetFirstFileStatus/GetNextFileStatus will only return items which are in the filter list\r
297          */\r
298         void SetFilter(const CTGitPathList& fileList);\r
299         void ClearFilter();\r
300 \r
301 #else\r
302         /**\r
303          * Returns the last error message as a CString object.\r
304          */\r
305         stdstring GetLastErrorMsg() const;\r
306 #endif\r
307 \r
308 \r
309 protected:\r
310 //      apr_pool_t *                            m_pool;                 ///< the memory pool\r
311 private:\r
312         typedef struct sort_item\r
313         {\r
314                 const void *key;\r
315 //              apr_ssize_t klen;\r
316                 void *value;\r
317         } sort_item;\r
318 \r
319         typedef struct hashbaton_t\r
320         {\r
321                 GitStatus*              pThis;\r
322 //              apr_hash_t *    hash;\r
323 //              apr_hash_t *    exthash;\r
324         } hash_baton_t;\r
325 \r
326 //      git_client_ctx_t *                      ctx;\r
327         git_wc_status_kind                      m_allstatus;    ///< used by GetAllStatus and GetAllStatusRecursive\r
328 //      git_error_t *                           m_err;                  ///< Subversion error baton\r
329         git_error_t                                                     m_err;\r
330 \r
331         git_wc_status2_t                        m_status;               // used for GetStatus\r
332 \r
333 #ifdef _MFC_VER\r
334 //      GitPrompt                                       m_prompt;\r
335 #endif\r
336 \r
337         /**\r
338          * Returns a numeric value indicating the importance of a status. \r
339          * A higher number indicates a more important status.\r
340          */\r
341         static int GetStatusRanking(git_wc_status_kind status);\r
342 \r
343         /**\r
344          * Callback function which collects the raw status from a Git_client_status() function call\r
345          */\r
346         //static git_error_t * getallstatus (void *baton, const char *path, git_wc_status2_t *status, apr_pool_t *pool);\r
347         static BOOL getallstatus(const struct wgFile_s *pFile, void *pUserData);\r
348         static BOOL getstatus(const struct wgFile_s *pFile, void *pUserData);\r
349 \r
350         /**\r
351          * Callback function which stores the raw status from a Git_client_status() function call\r
352          * in a hash table.\r
353          */\r
354 //      static git_error_t * getstatushash (void *baton, const char *path, git_wc_status2_t *status, apr_pool_t *pool);\r
355 \r
356         /**\r
357          * helper function to sort a hash to an array\r
358          */\r
359 //      static apr_array_header_t * sort_hash (apr_hash_t *ht, int (*comparison_func) (const sort_item *,\r
360 //                                                                              const sort_item *), apr_pool_t *pool);\r
361 \r
362         /**\r
363          * Callback function used by qsort() which does the comparison of two elements\r
364          */\r
365         static int __cdecl sort_compare_items_as_paths (const sort_item *a, const sort_item *b);\r
366 \r
367         //for GetFirstFileStatus and GetNextFileStatus\r
368 //      apr_hash_t *                            m_statushash;\r
369 //      apr_array_header_t *            m_statusarray;\r
370         unsigned int                            m_statushashindex;\r
371 //      apr_hash_t *                            m_externalhash;\r
372 \r
373 #pragma warning(push)\r
374 #pragma warning(disable: 4200)\r
375         struct STRINGRESOURCEIMAGE\r
376         {\r
377                 WORD nLength;\r
378                 WCHAR achString[];\r
379         };\r
380 #pragma warning(pop)    // C4200\r
381 \r
382         static int LoadStringEx(HINSTANCE hInstance, UINT uID, LPTSTR lpBuffer, int nBufferMax, WORD wLanguage);\r
383         static git_error_t* cancel(void *baton);\r
384 \r
385         // A sorted list of filenames (in Git format, in lowercase) \r
386         // when this list is set, we only pick-up files during a GetStatus which are found in this list\r
387         typedef std::vector<std::string> StdStrAVector;\r
388         StdStrAVector m_filterFileList;\r
389 };\r
390 \r
391 \r