aboutsummaryrefslogtreecommitdiff
path: root/bpkg/fetch-git.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/fetch-git.cxx')
-rw-r--r--bpkg/fetch-git.cxx41
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 ())