diff options
Diffstat (limited to 'bpkg/fetch-git.cxx')
-rw-r--r-- | bpkg/fetch-git.cxx | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/bpkg/fetch-git.cxx b/bpkg/fetch-git.cxx index 0c21af6..448cf49 100644 --- a/bpkg/fetch-git.cxx +++ b/bpkg/fetch-git.cxx @@ -2327,9 +2327,30 @@ namespace bpkg paths ls (find_symlinks (co, dir, prefix)); vector<pair<path, path>> links; // List of the link/target path pairs. + // Mark the being replaced in the working tree links as unchanged, + // running git-update-index(1) for multiple links per run. + // + strings unchanged_links; // Links to mark as unchanged. + + auto mark_unchanged = [&unchanged_links, &co, &dir, &failure] () + { + if (!unchanged_links.empty ()) + { + if (!run_git (co, + co.git_option (), + "-C", dir, + "update-index", + "--assume-unchanged", + unchanged_links)) + failure ("unable to mark symlinks as unchanged"); + + unchanged_links.clear (); + } + }; + // Cache/remove filesystem-agnostic symlinks. // - for (auto& l: ls) + for (path& l: ls) { path lp (dir / l); // Absolute or relative to the current directory. @@ -2390,14 +2411,14 @@ namespace bpkg // Mark the symlink as unchanged and remove it. // - if (!run_git (co, - co.git_option (), - "-C", dir, - "update-index", - "--assume-unchanged", - l)) - failure ("unable to mark symlink '" + l.string () + - "' as unchanged"); + // Note that we restrict the batch to 100 symlinks not to exceed the + // Windows command line max size, which is about 32K, and assuming + // that _MAX_PATH is 256 characters. + // + unchanged_links.push_back (l.string ()); + + if (unchanged_links.size () == 100) + mark_unchanged (); links.emplace_back (move (l), move (t)); @@ -2405,6 +2426,8 @@ namespace bpkg r = true; } + mark_unchanged (); // Mark the rest. + // Create real links (hardlinks, symlinks, and junctions). // while (!links.empty ()) |