private Tree GetOrCreateWorkspaceTree()
        {
            // Creating a Tree object for a Workspace is relatively expensive.  It requires reading all the files
            // on disk.  Given that we are the primary updaters of the tree we can safely cache the tree value to
            // avoid the operation.
            if (_cachedWorkspaceTree == null)
            {
                _cachedWorkspaceTree = GitUtils.CreateTreeFromWorkspace(_workspace, _workspacePath, _repository.ObjectDatabase);
            }

            return(_cachedWorkspaceTree);
        }
        /// <summary>
        /// Apply the specific commit to the Workspace.  This method assumes the Workspace is in a good
        /// state at the time the application of the commit occurs.
        /// <return>True if the operation was completed successfully (or there was simply no work to do)</return>
        /// </summary>
        private bool ApplyCommitToWorkspaceCore(CommitRange commitRange)
        {
            Debug.Assert(!HasPendingChangesBesidesLock());

            var newCommit = commitRange.NewCommit;

            _host.Status("Applying {0}", newCommit);

            // Note: This is a suboptimal way of building the tree.  The file system can be changed by
            // local builds and such.  Much better to build directly from the Workspace object.
            var workspaceTree = GitUtils.CreateTreeFromWorkspace(_workspace, _workspacePath, _repository.ObjectDatabase);
            var treeChanges   = _repository.Diff.Compare <TreeChanges>(workspaceTree, newCommit.Tree, compareOptions: new LibGit2Sharp.CompareOptions()
            {
                Similarity = SimilarityOptions.Renames
            });

            if (!treeChanges.Any())
            {
                _host.Status("No changes to apply");
                return(true);
            }

            if (!ApplyGitChangeToWorkspace(treeChanges))
            {
                return(false);
            }

            var ownerInfo = GetCommitOwnerInfo(commitRange.NewCommit);

            var checkinMessage = CreateCheckinMessage(commitRange, ownerInfo.UserDisplayName);

            if (_confirmBeforeCheckin && !ConfirmCheckin(newCommit, checkinMessage))
            {
                return(false);
            }

            try
            {
                _workspace.CheckIn(
                    _workspace.GetPendingChanges(),
                    author: ownerInfo.MappedTfsAuthorName,
                    comment: checkinMessage,
                    checkinNote: null,
                    workItemChanges: null,
                    policyOverride: null);
                _cachedWorkspaceTree = newCommit.Tree;
            }
            catch (Exception ex)
            {
                _host.Error("Unable to complete checkin: {0}", ex.Message);
                _cachedWorkspaceTree = null;
                return(false);
            }

            _host.Status("Checkin complete for {0}", commitRange.NewCommit.Sha);

            // The check in will undo the lock so re-lock now
            if (_lockWorkspacePath)
            {
                LockWorkspacePath();
            }

            return(true);
        }