Index: RepositoryBrowser.cpp
===================================================================
--- RepositoryBrowser.cpp	(revision 27484)
+++ RepositoryBrowser.cpp	(working copy)
@@ -845,6 +845,7 @@
         CheckoutDepthForItem(hRoot);
         FilterInfinityDepthItems(m_checkoutDepths);
         FilterInfinityDepthItems(m_updateDepths);
+        FilterUnknownDepthItems(m_updateDepths);
     }
 
     ++m_blockEvents;
@@ -4709,31 +4710,21 @@
     {
         m_checkoutDepths[pItem->url] = svn_depth_infinity;
         m_updateDepths[pItem->url] = svn_depth_infinity;
-        if (!pItem->children_fetched && (pItem->kind == svn_node_dir))
+
+        // If the directory was not expanded and a sticky depth is already set for it in the
+        // working copy, we can simply fetch the node with unknown depth, causing SVN to update
+        // the directory with working-copy depth. Otherwise, if we have no sticky depth yet, we
+        // can assume that the user has just selected the node without expanding it. In that case,
+        // we want to update the directory in a fully recursive way.
+        //
+        // Furthermore, if the user has re-checked the item without expanding its children, we assume
+        // that the user is requesting a fully recursive checkout of the directory.
+        if (!pItem->children_fetched && !pItem->checkbox_toggled && (pItem->kind == svn_node_dir))
         {
             auto foundWCDepth = m_wcDepths.find(pItem->url);
             if (foundWCDepth != m_wcDepths.end())
             {
-                m_updateDepths[pItem->url] = foundWCDepth->second;
-                if (foundWCDepth->second != svn_depth_infinity)
-                {
-                    // add all child states as well
-                    for (const auto& wcdepth : m_wcDepths)
-                    {
-                        if (wcdepth.first.GetLength() > pItem->url.GetLength())
-                        {
-                            CString sUrl = wcdepth.first.Left(pItem->url.GetLength());
-                            if (pItem->url.Compare(sUrl) == 0)
-                            {
-                                if (wcdepth.first[pItem->url.GetLength()] == '/')
-                                {
-                                    m_updateDepths[wcdepth.first] = wcdepth.second;
-                                    m_updateDepths[pItem->url] = svn_depth_unknown;
-                                }
-                            }
-                        }
-                    }
-                }
+                m_updateDepths[pItem->url] = svn_depth_unknown;
             }
         }
     }
