Beispiel #1
0
git_revnum_t GitStatus::GetStatus(const CTGitPath& path, bool update /* = false */, bool noignore /* = false */, bool noexternals /* = false */)
{
	// 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;

	CString sProjectRoot;
	if ( !path.HasAdminDir(&sProjectRoot) )
		return youngest;

	struct hashbaton_t hashbaton;
//	hashbaton.hash = statushash;
//	hashbaton.exthash = exthash;
	hashbaton.pThis = this;

#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
	{
		LPCTSTR lpszSubPath = NULL;
		CString sSubPath;
		CString s = path.GetWinPathString();
		if (s.GetLength() > sProjectRoot.GetLength())
		{
			sSubPath = 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(sProjectRoot, lpszSubPath, nFlags, &getstatus, &m_status);

		/*m_err = git_client_status4 (&youngest,
							path.GetGitApiPath(m_pool),
							&rev,
							getstatushash,
							&hashbaton,
							git_depth_empty,		//depth
							TRUE,		//getall
							update,		//update
							noignore,		//noignore
							noexternals,
							NULL,
							ctx,
							m_pool);*/
	}

	// Error present if function is not under version control
	if (m_err) /*|| (apr_hash_count(statushash) == 0)*/
	{
		status = NULL;
//		return -2;	
		return GIT_INVALID_REVNUM;
	}

	// Convert the unordered hash to an ordered, sorted array
	/*statusarray = sort_hash (statushash,
							  sort_compare_items_as_paths,
							  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;
	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;
}
int GitStatus::GetFileStatus(const CString &gitdir, const CString &pathParam, git_wc_status_kind * status,BOOL IsFull, BOOL /*IsRecursive*/,BOOL IsIgnore, FILL_STATUS_CALLBACK callback, void *pData, bool * assumeValid, bool * skipWorktree)
{
	try
	{
		CString path = pathParam;

		path.Replace(_T('\\'),_T('/'));

		CString lowcasepath =path;
		lowcasepath.MakeLower();

		if(status)
		{
			git_wc_status_kind st = git_wc_status_none;
			CGitHash hash;

			g_IndexFileMap.GetFileStatus(gitdir, path, &st, IsFull, false, callback, pData, &hash, true, assumeValid, skipWorktree);

			if( st == git_wc_status_conflicted )
			{
				*status =st;
				if (callback && assumeValid && skipWorktree)
					callback(gitdir + _T("/") + path, st, false, pData, *assumeValid, *skipWorktree);
				return 0;
			}

			if( st == git_wc_status_unversioned )
			{
				if(!IsIgnore)
				{
					*status = git_wc_status_unversioned;
					if (callback && assumeValid && skipWorktree)
						callback(gitdir + _T("/") + path, *status, false, pData, *assumeValid, *skipWorktree);
					return 0;
				}

				if (g_IgnoreList.CheckIgnoreChanged(gitdir, path, false))
				{
					g_IgnoreList.LoadAllIgnoreFile(gitdir, path, false);
				}
				if (g_IgnoreList.IsIgnore(path, gitdir, false))
				{
					st = git_wc_status_ignored;
				}
				*status = st;
				if (callback && assumeValid && skipWorktree)
					callback(gitdir + _T("/") + path, st, false, pData, *assumeValid, *skipWorktree);

				return 0;
			}

			if ((st == git_wc_status_normal || st == git_wc_status_modified) && IsFull)
			{
				{
					g_HeadFileMap.CheckHeadAndUpdate(gitdir);

					SHARED_TREE_PTR treeptr = g_HeadFileMap.SafeGet(gitdir);

					// Check Head Tree Hash;
					{
						//add item

						int start = SearchInSortVector(*treeptr, lowcasepath, -1);

						if(start<0)
						{
							*status =st=git_wc_status_added;
							CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": File miss in head tree %s"), path);
							if (callback && assumeValid && skipWorktree)
								callback(gitdir + _T("/") + path, st, false, pData, *assumeValid, *skipWorktree);
							return 0;
						}

						//staged and not commit
						if( treeptr->at(start).m_Hash != hash )
						{
							*status =st=git_wc_status_modified;
							if (callback && assumeValid && skipWorktree)
								callback(gitdir + _T("/") + path, st, false, pData, *assumeValid, *skipWorktree);
							return 0;
						}
					}
				}
			}
			*status =st;
			if (callback && assumeValid && skipWorktree)
				callback(gitdir + _T("/") + path, st, false, pData, *assumeValid, *skipWorktree);
			return 0;
		}
	}
	catch(...)
	{
		if(status)
			*status = git_wc_status_none;
		return -1;
	}

	return 0;

}
Beispiel #3
0
// static method
git_wc_status_kind GitStatus::GetAllStatus(const CTGitPath& path, git_depth_t depth)
{
	git_wc_status_kind			statuskind;
//	git_client_ctx_t * 			ctx;
	
//	apr_pool_t *				pool;
//	git_error_t *				err;
	BOOL						err;
	BOOL						isDir;
	CString						sProjectRoot;

	isDir = path.IsDirectory();
	if (!path.HasAdminDir(&sProjectRoot))
		return git_wc_status_none;

//	pool = git_pool_create (NULL);				// create the memory pool

//	git_error_clear(git_client_create_context(&ctx, pool));

//	git_revnum_t youngest = Git_INVALID_REVNUM;
//	git_opt_revision_t rev;
//	rev.kind = git_opt_revision_unspecified;
	statuskind = git_wc_status_none;

	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
	{
		// 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
	{
		LPCTSTR lpszSubPath = NULL;
		CString sSubPath;
		CString s = path.GetWinPathString();
		if (s.GetLength() > sProjectRoot.GetLength())
		{
			sSubPath = s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/);
			lpszSubPath = sSubPath;
		}

#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 = !wgEnumFiles(sProjectRoot, lpszSubPath, nFlags, &getallstatus, &statuskind);

		/*err = git_client_status4 (&youngest,
							path.GetSVNApiPath(pool),
							&rev,
							getallstatus,
							&statuskind,
							depth,
							TRUE,		//getall
							FALSE,		//update
							TRUE,		//noignore
							FALSE,		//ignore externals
							NULL,
							ctx,
							pool);*/
	}

	// Error present
	if (err != NULL)
	{
//		git_error_clear(err);
//		git_pool_destroy (pool);				//free allocated memory
		return git_wc_status_none;	
	}

//	git_pool_destroy (pool);				//free allocated memory

	return statuskind;
}