From da38351221998c74b67f33aecd3cb0873bfce6ad Mon Sep 17 00:00:00 2001 From: Denis Kudelin Date: Thu, 8 Aug 2024 17:09:16 +0300 Subject: [PATCH] Add support for long file paths in CheckoutOptions --- LibGit2Sharp.Tests/CloneFixture.cs | 25 +++++++++++++++++++++ LibGit2Sharp/CheckoutOptions.cs | 3 +++ LibGit2Sharp/CloneOptions.cs | 3 +++ LibGit2Sharp/Core/GitCheckoutOpts.cs | 13 +++++++++++ LibGit2Sharp/Core/GitCheckoutOptsWrapper.cs | 9 +++++++- LibGit2Sharp/MergeAndCheckoutOptionsBase.cs | 5 +++++ LibGit2Sharp/RebaseOptions.cs | 3 +++ LibGit2Sharp/SubmoduleUpdateOptions.cs | 3 +++ 8 files changed, 63 insertions(+), 1 deletion(-) diff --git a/LibGit2Sharp.Tests/CloneFixture.cs b/LibGit2Sharp.Tests/CloneFixture.cs index f205eddc2..2191ec09c 100644 --- a/LibGit2Sharp.Tests/CloneFixture.cs +++ b/LibGit2Sharp.Tests/CloneFixture.cs @@ -601,5 +601,30 @@ public void CanCloneWithCustomHeaders() var clonedRepoPath = Repository.Clone(url, scd.DirectoryPath, cloneOptions); Assert.True(Directory.Exists(clonedRepoPath)); } + + [Fact] + public void CanCloneWithLongPaths() + { + var scd = BuildSelfCleaningDirectory(); + + var cloneOptions = new CloneOptions + { + LongPaths = true + }; + + string clonedRepoPath = Repository.Clone("https://github.com/luiswolff/test-long-file-path.git", scd.DirectoryPath, cloneOptions); + + using (var repo = new Repository(clonedRepoPath)) + { + string dir = repo.Info.Path; + Assert.True(Path.IsPathRooted(dir)); + Assert.True(Directory.Exists(dir)); + Assert.NotNull(repo.Info.WorkingDirectory); + Assert.Equal(Path.Combine(scd.RootedDirectoryPath, ".git" + Path.DirectorySeparatorChar), repo.Info.Path); + Assert.False(repo.Info.IsBare); + + // Add additional assertions if necessary to verify long path support + } + } } } diff --git a/LibGit2Sharp/CheckoutOptions.cs b/LibGit2Sharp/CheckoutOptions.cs index 010502007..e14408738 100644 --- a/LibGit2Sharp/CheckoutOptions.cs +++ b/LibGit2Sharp/CheckoutOptions.cs @@ -30,6 +30,9 @@ public sealed class CheckoutOptions : IConvertableToGitCheckoutOpts /// controlled with the CheckoutNotifyFlags property. public CheckoutProgressHandler OnCheckoutProgress { get; set; } + /// + public bool LongPaths { get; set; } + CheckoutStrategy IConvertableToGitCheckoutOpts.CheckoutStrategy { get diff --git a/LibGit2Sharp/CloneOptions.cs b/LibGit2Sharp/CloneOptions.cs index a315d76fc..c29b36283 100644 --- a/LibGit2Sharp/CloneOptions.cs +++ b/LibGit2Sharp/CloneOptions.cs @@ -21,6 +21,9 @@ public CloneOptions() /// public bool IsBare { get; set; } + /// + public bool LongPaths { get; set; } + /// /// If true, the origin's HEAD will be checked out. This only applies /// to non-bare repositories. diff --git a/LibGit2Sharp/Core/GitCheckoutOpts.cs b/LibGit2Sharp/Core/GitCheckoutOpts.cs index 053258565..ddb62211e 100644 --- a/LibGit2Sharp/Core/GitCheckoutOpts.cs +++ b/LibGit2Sharp/Core/GitCheckoutOpts.cs @@ -105,6 +105,11 @@ internal enum CheckoutStrategy /// GIT_CHECKOUT_DONT_WRITE_INDEX = (1 << 23), + /// + /// Support for long file paths. + /// + GIT_CHECKOUT_LONGPATHS = (1 << 24), + // THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED /// @@ -183,6 +188,11 @@ internal interface IConvertableToGitCheckoutOpts CheckoutStrategy CheckoutStrategy { get; } CheckoutNotifyFlags CheckoutNotifyFlags { get; } + + /// + /// True will enable support for long paths, allowing the repository to handle paths longer than 260 characters. + /// + bool LongPaths { get; } } /// @@ -229,5 +239,8 @@ public CheckoutNotifyFlags CheckoutNotifyFlags { get { return internalOptions.CheckoutNotifyFlags; } } + + /// + public bool LongPaths { get; set; } } } diff --git a/LibGit2Sharp/Core/GitCheckoutOptsWrapper.cs b/LibGit2Sharp/Core/GitCheckoutOptsWrapper.cs index 0fba82754..d2c3e1baf 100644 --- a/LibGit2Sharp/Core/GitCheckoutOptsWrapper.cs +++ b/LibGit2Sharp/Core/GitCheckoutOptsWrapper.cs @@ -22,10 +22,17 @@ public GitCheckoutOptsWrapper(IConvertableToGitCheckoutOpts options, FilePath[] PathArray = GitStrArrayManaged.BuildFrom(paths); } + var checkout_strategy = options.CheckoutStrategy; + + if (options.LongPaths) + { + checkout_strategy |= CheckoutStrategy.GIT_CHECKOUT_LONGPATHS; + } + Options = new GitCheckoutOpts { version = 1, - checkout_strategy = options.CheckoutStrategy, + checkout_strategy = checkout_strategy, progress_cb = Callbacks.CheckoutProgressCallback, notify_cb = Callbacks.CheckoutNotifyCallback, notify_flags = options.CheckoutNotifyFlags, diff --git a/LibGit2Sharp/MergeAndCheckoutOptionsBase.cs b/LibGit2Sharp/MergeAndCheckoutOptionsBase.cs index b0d7cfc1d..29f35b5ad 100644 --- a/LibGit2Sharp/MergeAndCheckoutOptionsBase.cs +++ b/LibGit2Sharp/MergeAndCheckoutOptionsBase.cs @@ -46,6 +46,9 @@ public MergeAndCheckoutOptionsBase() /// public CheckoutProgressHandler OnCheckoutProgress { get; set; } + /// + public bool LongPaths { get; set; } + /// /// Delegate that checkout will notify callers of /// certain conditions. The conditions that are reported is @@ -69,6 +72,8 @@ CheckoutStrategy IConvertableToGitCheckoutOpts.CheckoutStrategy } } + + #endregion } } diff --git a/LibGit2Sharp/RebaseOptions.cs b/LibGit2Sharp/RebaseOptions.cs index 62cb6cbdb..3551d1390 100644 --- a/LibGit2Sharp/RebaseOptions.cs +++ b/LibGit2Sharp/RebaseOptions.cs @@ -54,5 +54,8 @@ CheckoutStrategy IConvertableToGitCheckoutOpts.CheckoutStrategy GitCheckoutOptsWrapper.CheckoutStrategyFromFileConflictStrategy(FileConflictStrategy); } } + + /// + public bool LongPaths { get; set; } } } diff --git a/LibGit2Sharp/SubmoduleUpdateOptions.cs b/LibGit2Sharp/SubmoduleUpdateOptions.cs index 082e17338..3777b4359 100644 --- a/LibGit2Sharp/SubmoduleUpdateOptions.cs +++ b/LibGit2Sharp/SubmoduleUpdateOptions.cs @@ -49,5 +49,8 @@ CheckoutNotifyFlags IConvertableToGitCheckoutOpts.CheckoutNotifyFlags { get { return CheckoutNotifyFlags; } } + + /// + public bool LongPaths { get; set; } } }