X-Git-Url: http://git.sourceforge.jp/view?p=tortoisegit%2FTortoiseGitJp.git;a=blobdiff_plain;f=src%2FGit%2FGitStatus.cpp;h=c2032a8a98f365f9535d84c7a3c9a294850d9dea;hp=0d47c48236f4dd50688f95ccf55b766fe956cf42;hb=9be52fb6cac4a5460b6db9fb63f84d1e5c54952f;hpb=494a73c5e5b662fada8f48ad88b7c2a554bebce1;ds=sidebyside diff --git a/src/Git/GitStatus.cpp b/src/Git/GitStatus.cpp index 0d47c48..c2032a8 100644 --- a/src/Git/GitStatus.cpp +++ b/src/Git/GitStatus.cpp @@ -18,6 +18,11 @@ // #include "stdafx.h" +#ifdef _TORTOISESHELL +#include "ShellExt.h" +#else +#include "registry.h" +#endif //#include "resource.h" #include "..\TortoiseShell\resource.h" //#include "git_config.h" @@ -32,7 +37,10 @@ //# include "TGitPath.h" //# include "PathUtils.h" #endif +#include "git.h" +#include "gitindex.h" +CGitIndexFileMap g_IndexFileMap; GitStatus::GitStatus(bool * pbCanceled) : status(NULL) @@ -212,25 +220,54 @@ git_wc_status_kind GitStatus::GetAllStatus(const CTGitPath& path, git_depth_t de // rev.kind = git_opt_revision_unspecified; statuskind = git_wc_status_none; - // TODO: not sure what to do with recursivenes, it's very unclear exactly what svn does, wingit will however return - // the correct (recursive) status for folders, so WGEFF_NoRecurse can be specified to avoid unecessary processing - //const BOOL bIsRecursive = (depth == git_depth_infinity || depth == git_depth_unknown); // taken from SVN source - UINT nFlags = WGEFF_DirStatusAll; - //if (!bIsRecursive) - nFlags |= WGEFF_NoRecurse; - - LPCSTR lpszSubPath = NULL; - CStringA sSubPath; - CString s = path.GetDirectory().GetWinPathString(); - if (s.GetLength() > sProjectRoot.GetLength()) + const BOOL bIsRecursive = (depth == git_depth_infinity || depth == git_depth_unknown); // taken from SVN source + +#ifdef _TORTOISESHELL + if (g_ShellCache.GetCacheType() == ShellCache::dll) +#else + if ((DWORD)CRegStdWORD(_T("Software\\TortoiseGit\\CacheType"), GetSystemMetrics(SM_REMOTESESSION) ? 2 : 1) == 2) +#endif { - sSubPath = CStringA(s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/)); - lpszSubPath = sSubPath; + // gitindex.h based status + + CString sSubPath; + CString s = path.GetWinPathString(); + if (s.GetLength() > sProjectRoot.GetLength()) + { + sSubPath = CStringA(s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/)); + } + + err = g_IndexFileMap.GetFileStatus(sProjectRoot,sSubPath,&statuskind); } + else + { + LPCSTR lpszSubPath = NULL; + CStringA sSubPath; + CString s = path.GetWinPathString(); + if (s.GetLength() > sProjectRoot.GetLength()) + { + sSubPath = CStringA(s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/)); + lpszSubPath = sSubPath; + } - err = !wgEnumFiles(CStringA(sProjectRoot), lpszSubPath, nFlags, &getallstatus, &statuskind); +#if 1 + // when recursion enabled, let wingit determine the recursive status for folders instead of enumerating all files here + UINT nFlags = WGEFF_SingleFile; + if (!bIsRecursive) + nFlags |= WGEFF_NoRecurse; + if (!lpszSubPath) + // report root dir as normal (otherwise it could be considered git_wc_status_unversioned, which would be wrong?) + nFlags |= WGEFF_EmptyAsNormal; +#else + // enumerate all files, recursively if requested + UINT nFlags = 0; + if (!bIsRecursive) + nFlags |= WGEFF_NoRecurse; +#endif - /*err = git_client_status4 (&youngest, + err = !wgEnumFiles(CStringA(sProjectRoot), lpszSubPath, nFlags, &getallstatus, &statuskind); + + /*err = git_client_status4 (&youngest, path.GetSVNApiPath(pool), &rev, getallstatus, @@ -243,6 +280,7 @@ git_wc_status_kind GitStatus::GetAllStatus(const CTGitPath& path, git_depth_t de NULL, ctx, pool);*/ + } // Error present if (err != NULL) @@ -308,23 +346,73 @@ int GitStatus::GetStatusRanking(git_wc_status_kind status) git_revnum_t GitStatus::GetStatus(const CTGitPath& path, bool update /* = false */, bool noignore /* = false */, bool noexternals /* = false */) { -#if 0 - apr_hash_t * statushash; - apr_hash_t * exthash; - apr_array_header_t * statusarray; - const sort_item* item; + // NOTE: unlike the SVN version this one does not cache the enumerated files, because in practice no code in all of + // Tortoise uses this, all places that call GetStatus create a temp GitStatus object which gets destroyed right + // after the call again + +// apr_hash_t * statushash; +// apr_hash_t * exthash; +// apr_array_header_t * statusarray; +// const sort_item* item; - git_error_clear(m_err); - statushash = apr_hash_make(m_pool); - exthash = apr_hash_make(m_pool); - git_revnum_t youngest = Git_INVALID_REVNUM; - git_opt_revision_t rev; - rev.kind = git_opt_revision_unspecified; +// git_error_clear(m_err); +// statushash = apr_hash_make(m_pool); +// exthash = apr_hash_make(m_pool); + git_revnum_t youngest = GIT_INVALID_REVNUM; +// git_opt_revision_t rev; +// rev.kind = git_opt_revision_unspecified; + + CString sProjectRoot; + if ( !path.HasAdminDir(&sProjectRoot) ) + return youngest; + struct hashbaton_t hashbaton; - hashbaton.hash = statushash; - hashbaton.exthash = exthash; +// hashbaton.hash = statushash; +// hashbaton.exthash = exthash; hashbaton.pThis = this; - m_err = git_client_status4 (&youngest, + +#ifdef _TORTOISESHELL + if (g_ShellCache.GetCacheType() == ShellCache::dll) +#else + if ((DWORD)CRegStdWORD(_T("Software\\TortoiseGit\\CacheType"), GetSystemMetrics(SM_REMOTESESSION) ? 2 : 1) == 2) +#endif + { + // gitindex.h based status + + CString sSubPath; + CString s = path.GetWinPathString(); + if (s.GetLength() > sProjectRoot.GetLength()) + { + sSubPath = CString(s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/)); + } + + m_status.prop_status = m_status.text_status = git_wc_status_none; + + m_err = g_IndexFileMap.GetFileStatus(sProjectRoot,sSubPath,&m_status.text_status); + } + else + { + LPCSTR lpszSubPath = NULL; + CStringA sSubPath; + CString s = path.GetWinPathString(); + if (s.GetLength() > sProjectRoot.GetLength()) + { + sSubPath = CStringA(s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/)); + lpszSubPath = sSubPath; + } + + // when recursion enabled, let wingit determine the recursive status for folders instead of enumerating all files here + UINT nFlags = WGEFF_SingleFile | WGEFF_NoRecurse; + if (!lpszSubPath) + // report root dir as normal (otherwise it could be considered git_wc_status_unversioned, which would be wrong?) + nFlags |= WGEFF_EmptyAsNormal; + + m_status.prop_status = m_status.text_status = git_wc_status_none; + + // NOTE: currently wgEnumFiles will not enumerate file if it isn't versioned (so status will be git_wc_status_none) + m_err = !wgEnumFiles(CStringA(sProjectRoot), lpszSubPath, nFlags, &getstatus, &m_status); + + /*m_err = git_client_status4 (&youngest, path.GetGitApiPath(m_pool), &rev, getstatushash, @@ -336,29 +424,36 @@ git_revnum_t GitStatus::GetStatus(const CTGitPath& path, bool update /* = false noexternals, NULL, ctx, - m_pool); - + m_pool);*/ + } // Error present if function is not under version control - if ((m_err != NULL) || (apr_hash_count(statushash) == 0)) + if (m_err) /*|| (apr_hash_count(statushash) == 0)*/ { status = NULL; - return -2; +// return -2; + return GIT_INVALID_REVNUM; } // Convert the unordered hash to an ordered, sorted array - statusarray = sort_hash (statushash, + /*statusarray = sort_hash (statushash, sort_compare_items_as_paths, - m_pool); + m_pool);*/ // only the first entry is needed (no recurse) - item = &APR_ARRAY_IDX (statusarray, 0, const sort_item); - - status = (git_wc_status2_t *) item->value; +// item = &APR_ARRAY_IDX (statusarray, 0, const sort_item); +// status = (git_wc_status2_t *) item->value; + status = &m_status; + + if (update) + { + // done to match TSVN functionality of this function (not sure if any code uses the reutrn val) + // if TGit does not need this, then change the return type of function + youngest = g_Git.GetHash(CString(_T("HEAD"))); + } + return youngest; -#endif - return CString(""); } git_wc_status2_t * GitStatus::GetFirstFileStatus(const CTGitPath& path, CTGitPath& retPath, bool update, git_depth_t depth, bool bNoIgnore /* = true */, bool bNoExternals /* = false */) @@ -743,6 +838,13 @@ BOOL GitStatus::getallstatus(const struct wgFile_s *pFile, void *pUserData) return FALSE; } +BOOL GitStatus::getstatus(const struct wgFile_s *pFile, void *pUserData) +{ + git_wc_status2_t * s = (git_wc_status2_t*)pUserData; + s->prop_status = s->text_status = GitStatus::GetMoreImportant(s->prop_status, GitStatusFromWingit(pFile->nStatus)); + return FALSE; +} + #if 0 git_error_t * GitStatus::getallstatus(void * baton, const char * /*path*/, git_wc_status2_t * status, apr_pool_t * /*pool*/) {