@@ -4806,9 +4797,15 @@
 // unchecked -> checked whole subtree -> unchecked whole subtree
 void CRepositoryBrowser::CheckTreeItem( HTREEITEM hItem, bool bCheck )
 {
+    CTreeItem * pItem = (CTreeItem *)m_RepoTree.GetItemData(hItem);
     bool itemExpanded = !!(m_RepoTree.GetItemState(hItem, TVIS_EXPANDED) & TVIS_EXPANDED);
     bool multiselectMode = m_RepoTree.GetSelectedCount() > 1;
 
+    if (pItem)
+    {
+        pItem->checkbox_toggled = true;
+    }
+
     // tri-state logic will be emulated for expanded, checked items, in single selection mode,
     // with at least one child, when all children unchecked
     if(!bCheck && !multiselectMode && itemExpanded && m_RepoTree.GetChildItem(hItem) != NULL && HaveAllChildrenSameCheckState(hItem))
@@ -4840,7 +4837,6 @@
         {
             // clear the wc depth state of this item so it won't get used
             // later in the OnOK handler in case this item is not expanded.
-            CTreeItem * pItem = (CTreeItem *)m_RepoTree.GetItemData(hItem);
             if (pItem)
             {
                 m_wcDepths.erase(pItem->url);
@@ -4929,6 +4925,35 @@
     }
 }
 
+void CRepositoryBrowser::FilterUnknownDepthItems(std::map<CString,svn_depth_t>& depths)
+{
+    if (depths.empty())
+        return;
+
+    // now go through the whole list and remove all children with unknown depth having a parent with unknown depth
+    for (std::map<CString,svn_depth_t>::iterator it = depths.begin(); it != depths.end(); ++it)
+    {
+        if (it->second != svn_depth_unknown)
+            continue;
+
+        for (std::map<CString,svn_depth_t>::iterator it2 = depths.begin(); it2 != depths.end(); ++it2)
+        {
+            if (it->first.Compare(it2->first)==0)
+                continue;
+            if (it2->second != svn_depth_unknown)
+                continue;
+
+            CString url1 = it->first + L"/";
+            if (url1.Compare(it2->first.Left(url1.GetLength()))==0)
+            {
+                std::map<CString,svn_depth_t>::iterator kill = it2;
+                --it2;
+                depths.erase(kill);
+            }
+        }
+    }
+}
+
 void CRepositoryBrowser::SetListItemInfo( int index, const CItem * it )
 {
     if (it->is_external)
Index: RepositoryBrowser.h
===================================================================
--- RepositoryBrowser.h	(revision 27484)
+++ RepositoryBrowser.h	(working copy)
@@ -48,6 +48,7 @@
 public:
     CTreeItem()
         : children_fetched(false)
+        , checkbox_toggled(false)
         , has_child_folders(false)
         , is_external(false)
         , kind(svn_node_unknown)
@@ -64,6 +65,7 @@
     CString         logicalPath;                ///< concatenated unescapedname values
     bool            is_external;                ///< if set, several operations may not be available
     bool            children_fetched;           ///< whether the contents of the folder are known/fetched or not
+    bool            checkbox_toggled;           ///< whether the checkbox has been modified by the user
     bool            has_child_folders;
     bool            unversioned;
     std::deque<CItem>    children;
@@ -292,6 +294,7 @@
 
     void ShowText(const CString& sText, bool forceupdate = false);
     static void FilterInfinityDepthItems(std::map<CString,svn_depth_t>& depths);
+    static void CRepositoryBrowser::FilterUnknownDepthItems(std::map<CString,svn_depth_t>& depths);
     void SetListItemInfo( int index, const CItem * it );
 
     bool RunStartCommit(const CTSVNPathList& pathlist, CString& sLogMsg);
Index: SVNProgressDlg.cpp
===================================================================
--- SVNProgressDlg.cpp	(revision 27484)
+++ SVNProgressDlg.cpp	(working copy)
@@ -2564,9 +2564,11 @@
     sWindowTitle.LoadString(IDS_PROGRS_TITLE_CHECKOUT);
     SetBackgroundImage(IDI_CHECKOUT_BKG);
 
+    std::map<CString, svn_depth_t> unknowns;
     CString sCmdInfo;
     int index = 0;
     CString rootUrl;
+
     for (std::map<CString,svn_depth_t>::iterator it = m_pathdepths.begin(); it != m_pathdepths.end(); ++it)
     {
         if (index == 0)
@@ -2583,6 +2585,7 @@
         }
         if ((depth == svn_depth_unknown)&&(checkoutdir.Exists()))
         {
+            unknowns[it->first] = it->second;
             ++index;
             continue;
         }
@@ -2640,6 +2643,30 @@
         ++index;
     }
 
+    for (std::map<CString,svn_depth_t>::iterator it = unknowns.begin(); it != unknowns.end(); ++it)
+    {
+        CTSVNPath url = CTSVNPath(it->first);
+        CTSVNPath checkoutdir = m_targetPathList[0];
+        CString dir = it->first.Mid(rootUrl.GetLength());
+        if (it->first.Compare((LPCWSTR)rootUrl)!=0)
+        {
+            dir = CPathUtils::PathUnescape(dir);
+            checkoutdir.AppendPathString(dir);
+            dir.TrimLeft('/');
+        }
+
+        CAppUtils::SetWindowTitle(m_hWnd, url.GetUIFileOrDirectoryName(), sWindowTitle);
+        sCmdInfo.FormatMessage(IDS_PROGRS_CMD_SPARSEUPDATE, (LPCTSTR)dir, (LPCTSTR)SVNStatus::GetDepthString(svn_depth_unknown));
+        ReportCmd(sCmdInfo);
+
+        CBlockCacheForPath cacheBlock(checkoutdir.GetWinPath());
+        if (!Update(CTSVNPathList(checkoutdir), m_Revision, svn_depth_unknown, true, (m_options & ProgOptIgnoreExternals) != 0, true, false))
+        {
+            ReportSVNError();
+            return false;
+        }
+    }
+
     DWORD exitcode = 0;
     CString error;
     CHooks::Instance().SetProjectProperties(m_targetPathList.GetCommonRoot(), m_ProjectProperties);

