diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f44285812..54837ac35 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,77 +15,88 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout - uses: actions/checkout@v3.5.0 + uses: actions/checkout@v4.1.2 with: fetch-depth: 0 - name: Install .NET SDK - uses: actions/setup-dotnet@v3.0.3 + uses: actions/setup-dotnet@v4.0.0 with: - dotnet-version: 7.0.x + dotnet-version: 9.0.x - name: Build run: dotnet build LibGit2Sharp.sln --configuration Release - name: Upload packages - uses: actions/upload-artifact@v3.1.2 + uses: actions/upload-artifact@v4.3.1 with: name: NuGet packages - path: bin/Packages/ + path: artifacts/package/ retention-days: 7 + - name: Verify trimming compatibility + run: dotnet publish TrimmingTestApp test: name: Test / ${{ matrix.os }} / ${{ matrix.arch }} / ${{ matrix.tfm }} runs-on: ${{ matrix.os }} strategy: matrix: - arch: [ amd64 ] - os: [ windows-2019, macos-11 ] - tfm: [ net472, net6.0, net7.0 ] + arch: [ x64 ] + os: [ windows-2019, windows-2022, macos-13 ] + tfm: [ net472, net8.0, net9.0 ] exclude: - - os: macos-11 + - os: macos-13 tfm: net472 + include: + - arch: arm64 + os: macos-14 + tfm: net8.0 + - arch: arm64 + os: macos-14 + tfm: net9.0 fail-fast: false steps: - name: Checkout - uses: actions/checkout@v3.5.0 + uses: actions/checkout@v4.1.2 with: fetch-depth: 0 - name: Install .NET SDK - uses: actions/setup-dotnet@v3.0.3 + uses: actions/setup-dotnet@v4.0.0 with: dotnet-version: | - 7.0.x - 6.0.x + 9.0.x + 8.0.x - name: Run ${{ matrix.tfm }} tests run: dotnet test LibGit2Sharp.sln --configuration Release --framework ${{ matrix.tfm }} --logger "GitHubActions" /p:ExtraDefine=LEAKS_IDENTIFYING test-linux: name: Test / ${{ matrix.distro }} / ${{ matrix.arch }} / ${{ matrix.tfm }} - runs-on: ubuntu-22.04 + runs-on: ${{ matrix.runnerImage }} strategy: matrix: - arch: [ amd64 ] - # arch: [ amd64, arm64 ] - distro: [ alpine.3.13, alpine.3.14, alpine.3.15, alpine.3.16, alpine.3.17, centos.7, centos.stream.8, debian.10, debian.11, fedora.36, ubuntu.18.04, ubuntu.20.04, ubuntu.22.04 ] - sdk: [ '6.0', '7.0' ] + arch: [ amd64, arm64 ] + distro: [ alpine.3.17, alpine.3.18, alpine.3.19, alpine.3.20, centos.stream.9, debian.12, fedora.40, ubuntu.20.04, ubuntu.22.04, ubuntu.24.04 ] + sdk: [ '8.0', '9.0' ] exclude: - - distro: alpine.3.13 - sdk: '7.0' - - distro: alpine.3.14 - sdk: '7.0' + - distro: alpine.3.17 + sdk: '9.0' + - distro: alpine.3.18 + sdk: '9.0' + - distro: alpine.3.19 + sdk: '9.0' include: - - sdk: '6.0' - tfm: net6.0 - - sdk: '7.0' - tfm: net7.0 + - sdk: '8.0' + tfm: net8.0 + - sdk: '9.0' + tfm: net9.0 + - arch: amd64 + runnerImage: ubuntu-22.04 + - arch: arm64 + runnerImage: ubuntu-22.04-arm fail-fast: false steps: - name: Checkout - uses: actions/checkout@v3.5.0 + uses: actions/checkout@v4.1.2 with: fetch-depth: 0 - - name: Setup QEMU - if: matrix.arch == 'arm64' - run: docker run --rm --privileged multiarch/qemu-user-static:register --reset - name: Run ${{ matrix.tfm }} tests run: | git_command="git config --global --add safe.directory /app" test_command="dotnet test LibGit2Sharp.sln --configuration Release -p:TargetFrameworks=${{ matrix.tfm }} --logger "GitHubActions" -p:ExtraDefine=LEAKS_IDENTIFYING" - docker run -t --rm --platform linux/${{ matrix.arch }} -v "$PWD:/app" gittools/build-images:${{ matrix.distro }}-sdk-${{ matrix.sdk }} sh -c "$git_command && $test_command" + docker run -t --rm --platform linux/${{ matrix.arch }} -v "$PWD:/app" -e OPENSSL_ENABLE_SHA1_SIGNATURES=1 gittools/build-images:${{ matrix.distro }}-sdk-${{ matrix.sdk }} sh -c "$git_command && $test_command" diff --git a/.gitignore b/.gitignore index 2f75ccc1d..32e17b4d0 100644 --- a/.gitignore +++ b/.gitignore @@ -38,5 +38,5 @@ _ReSharper*/ *.DotSettings _NCrunch_LibGit2Sharp/ -packages/ +artifacts/ worktree.playlist diff --git a/CHANGES.md b/CHANGES.md index c902a8640..a00b598d7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,58 @@ # LibGit2Sharp Changes +## v0.31 - ([diff](https://github.com/libgit2/libgit2sharp/compare/0.30.0..0.31.0)) + +### Changes +- This release includes [libgit2 v1.8.4](https://github.com/libgit2/libgit2/releases/tag/v1.8.4). + - SSH is now supported through [libgit2's support for OpenSSH](https://github.com/libgit2/libgit2/pull/6617). +- The ppc64le architecture is now supported on Linux. +- .NET 6 has reached end of support, so LibGit2Sharp now targets `net472` and `net8.0`. + +### Additions +- Adds Depth to FetchOptions allowing for shallow cloning [#2070](https://github.com/libgit2/libgit2sharp/pull/2070) +- Make owner validation configurable [#2093](https://github.com/libgit2/libgit2sharp/pull/2093) +- Add a CloneOptions constructor that takes a FetchOptions [#2132](https://github.com/libgit2/libgit2sharp/pull/2132) + +### Fixes +- TreeDefinition.Remove fails to remove unwrapped trees [#1869](https://github.com/libgit2/libgit2sharp/issues/1869) +- ObjectDatabase.Write(Stream stream...) overload does not respect T [#2071](https://github.com/libgit2/libgit2sharp/issues/2071) +- Repository.Worktrees.Add leaves now worktree empty [#2037](https://github.com/libgit2/libgit2sharp/issues/2037) + +## v0.30 - ([diff](https://github.com/libgit2/libgit2sharp/compare/0.29.0..0.30.0)) + +### Changes +- This release includes [libgit2 v1.7.2](https://github.com/libgit2/libgit2/releases/tag/v1.7.2). +- Updates for trimming compatibility [#2084](https://github.com/libgit2/libgit2sharp/pull/2084) +- Updates for .NET 8 [#2085](https://github.com/libgit2/libgit2sharp/pull/2085) + +## v0.29 - ([diff](https://github.com/libgit2/libgit2sharp/compare/0.28.0..0.29.0)) + +### Changes +- This release includes [libgit2 v1.7.1](https://github.com/libgit2/libgit2/releases/tag/v1.7.1). + - CI changes for the native binaries has removed support for CentOS 7. See [#2066](https://github.com/libgit2/libgit2sharp/pull/2066) for details. + +### Additions +- Add proxy options [#2065](https://github.com/libgit2/libgit2sharp/pull/2065) + - See PR for details, including some breaking changes to `CloneOptions` and `SubmoduleUpdateOptions` + +## v0.28 - ([diff](https://github.com/libgit2/libgit2sharp/compare/0.27.2..0.28.0)) + +### Additions +- Add CustomHeaders to PushOptions [#2052](https://github.com/libgit2/libgit2sharp/pull/2052) + +## v0.27.2 - ([diff](https://github.com/libgit2/libgit2sharp/compare/0.27.1..0.27.2)) + +### Changes +- This release includes [libgit2 v1.6.4](https://github.com/libgit2/libgit2/releases/tag/v1.6.4). + +### Fixes +- Can't access GIT config (Repository.Config) since v0.27.0 [#2031](https://github.com/libgit2/libgit2sharp/issues/2031) + +## v0.27.1 - ([diff](https://github.com/libgit2/libgit2sharp/compare/0.27.0..0.27.1)) + +### Fixes +- AssemblyVersion of v0.27.0 is `0.0.0.0`, which is lower than the AssemblyVersion of the v0.26.x releases. [#2030](https://github.com/libgit2/libgit2sharp/pull/2030) + ## v0.27 - ([diff](https://github.com/libgit2/libgit2sharp/compare/v0.26..0.27.0)) ### Changes diff --git a/Directory.Build.props b/Directory.Build.props index 72eda8864..2c14cc2bd 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,10 +1,9 @@ + true true - $(MSBuildThisFileDirectory)bin\$(MSBuildProjectName)\$(Configuration)\ - $(MSBuildThisFileDirectory)obj\$(MSBuildProjectName)\ - $(MSBuildThisFileDirectory)bin\Packages\ + true $(DefineConstants);$(ExtraDefine) diff --git a/LibGit2Sharp.Tests/BlameFixture.cs b/LibGit2Sharp.Tests/BlameFixture.cs index da63dc124..8cefcfb45 100644 --- a/LibGit2Sharp.Tests/BlameFixture.cs +++ b/LibGit2Sharp.Tests/BlameFixture.cs @@ -62,10 +62,10 @@ public void CanBlameFromVariousTypes() string path = SandboxBareTestRepo(); using (var repo = new Repository(path)) { - AssertCorrectHeadBlame(repo.Blame("README", new BlameOptions {StartingAt = "HEAD" })); - AssertCorrectHeadBlame(repo.Blame("README", new BlameOptions {StartingAt = repo.Head })); - AssertCorrectHeadBlame(repo.Blame("README", new BlameOptions {StartingAt = repo.Head.Tip })); - AssertCorrectHeadBlame(repo.Blame("README", new BlameOptions {StartingAt = repo.Branches["master"]})); + AssertCorrectHeadBlame(repo.Blame("README", new BlameOptions { StartingAt = "HEAD" })); + AssertCorrectHeadBlame(repo.Blame("README", new BlameOptions { StartingAt = repo.Head })); + AssertCorrectHeadBlame(repo.Blame("README", new BlameOptions { StartingAt = repo.Head.Tip })); + AssertCorrectHeadBlame(repo.Blame("README", new BlameOptions { StartingAt = repo.Branches["master"] })); } } @@ -78,7 +78,7 @@ public void CanStopBlame() // $ git blame .\new.txt // 9fd738e8 (Scott Chacon 2010-05-24 10:19:19 -0700 1) my new file // (be3563a comes after 9fd738e8) - var blame = repo.Blame("new.txt", new BlameOptions {StoppingAt = "be3563a"}); + var blame = repo.Blame("new.txt", new BlameOptions { StoppingAt = "be3563a" }); Assert.StartsWith("be3563a", blame[0].FinalCommit.Sha); } } diff --git a/LibGit2Sharp.Tests/BranchFixture.cs b/LibGit2Sharp.Tests/BranchFixture.cs index 736b0faec..88247e256 100644 --- a/LibGit2Sharp.Tests/BranchFixture.cs +++ b/LibGit2Sharp.Tests/BranchFixture.cs @@ -4,7 +4,6 @@ using System.Linq; using LibGit2Sharp.Tests.TestHelpers; using Xunit; -using Xunit.Extensions; namespace LibGit2Sharp.Tests { @@ -103,7 +102,7 @@ public void CanCreateAnUnbornBranch() public void CanCreateBranchUsingAbbreviatedSha() { string path = SandboxBareTestRepo(); - using (var repo = new Repository(path, new RepositoryOptions{ Identity = Constants.Identity })) + using (var repo = new Repository(path, new RepositoryOptions { Identity = Constants.Identity })) { EnableRefLog(repo); @@ -1001,7 +1000,7 @@ public void OnlyOneBranchIsTheHead() continue; } - Assert.True(false, string.Format("Both '{0}' and '{1}' appear to be Head.", head.CanonicalName, branch.CanonicalName)); + Assert.Fail(string.Format("Both '{0}' and '{1}' appear to be Head.", head.CanonicalName, branch.CanonicalName)); } Assert.NotNull(head); diff --git a/LibGit2Sharp.Tests/CheckoutFixture.cs b/LibGit2Sharp.Tests/CheckoutFixture.cs index 8962cbc1d..045e20e1f 100644 --- a/LibGit2Sharp.Tests/CheckoutFixture.cs +++ b/LibGit2Sharp.Tests/CheckoutFixture.cs @@ -269,7 +269,7 @@ public void CanForcefullyCheckoutWithConflictingStagedChanges() Assert.Throws(() => Commands.Checkout(repo, master.CanonicalName)); // Checkout with force option should succeed. - Commands.Checkout(repo, master.CanonicalName, new CheckoutOptions() { CheckoutModifiers = CheckoutModifiers.Force}); + Commands.Checkout(repo, master.CanonicalName, new CheckoutOptions() { CheckoutModifiers = CheckoutModifiers.Force }); // Assert that master branch is checked out. Assert.True(repo.Branches["master"].IsCurrentRepositoryHead); @@ -411,7 +411,7 @@ public void CheckingOutThroughBranchCallsCheckoutProgress() Branch branch = repo.Branches[otherBranchName]; Commands.Checkout(repo, branch, - new CheckoutOptions { OnCheckoutProgress = (path, completed, total) => wasCalled = true}); + new CheckoutOptions { OnCheckoutProgress = (path, completed, total) => wasCalled = true }); Assert.True(wasCalled); } @@ -427,7 +427,7 @@ public void CheckingOutThroughRepositoryCallsCheckoutProgress() PopulateBasicRepository(repo); bool wasCalled = false; - Commands.Checkout(repo, otherBranchName, new CheckoutOptions() { OnCheckoutProgress = (path, completed, total) => wasCalled = true}); + Commands.Checkout(repo, otherBranchName, new CheckoutOptions() { OnCheckoutProgress = (path, completed, total) => wasCalled = true }); Assert.True(wasCalled); } @@ -779,7 +779,7 @@ public void CheckoutFromDetachedHead(string commitPointer) public void CheckoutBranchFromDetachedHead() { string path = SandboxStandardTestRepo(); - using (var repo = new Repository(path, new RepositoryOptions{ Identity = Constants.Identity })) + using (var repo = new Repository(path, new RepositoryOptions { Identity = Constants.Identity })) { // Set the working directory to the current head ResetAndCleanWorkingDirectory(repo); diff --git a/LibGit2Sharp.Tests/CloneFixture.cs b/LibGit2Sharp.Tests/CloneFixture.cs index 1b26c1226..831f6779f 100644 --- a/LibGit2Sharp.Tests/CloneFixture.cs +++ b/LibGit2Sharp.Tests/CloneFixture.cs @@ -35,6 +35,34 @@ public void CanClone(string url) } } + [Theory] + [InlineData("https://github.com/libgit2/TestGitRepository", 1)] + [InlineData("https://github.com/libgit2/TestGitRepository", 5)] + [InlineData("https://github.com/libgit2/TestGitRepository", 7)] + public void CanCloneShallow(string url, int depth) + { + var scd = BuildSelfCleaningDirectory(); + + var clonedRepoPath = Repository.Clone(url, scd.DirectoryPath, new CloneOptions + { + FetchOptions = + { + Depth = depth, + }, + }); + + using (var repo = new Repository(clonedRepoPath)) + { + var commitsFirstParentOnly = repo.Commits.QueryBy(new CommitFilter + { + FirstParentOnly = true, + }); + + Assert.Equal(depth, commitsFirstParentOnly.Count()); + Assert.Equal("49322bb17d3acc9146f98c97d078513228bbf3c0", repo.Head.Tip.Id.ToString()); + } + } + [Theory] [InlineData("br2", "a4a7dce85cf63874e984719f4fdd239f5145052f")] [InlineData("packed", "41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9")] @@ -151,10 +179,14 @@ public void CallsProgressCallbacks(string url) Repository.Clone(url, scd.DirectoryPath, new CloneOptions() { - OnTransferProgress = _ => { transferWasCalled = true; return true; }, - OnProgress = progress => { progressWasCalled = true; return true; }, - OnUpdateTips = (name, oldId, newId) => { updateTipsWasCalled = true; return true; }, + FetchOptions = + { + OnTransferProgress = _ => { transferWasCalled = true; return true; }, + OnProgress = progress => { progressWasCalled = true; return true; }, + OnUpdateTips = (name, oldId, newId) => { updateTipsWasCalled = true; return true; } + }, OnCheckoutProgress = (a, b, c) => checkoutWasCalled = true + }); Assert.True(transferWasCalled); @@ -174,7 +206,7 @@ public void CanCloneWithCredentials() string clonedRepoPath = Repository.Clone(Constants.PrivateRepoUrl, scd.DirectoryPath, new CloneOptions() { - CredentialsProvider = Constants.PrivateRepoCredentials + FetchOptions = { CredentialsProvider = Constants.PrivateRepoCredentials } }); @@ -234,7 +266,7 @@ static Credentials CreateUsernamePasswordCredentials(string user, string pass, b [SkippableTheory] [InlineData("https://github.com/libgit2/TestGitRepository.git", "github.com", typeof(CertificateX509))] - [InlineData("git@github.com:libgit2/TestGitRepository.git", "github.com", typeof(CertificateSsh))] + //[InlineData("git@github.com:libgit2/TestGitRepository.git", "github.com", typeof(CertificateSsh))] public void CanInspectCertificateOnClone(string url, string hostname, Type certType) { var scd = BuildSelfCleaningDirectory(); @@ -249,43 +281,46 @@ public void CanInspectCertificateOnClone(string url, string hostname, Type certT var options = new CloneOptions { - CertificateCheck = (cert, valid, host) => + FetchOptions = { - wasCalled = true; - - Assert.Equal(hostname, host); - Assert.Equal(certType, cert.GetType()); - - if (certType == typeof(CertificateX509)) + CertificateCheck = (cert, valid, host) => { - Assert.True(valid); - var x509 = ((CertificateX509)cert).Certificate; - // we get a string with the different fields instead of a structure, so... - Assert.Contains("CN=github.com,", x509.Subject); - checksHappy = true; - return false; - } + wasCalled = true; + + Assert.Equal(hostname, host); + Assert.Equal(certType, cert.GetType()); + + if (certType == typeof(CertificateX509)) + { + Assert.True(valid); + var x509 = ((CertificateX509)cert).Certificate; + // we get a string with the different fields instead of a structure, so... + Assert.Contains("CN=github.com", x509.Subject); + checksHappy = true; + return false; + } + + if (certType == typeof(CertificateSsh)) + { + var hostkey = (CertificateSsh)cert; + Assert.True(hostkey.HasMD5); + /* + * Once you've connected and thus your ssh has stored the hostkey, + * you can get the hostkey for a host with + * + * ssh-keygen -F github.com -l | tail -n 1 | cut -d ' ' -f 2 | tr -d ':' + * + * though GitHub's hostkey won't change anytime soon. + */ + Assert.Equal("1627aca576282d36631b564debdfa648", + BitConverter.ToString(hostkey.HashMD5).ToLower().Replace("-", "")); + checksHappy = true; + return false; + } - if (certType == typeof(CertificateSsh)) - { - var hostkey = (CertificateSsh)cert; - Assert.True(hostkey.HasMD5); - /* - * Once you've connected and thus your ssh has stored the hostkey, - * you can get the hostkey for a host with - * - * ssh-keygen -F github.com -l | tail -n 1 | cut -d ' ' -f 2 | tr -d ':' - * - * though GitHub's hostkey won't change anytime soon. - */ - Assert.Equal("1627aca576282d36631b564debdfa648", - BitConverter.ToString(hostkey.HashMD5).ToLower().Replace("-", "")); - checksHappy = true; return false; } - - return false; - }, + } }; Assert.Throws(() => @@ -432,9 +467,12 @@ public void CanRecursivelyCloneSubmodules() { RecurseSubmodules = true, OnCheckoutProgress = checkoutProgressHandler, - OnUpdateTips = remoteRefUpdated, - RepositoryOperationStarting = repositoryOperationStarting, - RepositoryOperationCompleted = repositoryOperationCompleted, + FetchOptions = + { + OnUpdateTips = remoteRefUpdated, + RepositoryOperationStarting = repositoryOperationStarting, + RepositoryOperationCompleted = repositoryOperationCompleted + } }; string clonedRepoPath = Repository.Clone(uri.AbsolutePath, scd.DirectoryPath, options); @@ -517,7 +555,7 @@ public void CanCancelRecursiveClone() CloneOptions options = new CloneOptions() { RecurseSubmodules = true, - RepositoryOperationStarting = repositoryOperationStarting, + FetchOptions = { RepositoryOperationStarting = repositoryOperationStarting } }; Assert.Throws(() => @@ -557,10 +595,8 @@ public void CannotCloneWithForbiddenCustomHeaders() const string url = "https://github.com/libgit2/TestGitRepository"; const string knownHeader = "User-Agent: mygit-201"; - var cloneOptions = new CloneOptions() - { - FetchOptions = new FetchOptions { CustomHeaders = new String[] { knownHeader } } - }; + var cloneOptions = new CloneOptions(); + cloneOptions.FetchOptions.CustomHeaders = new string[] { knownHeader }; Assert.Throws(() => Repository.Clone(url, scd.DirectoryPath, cloneOptions)); } @@ -573,10 +609,8 @@ public void CannotCloneWithMalformedCustomHeaders() const string url = "https://github.com/libgit2/TestGitRepository"; const string knownHeader = "hello world"; - var cloneOptions = new CloneOptions() - { - FetchOptions = new FetchOptions { CustomHeaders = new String[] { knownHeader } } - }; + var cloneOptions = new CloneOptions(); + cloneOptions.FetchOptions.CustomHeaders = new string[] { knownHeader }; Assert.Throws(() => Repository.Clone(url, scd.DirectoryPath, cloneOptions)); } @@ -589,10 +623,8 @@ public void CanCloneWithCustomHeaders() const string url = "https://github.com/libgit2/TestGitRepository"; const string knownHeader = "X-Hello: world"; - var cloneOptions = new CloneOptions() - { - FetchOptions = new FetchOptions { CustomHeaders = new String[] { knownHeader } } - }; + var cloneOptions = new CloneOptions(); + cloneOptions.FetchOptions.CustomHeaders = new string[] { knownHeader }; var clonedRepoPath = Repository.Clone(url, scd.DirectoryPath, cloneOptions); Assert.True(Directory.Exists(clonedRepoPath)); diff --git a/LibGit2Sharp.Tests/CommitFixture.cs b/LibGit2Sharp.Tests/CommitFixture.cs index f555e7874..e99ca918f 100644 --- a/LibGit2Sharp.Tests/CommitFixture.cs +++ b/LibGit2Sharp.Tests/CommitFixture.cs @@ -3,10 +3,8 @@ using System.IO; using System.Linq; using System.Text; -using LibGit2Sharp.Core; using LibGit2Sharp.Tests.TestHelpers; using Xunit; -using Xunit.Extensions; namespace LibGit2Sharp.Tests { @@ -150,10 +148,10 @@ public void CanEnumerateCommitsWithReverseTimeSorting() using (var repo = new Repository(path)) { foreach (Commit commit in repo.Commits.QueryBy(new CommitFilter - { - IncludeReachableFrom = "a4a7dce85cf63874e984719f4fdd239f5145052f", - SortBy = CommitSortStrategies.Time | CommitSortStrategies.Reverse - })) + { + IncludeReachableFrom = "a4a7dce85cf63874e984719f4fdd239f5145052f", + SortBy = CommitSortStrategies.Time | CommitSortStrategies.Reverse + })) { Assert.NotNull(commit); Assert.StartsWith(reversedShas[count], commit.Sha); @@ -170,10 +168,10 @@ public void CanEnumerateCommitsWithReverseTopoSorting() using (var repo = new Repository(path)) { List commits = repo.Commits.QueryBy(new CommitFilter - { - IncludeReachableFrom = "a4a7dce85cf63874e984719f4fdd239f5145052f", - SortBy = CommitSortStrategies.Time | CommitSortStrategies.Reverse - }).ToList(); + { + IncludeReachableFrom = "a4a7dce85cf63874e984719f4fdd239f5145052f", + SortBy = CommitSortStrategies.Time | CommitSortStrategies.Reverse + }).ToList(); foreach (Commit commit in commits) { Assert.NotNull(commit); @@ -216,10 +214,10 @@ public void CanEnumerateCommitsWithTimeSorting() using (var repo = new Repository(path)) { foreach (Commit commit in repo.Commits.QueryBy(new CommitFilter - { - IncludeReachableFrom = "a4a7dce85cf63874e984719f4fdd239f5145052f", - SortBy = CommitSortStrategies.Time - })) + { + IncludeReachableFrom = "a4a7dce85cf63874e984719f4fdd239f5145052f", + SortBy = CommitSortStrategies.Time + })) { Assert.NotNull(commit); Assert.StartsWith(expectedShas[count], commit.Sha); @@ -236,10 +234,10 @@ public void CanEnumerateCommitsWithTopoSorting() using (var repo = new Repository(path)) { List commits = repo.Commits.QueryBy(new CommitFilter - { - IncludeReachableFrom = "a4a7dce85cf63874e984719f4fdd239f5145052f", - SortBy = CommitSortStrategies.Topological - }).ToList(); + { + IncludeReachableFrom = "a4a7dce85cf63874e984719f4fdd239f5145052f", + SortBy = CommitSortStrategies.Topological + }).ToList(); foreach (Commit commit in commits) { Assert.NotNull(commit); @@ -331,9 +329,12 @@ public void CanEnumerateCommitsFromTwoHeads() public void CanEnumerateCommitsFromMixedStartingPoints() { AssertEnumerationOfCommits( - repo => new CommitFilter { IncludeReachableFrom = new object[] { repo.Branches["br2"], + repo => new CommitFilter + { + IncludeReachableFrom = new object[] { repo.Branches["br2"], "refs/heads/master", - new ObjectId("e90810b8df3e80c413d903f631643c716887138d") } }, + new ObjectId("e90810b8df3e80c413d903f631643c716887138d") } + }, new[] { "4c062a6", "e90810b", "6dcf9bf", "a4a7dce", @@ -389,9 +390,9 @@ public void CanEnumerateAllCommits() { AssertEnumerationOfCommits( repo => new CommitFilter - { - IncludeReachableFrom = repo.Refs.OrderBy(r => r.CanonicalName, StringComparer.Ordinal), - }, + { + IncludeReachableFrom = repo.Refs.OrderBy(r => r.CanonicalName, StringComparer.Ordinal), + }, new[] { "44d5d18", "bb65291", "532740a", "503a16f", "3dfd6fd", @@ -406,7 +407,7 @@ public void CanEnumerateCommitsFromATagWhichPointsToABlob() { AssertEnumerationOfCommits( repo => new CommitFilter { IncludeReachableFrom = repo.Tags["point_to_blob"] }, - new string[] { }); + Array.Empty()); } [Fact] @@ -421,7 +422,7 @@ public void CanEnumerateCommitsFromATagWhichPointsToATree() AssertEnumerationOfCommitsInRepo(repo, r => new CommitFilter { IncludeReachableFrom = tag }, - new string[] { }); + Array.Empty()); } } @@ -680,8 +681,12 @@ public void CanCommitALittleBit() Assert.Equal(identity.Name, reflogEntry.Committer.Name); Assert.Equal(identity.Email, reflogEntry.Committer.Email); - var now = DateTimeOffset.Now; - Assert.InRange(reflogEntry.Committer.When, before, now); + // When verifying the timestamp range, give a little more room on the range. + // Git or file system datetime truncation seems to cause these stamps to jump up to a second earlier + // than we expect. See https://github.com/libgit2/libgit2sharp/issues/1764 + var low = before - TimeSpan.FromSeconds(1); + var high = DateTimeOffset.Now.TruncateMilliseconds() + TimeSpan.FromSeconds(1); + Assert.InRange(reflogEntry.Committer.When, low, high); Assert.Equal(commit.Id, reflogEntry.To); Assert.Equal(ObjectId.Zero, reflogEntry.From); @@ -859,21 +864,21 @@ public void CanRetrieveChildrenOfASpecificCommit() const string parentSha = "5b5b025afb0b4c913b4c338a42934a3863bf3644"; var filter = new CommitFilter - { - /* Revwalk from all the refs (git log --all) ... */ - IncludeReachableFrom = repo.Refs, + { + /* Revwalk from all the refs (git log --all) ... */ + IncludeReachableFrom = repo.Refs, - /* ... and stop when the parent is reached */ - ExcludeReachableFrom = parentSha - }; + /* ... and stop when the parent is reached */ + ExcludeReachableFrom = parentSha + }; var commits = repo.Commits.QueryBy(filter); var children = from c in commits - from p in c.Parents - let pId = p.Id - where pId.Sha == parentSha - select c; + from p in c.Parents + let pId = p.Id + where pId.Sha == parentSha + select c; var expectedChildren = new[] { "c47800c7266a2be04c571c04d5a6614691ea99bd", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045" }; diff --git a/LibGit2Sharp.Tests/ConfigurationFixture.cs b/LibGit2Sharp.Tests/ConfigurationFixture.cs index 999aa0336..aaee77b02 100644 --- a/LibGit2Sharp.Tests/ConfigurationFixture.cs +++ b/LibGit2Sharp.Tests/ConfigurationFixture.cs @@ -4,7 +4,6 @@ using System.Linq; using LibGit2Sharp.Tests.TestHelpers; using Xunit; -using Xunit.Extensions; namespace LibGit2Sharp.Tests { @@ -56,9 +55,7 @@ public void CanAddAndReadMultivarFromTheLocalConfiguration() string path = SandboxStandardTestRepo(); using (var repo = new Repository(path)) { - Assert.Empty(repo.Config - .OfType>() - .Where(x => x.Key == "unittests.plugin")); + Assert.DoesNotContain(repo.Config.OfType>(), x => x.Key == "unittests.plugin"); repo.Config.Add("unittests.plugin", "value1", ConfigurationLevel.Local); repo.Config.Add("unittests.plugin", "value2", ConfigurationLevel.Local); @@ -78,9 +75,7 @@ public void CanAddAndReadMultivarFromTheGlobalConfiguration() using (var repo = new Repository(path)) { Assert.True(repo.Config.HasConfig(ConfigurationLevel.Global)); - Assert.Empty(repo.Config - .OfType>() - .Where(x => x.Key == "unittests.plugin")); + Assert.DoesNotContain(repo.Config.OfType>(), x => x.Key == "unittests.plugin"); repo.Config.Add("unittests.plugin", "value1", ConfigurationLevel.Global); repo.Config.Add("unittests.plugin", "value2", ConfigurationLevel.Global); @@ -157,9 +152,7 @@ public void CanUnsetAllFromTheLocalConfiguration() repo.Config.UnsetAll("unittests.plugin"); - Assert.Empty(repo.Config - .OfType>() - .Where(x => x.Key == "unittests.plugin")); + Assert.DoesNotContain(repo.Config.OfType>(), x => x.Key == "unittests.plugin"); } } @@ -531,20 +524,20 @@ public void CanSetAndGetSearchPath() { string globalPath = Path.Combine(Constants.TemporaryReposPath, Path.GetRandomFileName()); string systemPath = Path.Combine(Constants.TemporaryReposPath, Path.GetRandomFileName()); - string xdgPath = Path.Combine(Constants.TemporaryReposPath, Path.GetRandomFileName()); + string xdgPath = Path.Combine(Constants.TemporaryReposPath, Path.GetRandomFileName()); GlobalSettings.SetConfigSearchPaths(ConfigurationLevel.Global, globalPath); GlobalSettings.SetConfigSearchPaths(ConfigurationLevel.System, systemPath); - GlobalSettings.SetConfigSearchPaths(ConfigurationLevel.Xdg, xdgPath); + GlobalSettings.SetConfigSearchPaths(ConfigurationLevel.Xdg, xdgPath); Assert.Equal(globalPath, GlobalSettings.GetConfigSearchPaths(ConfigurationLevel.Global).Single()); Assert.Equal(systemPath, GlobalSettings.GetConfigSearchPaths(ConfigurationLevel.System).Single()); - Assert.Equal(xdgPath, GlobalSettings.GetConfigSearchPaths(ConfigurationLevel.Xdg).Single()); + Assert.Equal(xdgPath, GlobalSettings.GetConfigSearchPaths(ConfigurationLevel.Xdg).Single()); // reset the search paths to their defaults GlobalSettings.SetConfigSearchPaths(ConfigurationLevel.Global, null); GlobalSettings.SetConfigSearchPaths(ConfigurationLevel.System, null); - GlobalSettings.SetConfigSearchPaths(ConfigurationLevel.Xdg, null); + GlobalSettings.SetConfigSearchPaths(ConfigurationLevel.Xdg, null); } [Fact] @@ -577,12 +570,12 @@ public void CanResetSearchPaths() var newPaths = new string[] { Path.Combine(Constants.TemporaryReposPath, Path.GetRandomFileName()) }; // change to the non-default path - GlobalSettings.SetConfigSearchPaths (ConfigurationLevel.Global, newPaths); - Assert.Equal (newPaths, GlobalSettings.GetConfigSearchPaths (ConfigurationLevel.Global)); + GlobalSettings.SetConfigSearchPaths(ConfigurationLevel.Global, newPaths); + Assert.Equal(newPaths, GlobalSettings.GetConfigSearchPaths(ConfigurationLevel.Global)); // set it back to the default - GlobalSettings.SetConfigSearchPaths (ConfigurationLevel.Global, null); - Assert.Equal (oldPaths, GlobalSettings.GetConfigSearchPaths (ConfigurationLevel.Global)); + GlobalSettings.SetConfigSearchPaths(ConfigurationLevel.Global, null); + Assert.Equal(oldPaths, GlobalSettings.GetConfigSearchPaths(ConfigurationLevel.Global)); } [Fact] diff --git a/LibGit2Sharp.Tests/ConflictFixture.cs b/LibGit2Sharp.Tests/ConflictFixture.cs index b28270b7e..6317bf431 100644 --- a/LibGit2Sharp.Tests/ConflictFixture.cs +++ b/LibGit2Sharp.Tests/ConflictFixture.cs @@ -48,7 +48,7 @@ private static List RenameConflictData [Theory] [InlineData(true, "ancestor-and-ours.txt", true, false, FileStatus.DeletedFromIndex, 2)] - [InlineData(false, "ancestor-and-ours.txt", true, true, FileStatus.DeletedFromIndex |FileStatus.NewInWorkdir, 2)] + [InlineData(false, "ancestor-and-ours.txt", true, true, FileStatus.DeletedFromIndex | FileStatus.NewInWorkdir, 2)] [InlineData(true, "ancestor-and-theirs.txt", true, false, FileStatus.Nonexistent, 2)] [InlineData(false, "ancestor-and-theirs.txt", true, true, FileStatus.NewInWorkdir, 2)] [InlineData(true, "ancestor-only.txt", false, false, FileStatus.Nonexistent, 1)] @@ -101,7 +101,7 @@ public void CanGetOriginalNamesOfRenameConflicts() Assert.Equal(expected.Count, actual.Count()); int i = 0; - foreach(var name in actual) + foreach (var name in actual) { Assert.Equal(expected[i][0], name.Ancestor); Assert.Equal(expected[i][1], name.Ours); diff --git a/LibGit2Sharp.Tests/DescribeFixture.cs b/LibGit2Sharp.Tests/DescribeFixture.cs index ca859b9cd..bb2cacd06 100644 --- a/LibGit2Sharp.Tests/DescribeFixture.cs +++ b/LibGit2Sharp.Tests/DescribeFixture.cs @@ -23,7 +23,7 @@ public void CanDescribeACommit() // No lightweight tags can either be used to describe "master" Assert.Throws(() => repo.Describe(masterTip, - new DescribeOptions{ Strategy = DescribeStrategy.Tags })); + new DescribeOptions { Strategy = DescribeStrategy.Tags })); repo.ApplyTag("myTag", "5b5b025afb0b4c913b4c338a42934a3863bf3644"); Assert.Equal("myTag-5-g4c062a6", repo.Describe(masterTip, @@ -47,7 +47,7 @@ public void CanDescribeACommit() var anotherTip = repo.Branches["ForLackOfABetterName"].Tip; Assert.Equal("test", repo.Describe(anotherTip)); Assert.Equal("test-0-g7b43849", repo.Describe(anotherTip, - new DescribeOptions{ AlwaysRenderLongFormat = true })); + new DescribeOptions { AlwaysRenderLongFormat = true })); } } diff --git a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs index 0fe7adee1..8c2956331 100644 --- a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs +++ b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs @@ -9,7 +9,7 @@ namespace LibGit2Sharp.Tests { public class DiffTreeToTreeFixture : BaseFixture { - private static readonly string subBranchFilePath = String.Join("/", "1", "branch_file.txt"); + private static readonly string subBranchFilePath = string.Join("/", "1", "branch_file.txt"); [Fact] public void ComparingATreeAgainstItselfReturnsNoDifference() @@ -27,7 +27,7 @@ public void ComparingATreeAgainstItselfReturnsNoDifference() using (var patch = repo.Diff.Compare(tree, tree)) { Assert.Empty(patch); - Assert.Equal(String.Empty, patch); + Assert.Equal(string.Empty, patch); } } } @@ -1263,7 +1263,7 @@ public void DiffThrowsANotFoundExceptionIfATreeIsMissing() string repoPath = SandboxBareTestRepo(); // Manually delete the tree object to simulate a partial clone - File.Delete(Path.Combine(repoPath, "objects", "58", "1f9824ecaf824221bd36edf5430f2739a7c4f5")); + File.Delete(Path.Combine(repoPath, "objects", "58", "1f9824ecaf824221bd36edf5430f2739a7c4f5")); using (var repo = new Repository(repoPath)) { @@ -1282,12 +1282,12 @@ public void DiffThrowsANotFoundExceptionIfATreeIsMissing() Assert.Throws(() => { - using (repo.Diff.Compare(commit.Tree, otherCommit.Tree)) {} + using (repo.Diff.Compare(commit.Tree, otherCommit.Tree)) { } }); Assert.Throws(() => { - using (repo.Diff.Compare(otherCommit.Tree, commit.Tree)) {} + using (repo.Diff.Compare(otherCommit.Tree, commit.Tree)) { } }); } } diff --git a/LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs b/LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs index 430859577..c6ef700bb 100644 --- a/LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs +++ b/LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs @@ -137,7 +137,7 @@ public void ComparingReliesOnProvidedConfigEntriesIfAny() using (var repo = new Repository(path)) { SetFilemode(repo, true); - using(var changes = repo.Diff.Compare(new[] { file })) + using (var changes = repo.Diff.Compare(new[] { file })) { Assert.Single(changes); @@ -150,7 +150,7 @@ public void ComparingReliesOnProvidedConfigEntriesIfAny() using (var repo = new Repository(path)) { SetFilemode(repo, false); - using(var changes = repo.Diff.Compare(new[] { file })) + using (var changes = repo.Diff.Compare(new[] { file })) { Assert.Empty(changes); } diff --git a/LibGit2Sharp.Tests/FetchFixture.cs b/LibGit2Sharp.Tests/FetchFixture.cs index c0c6f0478..b36da7ccd 100644 --- a/LibGit2Sharp.Tests/FetchFixture.cs +++ b/LibGit2Sharp.Tests/FetchFixture.cs @@ -42,7 +42,7 @@ public void CanFetchIntoAnEmptyRepository(string url) } // Perform the actual fetch - Commands.Fetch(repo, remoteName, new string[0], new FetchOptions { OnUpdateTips = expectedFetchState.RemoteUpdateTipsHandler }, null); + Commands.Fetch(repo, remoteName, Array.Empty(), new FetchOptions { OnUpdateTips = expectedFetchState.RemoteUpdateTipsHandler }, null); // Verify the expected expectedFetchState.CheckUpdatedReferences(repo); @@ -62,7 +62,7 @@ public void CanFetchIntoAnEmptyRepositoryWithCredentials() repo.Network.Remotes.Add(remoteName, Constants.PrivateRepoUrl); // Perform the actual fetch - Commands.Fetch(repo, remoteName, new string[0], new FetchOptions + Commands.Fetch(repo, remoteName, Array.Empty(), new FetchOptions { CredentialsProvider = Constants.PrivateRepoCredentials }, null); @@ -98,7 +98,7 @@ public void CanFetchAllTagsIntoAnEmptyRepository(string url) } // Perform the actual fetch - Commands.Fetch(repo, remoteName, new string[0], new FetchOptions + Commands.Fetch(repo, remoteName, Array.Empty(), new FetchOptions { TagFetchMode = TagFetchMode.All, OnUpdateTips = expectedFetchState.RemoteUpdateTipsHandler @@ -179,7 +179,7 @@ public void FetchRespectsConfiguredAutoTagSetting(TagFetchMode tagFetchMode, int r => r.TagFetchMode = tagFetchMode); // Perform the actual fetch. - Commands.Fetch(repo, remoteName, new string[0], null, null); + Commands.Fetch(repo, remoteName, Array.Empty(), null, null); // Verify the number of fetched tags. Assert.Equal(expectedTagCount, repo.Tags.Count()); @@ -197,7 +197,7 @@ public void CanFetchAllTagsAfterAnInitialClone() using (var repo = new Repository(clonedRepoPath)) { - Commands.Fetch(repo, "origin", new string[0], new FetchOptions { TagFetchMode = TagFetchMode.All }, null); + Commands.Fetch(repo, "origin", Array.Empty(), new FetchOptions { TagFetchMode = TagFetchMode.All }, null); } } @@ -223,17 +223,17 @@ public void FetchHonorsTheFetchPruneConfigurationEntry() // No pruning when the configuration entry isn't defined Assert.Null(clonedRepo.Config.Get("fetch.prune")); - Commands.Fetch(clonedRepo, "origin", new string[0], null, null); + Commands.Fetch(clonedRepo, "origin", Array.Empty(), null, null); Assert.Equal(5, clonedRepo.Branches.Count(b => b.IsRemote && b.FriendlyName != "origin/HEAD")); // No pruning when the configuration entry is set to false clonedRepo.Config.Set("fetch.prune", false); - Commands.Fetch(clonedRepo, "origin", new string[0], null, null); + Commands.Fetch(clonedRepo, "origin", Array.Empty(), null, null); Assert.Equal(5, clonedRepo.Branches.Count(b => b.IsRemote && b.FriendlyName != "origin/HEAD")); // Auto pruning when the configuration entry is set to true clonedRepo.Config.Set("fetch.prune", true); - Commands.Fetch(clonedRepo, "origin", new string[0], null, null); + Commands.Fetch(clonedRepo, "origin", Array.Empty(), null, null); Assert.Equal(4, clonedRepo.Branches.Count(b => b.IsRemote && b.FriendlyName != "origin/HEAD")); } } @@ -248,10 +248,10 @@ public void CannotFetchWithForbiddenCustomHeaders() string clonedRepoPath = Repository.Clone(url, scd.DirectoryPath); const string knownHeader = "User-Agent: mygit-201"; - var options = new FetchOptions { CustomHeaders = new String[] { knownHeader } }; + var options = new FetchOptions { CustomHeaders = new string[] { knownHeader } }; using (var repo = new Repository(clonedRepoPath)) { - Assert.Throws(() => Commands.Fetch(repo, "origin", new string[0], options, null)); + Assert.Throws(() => Commands.Fetch(repo, "origin", Array.Empty(), options, null)); } } @@ -265,10 +265,10 @@ public void CanFetchWithCustomHeaders() string clonedRepoPath = Repository.Clone(url, scd.DirectoryPath); const string knownHeader = "X-Hello: mygit-201"; - var options = new FetchOptions { CustomHeaders = new String[] { knownHeader } }; + var options = new FetchOptions { CustomHeaders = new string[] { knownHeader } }; using (var repo = new Repository(clonedRepoPath)) { - Commands.Fetch(repo, "origin", new string[0], options, null); + Commands.Fetch(repo, "origin", Array.Empty(), options, null); } } @@ -282,10 +282,10 @@ public void CannotFetchWithMalformedCustomHeaders() string clonedRepoPath = Repository.Clone(url, scd.DirectoryPath); const string knownHeader = "Hello world"; - var options = new FetchOptions { CustomHeaders = new String[] { knownHeader } }; + var options = new FetchOptions { CustomHeaders = new string[] { knownHeader } }; using (var repo = new Repository(clonedRepoPath)) { - Assert.Throws(() => Commands.Fetch(repo, "origin", new string[0], options, null)); + Assert.Throws(() => Commands.Fetch(repo, "origin", Array.Empty(), options, null)); } } diff --git a/LibGit2Sharp.Tests/FileHistoryFixture.cs b/LibGit2Sharp.Tests/FileHistoryFixture.cs index e6465d1ac..dcbd0e6d8 100644 --- a/LibGit2Sharp.Tests/FileHistoryFixture.cs +++ b/LibGit2Sharp.Tests/FileHistoryFixture.cs @@ -163,7 +163,7 @@ public void CanTellComplexCommitHistory() var commit4 = MakeAndCommitChange(repo, repoPath, newPath1, "I have done it again!"); // Perform tests. - var commitFilter = new CommitFilter () { SortBy = CommitSortStrategies.Topological }; + var commitFilter = new CommitFilter() { SortBy = CommitSortStrategies.Topological }; var fileHistoryEntries = repo.Commits.QueryBy(newPath1, commitFilter).ToList(); var changedBlobs = fileHistoryEntries.Blobs().Distinct().ToList(); diff --git a/LibGit2Sharp.Tests/FilterBranchFixture.cs b/LibGit2Sharp.Tests/FilterBranchFixture.cs index 60aee38f3..de4663a22 100644 --- a/LibGit2Sharp.Tests/FilterBranchFixture.cs +++ b/LibGit2Sharp.Tests/FilterBranchFixture.cs @@ -3,7 +3,6 @@ using System.Linq; using LibGit2Sharp.Tests.TestHelpers; using Xunit; -using Xunit.Extensions; namespace LibGit2Sharp.Tests { @@ -162,10 +161,8 @@ public void CanRewriteAuthorOfCommits() AssertSucceedingButNotError(); - var nonBackedUpRefs = repo.Refs.Where( - x => !x.CanonicalName.StartsWith("refs/original/") && !x.CanonicalName.StartsWith("refs/notes/")); - Assert.Empty(repo.Commits.QueryBy(new CommitFilter { IncludeReachableFrom = nonBackedUpRefs }) - .Where(c => c.Author.Name != "Ben Straub")); + var nonBackedUpRefs = repo.Refs.Where(x => !x.CanonicalName.StartsWith("refs/original/") && !x.CanonicalName.StartsWith("refs/notes/")); + Assert.DoesNotContain(repo.Commits.QueryBy(new CommitFilter { IncludeReachableFrom = nonBackedUpRefs }), c => c.Author.Name != "Ben Straub"); } [Fact] @@ -234,9 +231,9 @@ public void CanRewriteTreesByInjectingTreeEntry() AssertSucceedingButNotError(); - Assert.Equal(new Commit[0], + Assert.Equal(Array.Empty(), repo.Commits - .QueryBy(new CommitFilter {IncludeReachableFrom = repo.Branches}) + .QueryBy(new CommitFilter { IncludeReachableFrom = repo.Branches }) .Where(c => c["README"] != null && c["README"].Target.Id != currentReadme.Target.Id) .ToArray()); @@ -403,9 +400,9 @@ public void CanCustomizeTheNamespaceOfBackedUpRefs(string backupRefsNamespace) AssertSucceedingButNotError(); - Assert.NotEmpty(repo.Refs.Where(x => x.CanonicalName.StartsWith("refs/original"))); + Assert.Contains(repo.Refs, x => x.CanonicalName.StartsWith("refs/original")); - Assert.Empty(repo.Refs.Where(x => x.CanonicalName.StartsWith("refs/rewritten"))); + Assert.DoesNotContain(repo.Refs, x => x.CanonicalName.StartsWith("refs/rewritten")); repo.Refs.RewriteHistory(new RewriteHistoryOptions { @@ -418,7 +415,7 @@ public void CanCustomizeTheNamespaceOfBackedUpRefs(string backupRefsNamespace) AssertSucceedingButNotError(); - Assert.NotEmpty(repo.Refs.Where(x => x.CanonicalName.StartsWith("refs/rewritten"))); + Assert.Contains(repo.Refs, x => x.CanonicalName.StartsWith("refs/rewritten")); } [Fact] @@ -494,7 +491,7 @@ public void DoesNotRewriteRefsThatDontChange() // Ensure br2 is still a merge commit var parents = repo.Branches["br2"].Tip.Parents.ToList(); Assert.Equal(2, parents.Count()); - Assert.NotEmpty(parents.Where(c => c.Sha.StartsWith("9fd738e"))); + Assert.Contains(parents, c => c.Sha.StartsWith("9fd738e")); Assert.Equal("abc", parents.Single(c => !c.Sha.StartsWith("9fd738e")).Message); } @@ -535,7 +532,7 @@ public void CanNotOverWriteBackedUpReferences() var newOriginalRefs = repo.Refs.FromGlob("refs/original/*").OrderBy(r => r.CanonicalName).ToArray(); Assert.Equal(originalRefs, newOriginalRefs); - Assert.Empty(repo.Refs.Where(x => x.CanonicalName.StartsWith("refs/original/original/"))); + Assert.DoesNotContain(repo.Refs, x => x.CanonicalName.StartsWith("refs/original/original/")); } [Fact] diff --git a/LibGit2Sharp.Tests/FilterFixture.cs b/LibGit2Sharp.Tests/FilterFixture.cs index 4de354003..8fd9c8392 100644 --- a/LibGit2Sharp.Tests/FilterFixture.cs +++ b/LibGit2Sharp.Tests/FilterFixture.cs @@ -1,10 +1,9 @@ using System; using System.Collections.Generic; -using System.Linq; using System.IO; +using System.Threading.Tasks; using LibGit2Sharp.Tests.TestHelpers; using Xunit; -using System.Threading.Tasks; namespace LibGit2Sharp.Tests { @@ -174,7 +173,7 @@ public void CleanFilterWritesOutputToObjectTree() } [Fact] - public void CanHandleMultipleSmudgesConcurrently() + public async Task CanHandleMultipleSmudgesConcurrently() { const string decodedInput = "This is a substitution cipher"; const string encodedInput = "Guvf vf n fhofgvghgvba pvcure"; @@ -193,20 +192,18 @@ public void CanHandleMultipleSmudgesConcurrently() for (int i = 0; i < count; i++) { - tasks[i] = Task.Factory.StartNew(() => + tasks[i] = Task.Run(() => { string repoPath = InitNewRepository(); return CheckoutFileForSmudge(repoPath, branchName, encodedInput); }); } - Task.WaitAll(tasks); + var files = await Task.WhenAll(tasks); - foreach(var task in tasks) + foreach (var file in files) { - FileInfo expectedFile = task.Result; - - string readAllText = File.ReadAllText(expectedFile.FullName); + string readAllText = File.ReadAllText(file.FullName); Assert.Equal(decodedInput, readAllText); } } @@ -399,7 +396,7 @@ private FileInfo CheckoutFileForSmudge(string repoPath, string branchName, strin return expectedPath; } - private static FileInfo CommitFileOnBranch(Repository repo, string branchName, String content) + private static FileInfo CommitFileOnBranch(Repository repo, string branchName, string content) { var branch = repo.CreateBranch(branchName); Commands.Checkout(repo, branch.FriendlyName); diff --git a/LibGit2Sharp.Tests/GlobalSettingsFixture.cs b/LibGit2Sharp.Tests/GlobalSettingsFixture.cs index cd237663e..925efc3d0 100644 --- a/LibGit2Sharp.Tests/GlobalSettingsFixture.cs +++ b/LibGit2Sharp.Tests/GlobalSettingsFixture.cs @@ -90,17 +90,32 @@ public void SetExtensions() var extensions = GlobalSettings.GetExtensions(); // Assert that "noop" is supported by default - Assert.Equal(new[] { "noop", "objectformat" }, extensions); + Assert.Equal(new[] { "noop", "objectformat", "worktreeconfig" }, extensions); // Disable "noop" extensions GlobalSettings.SetExtensions("!noop"); extensions = GlobalSettings.GetExtensions(); - Assert.Equal(new[] { "objectformat" }, extensions); + Assert.Equal(new[] { "objectformat", "worktreeconfig" }, extensions); // Enable two new extensions (it will reset the configuration and "noop" will be enabled) GlobalSettings.SetExtensions("partialclone", "newext"); extensions = GlobalSettings.GetExtensions(); - Assert.Equal(new[] { "noop", "objectformat", "partialclone", "newext" }, extensions); + Assert.Equal(new[] { "newext", "noop", "objectformat", "partialclone", "worktreeconfig" }, extensions); + } + + [Fact] + public void OwnerValidation() + { + // Assert that owner validation is enabled by default + Assert.True(GlobalSettings.GetOwnerValidation()); + + // Disable owner validation + GlobalSettings.SetOwnerValidation(false); + Assert.False(GlobalSettings.GetOwnerValidation()); + + // Enable it again + GlobalSettings.SetOwnerValidation(true); + Assert.True(GlobalSettings.GetOwnerValidation()); } } } diff --git a/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj b/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj index c5cbb5f24..fb81a76a3 100644 --- a/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj +++ b/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj @@ -1,7 +1,7 @@  - net472;net6.0;net7.0 + net472;net8.0;net9.0 @@ -11,12 +11,12 @@ - - - - - - + + + + + + diff --git a/LibGit2Sharp.Tests/MergeFixture.cs b/LibGit2Sharp.Tests/MergeFixture.cs index 7ce3ff496..7b1fda718 100644 --- a/LibGit2Sharp.Tests/MergeFixture.cs +++ b/LibGit2Sharp.Tests/MergeFixture.cs @@ -323,7 +323,7 @@ public void CanFastForwardCommit(bool fromDetachedHead, FastForwardStrategy fast string path = SandboxMergeTestRepo(); using (var repo = new Repository(path)) { - if(fromDetachedHead) + if (fromDetachedHead) { Commands.Checkout(repo, repo.Head.Tip.Id.Sha); } @@ -512,7 +512,7 @@ public void CanMergeAndNotCommit() { Commit commitToMerge = repo.Branches["normal_merge"].Tip; - MergeResult result = repo.Merge(commitToMerge, Constants.Signature, new MergeOptions() { CommitOnSuccess = false}); + MergeResult result = repo.Merge(commitToMerge, Constants.Signature, new MergeOptions() { CommitOnSuccess = false }); Assert.Equal(MergeStatus.NonFastForward, result.Status); Assert.Null(result.Commit); @@ -649,7 +649,7 @@ public void CanSpecifyConflictFileStrategy(CheckoutFileConflictStrategy conflict // Get the blob containing the expected content. Blob expectedBlob = null; - switch(conflictStrategy) + switch (conflictStrategy) { case CheckoutFileConflictStrategy.Theirs: expectedBlob = repo.Lookup(conflict.Theirs.Id); @@ -731,7 +731,7 @@ public void CanMergeBranch(string branchName, FastForwardStrategy strategy, Merg string path = SandboxMergeTestRepo(); using (var repo = new Repository(path)) { - Branch branch = repo. Branches[branchName]; + Branch branch = repo.Branches[branchName]; MergeResult result = repo.Merge(branch, Constants.Signature, new MergeOptions() { FastForwardStrategy = strategy }); Assert.Equal(expectedMergeStatus, result.Status); @@ -748,7 +748,7 @@ public void CanMergeIntoOrphanedBranch() repo.Refs.Add("HEAD", "refs/heads/orphan", true); // Remove entries from the working directory - foreach(var entry in repo.RetrieveStatus()) + foreach (var entry in repo.RetrieveStatus()) { Commands.Unstage(repo, entry.FilePath); Commands.Remove(repo, entry.FilePath, true); diff --git a/LibGit2Sharp.Tests/MetaFixture.cs b/LibGit2Sharp.Tests/MetaFixture.cs index b70d9022c..1d0a1d101 100644 --- a/LibGit2Sharp.Tests/MetaFixture.cs +++ b/LibGit2Sharp.Tests/MetaFixture.cs @@ -1,15 +1,12 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using LibGit2Sharp.Tests.TestHelpers; using Xunit; -using Xunit.Extensions; -using Moq; namespace LibGit2Sharp.Tests { @@ -86,7 +83,7 @@ public void TypesInLibGit2DecoratedWithDebuggerDisplayMustFollowTheStandardImplP var typesWithDebuggerDisplayAndInvalidImplPattern = new List(); IEnumerable libGit2SharpTypes = typeof(IRepository).GetTypeInfo().Assembly.GetExportedTypes() - .Where(t => t.GetTypeInfo().GetCustomAttributes(typeof(DebuggerDisplayAttribute), false).Any()); + .Where(t => t.GetTypeInfo().GetCustomAttributes(typeof(DebuggerDisplayAttribute), false).Length != 0); foreach (Type type in libGit2SharpTypes) { @@ -113,9 +110,9 @@ public void TypesInLibGit2DecoratedWithDebuggerDisplayMustFollowTheStandardImplP } } - if (typesWithDebuggerDisplayAndInvalidImplPattern.Any()) + if (typesWithDebuggerDisplayAndInvalidImplPattern.Count != 0) { - Assert.True(false, Environment.NewLine + BuildMissingDebuggerDisplayPropertyMessage(typesWithDebuggerDisplayAndInvalidImplPattern)); + Assert.Fail(Environment.NewLine + BuildMissingDebuggerDisplayPropertyMessage(typesWithDebuggerDisplayAndInvalidImplPattern)); } } @@ -134,7 +131,7 @@ public void TypesInLibGit2SharpMustBeExtensibleInATestingContext() continue; var nonVirtualMethodNamesForType = GetNonVirtualPublicMethodsNames(type).ToList(); - if (nonVirtualMethodNamesForType.Any()) + if (nonVirtualMethodNamesForType.Count != 0) { nonTestableTypes.Add(type, nonVirtualMethodNamesForType); continue; @@ -168,9 +165,9 @@ public void TypesInLibGit2SharpMustBeExtensibleInATestingContext() } } - if (nonTestableTypes.Any()) + if (nonTestableTypes.Count != 0) { - Assert.True(false, Environment.NewLine + BuildNonTestableTypesMessage(nonTestableTypes)); + Assert.Fail(Environment.NewLine + BuildNonTestableTypesMessage(nonTestableTypes)); } } @@ -196,7 +193,7 @@ private static bool MustBeMockable(Type type) public void EnumsWithFlagsHaveMutuallyExclusiveValues() { var flagsEnums = typeof(IRepository).GetTypeInfo().Assembly.GetExportedTypes() - .Where(t => t.GetTypeInfo().IsEnum && t.GetTypeInfo().GetCustomAttributes(typeof(FlagsAttribute), false).Any()); + .Where(t => t.GetTypeInfo().IsEnum && t.GetTypeInfo().GetCustomAttributes(typeof(FlagsAttribute), false).Length != 0); var overlaps = from t in flagsEnums from int x in Enum.GetValues(t) @@ -280,7 +277,7 @@ public void GetEnumeratorMethodsInLibGit2SharpMustBeVirtualForTestability() (!m.IsVirtual || m.IsFinal)) .ToList(); - if (nonVirtualGetEnumeratorMethods.Any()) + if (nonVirtualGetEnumeratorMethods.Count != 0) { var sb = new StringBuilder(); @@ -290,7 +287,7 @@ public void GetEnumeratorMethodsInLibGit2SharpMustBeVirtualForTestability() method.DeclaringType, Environment.NewLine); } - Assert.True(false, Environment.NewLine + sb.ToString()); + Assert.Fail(Environment.NewLine + sb.ToString()); } } @@ -309,7 +306,7 @@ public void NoPublicTypesUnderLibGit2SharpCoreNamespace() .Where(t => t.FullName != "LibGit2Sharp.Core.LeaksContainer") .ToList(); - if (types.Any()) + if (types.Count != 0) { var sb = new StringBuilder(); @@ -319,7 +316,7 @@ public void NoPublicTypesUnderLibGit2SharpCoreNamespace() type.FullName, coreNamespace, Environment.NewLine); } - Assert.True(false, Environment.NewLine + sb.ToString()); + Assert.Fail(Environment.NewLine + sb.ToString()); } } diff --git a/LibGit2Sharp.Tests/NetworkFixture.cs b/LibGit2Sharp.Tests/NetworkFixture.cs index 3a3517432..f4ad922f6 100644 --- a/LibGit2Sharp.Tests/NetworkFixture.cs +++ b/LibGit2Sharp.Tests/NetworkFixture.cs @@ -249,7 +249,7 @@ public void CanMergeFetchedRefs() Assert.False(repo.RetrieveStatus().Any()); Assert.Equal(repo.Lookup("refs/remotes/origin/master~1"), repo.Head.Tip); - Commands.Fetch(repo, repo.Head.RemoteName, new string[0], null, null); + Commands.Fetch(repo, repo.Head.RemoteName, Array.Empty(), null, null); MergeOptions mergeOptions = new MergeOptions() { @@ -276,7 +276,7 @@ public void CanPruneRefs() using (var repo = new Repository(clonedRepoPath)) { repo.Network.Remotes.Add("pruner", clonedRepoPath2); - Commands.Fetch(repo, "pruner", new string[0], null, null); + Commands.Fetch(repo, "pruner", Array.Empty(), null, null); Assert.NotNull(repo.Refs["refs/remotes/pruner/master"]); // Remove the branch from the source repository @@ -286,11 +286,11 @@ public void CanPruneRefs() } // and by default we don't prune it - Commands.Fetch(repo, "pruner", new string[0], null, null); + Commands.Fetch(repo, "pruner", Array.Empty(), null, null); Assert.NotNull(repo.Refs["refs/remotes/pruner/master"]); // but we do when asked by the user - Commands.Fetch(repo, "pruner", new string[0], new FetchOptions { Prune = true }, null); + Commands.Fetch(repo, "pruner", Array.Empty(), new FetchOptions { Prune = true }, null); Assert.Null(repo.Refs["refs/remotes/pruner/master"]); } } diff --git a/LibGit2Sharp.Tests/NoteFixture.cs b/LibGit2Sharp.Tests/NoteFixture.cs index 98801e3b2..4f23ced5c 100644 --- a/LibGit2Sharp.Tests/NoteFixture.cs +++ b/LibGit2Sharp.Tests/NoteFixture.cs @@ -56,7 +56,7 @@ public void RetrievingNotesFromAGitObjectWhichHasNoNoteYieldsNoResult() [Fact] public void CanRetrieveNotesFromAGitObject() { - var expectedMessages = new [] { "Just Note, don't you understand?\n", "Nope\n", "Not Nope, Note!\n" }; + var expectedMessages = new[] { "Just Note, don't you understand?\n", "Nope\n", "Not Nope, Note!\n" }; string path = SandboxBareTestRepo(); using (var repo = new Repository(path)) diff --git a/LibGit2Sharp.Tests/OdbBackendFixture.cs b/LibGit2Sharp.Tests/OdbBackendFixture.cs index 975d0e88c..65011ce0f 100644 --- a/LibGit2Sharp.Tests/OdbBackendFixture.cs +++ b/LibGit2Sharp.Tests/OdbBackendFixture.cs @@ -26,7 +26,7 @@ private static Commit AddCommitToRepo(IRepository repo) var commit = repo.Commit("Initial commit", author, author); relativeFilepath = "big.txt"; - var zeros = new string('0', 32*1024 + 3); + var zeros = new string('0', 32 * 1024 + 3); Touch(repo.Info.WorkingDirectory, relativeFilepath, zeros); Commands.Stage(repo, relativeFilepath); @@ -145,7 +145,7 @@ public void CanEnumerateTheContentOfTheObjectDatabase() AddCommitToRepo(repo); - var expected = new[]{ "1fe3126", "2b297e6", "6518215", "9daeafb" }; + var expected = new[] { "1fe3126", "2b297e6", "6518215", "9daeafb" }; IEnumerable objs = repo.ObjectDatabase; @@ -296,7 +296,7 @@ public override int Read(ObjectId oid, out UnmanagedMemoryStream data, out Objec if (!m_objectIdToContent.TryGetValue(oid, out gitObject)) { - return (int) ReturnCode.GIT_ENOTFOUND; + return (int)ReturnCode.GIT_ENOTFOUND; } data = Allocate(gitObject.Length); @@ -411,7 +411,7 @@ public override int ExistsPrefix(string shortSha, out ObjectId found) if (numFound > 1) { found = null; - return (int) ReturnCode.GIT_EAMBIGUOUS; + return (int)ReturnCode.GIT_EAMBIGUOUS; } } diff --git a/LibGit2Sharp.Tests/PatchEntryChangesFixture.cs b/LibGit2Sharp.Tests/PatchEntryChangesFixture.cs index dc2552a10..ff4949aa4 100644 --- a/LibGit2Sharp.Tests/PatchEntryChangesFixture.cs +++ b/LibGit2Sharp.Tests/PatchEntryChangesFixture.cs @@ -8,37 +8,37 @@ namespace LibGit2Sharp.Tests { - public class PatchEntryChangesFixture : BaseFixture - { - [Fact] - public void PatchEntryBasics() + public class PatchEntryChangesFixture : BaseFixture { - // Init test repo - var path = SandboxStandardTestRepoGitDir(); - string file = "numbers.txt"; + [Fact] + public void PatchEntryBasics() + { + // Init test repo + var path = SandboxStandardTestRepoGitDir(); + string file = "numbers.txt"; - // The repo - using (var repo = new Repository(path)) - { - Tree rootCommitTree = repo.Lookup("f8d44d7").Tree; - Tree commitTreeWithUpdatedFile = repo.Lookup("ec9e401").Tree; + // The repo + using (var repo = new Repository(path)) + { + Tree rootCommitTree = repo.Lookup("f8d44d7").Tree; + Tree commitTreeWithUpdatedFile = repo.Lookup("ec9e401").Tree; - // Create patch by diffing - using (var patch = repo.Diff.Compare(rootCommitTree, commitTreeWithUpdatedFile)) - { - PatchEntryChanges entryChanges = patch[file]; - Assert.Equal(2, entryChanges.LinesAdded); - Assert.Equal(1, entryChanges.LinesDeleted); - Assert.Equal(187, entryChanges.Patch.Length); - // Smoke test - Assert.Equal(Mode.NonExecutableFile, entryChanges.Mode); - Assert.Equal(new ObjectId("4625a3628cb78970c57e23a2fe2574514ba403c7"), entryChanges.Oid); - Assert.Equal(ChangeKind.Modified, entryChanges.Status); - Assert.Equal(file, entryChanges.OldPath); - Assert.Equal(Mode.NonExecutableFile, entryChanges.OldMode); - Assert.Equal(new ObjectId("7909961ae96accd75b6813d32e0fc1d6d52ec941"), entryChanges.OldOid); + // Create patch by diffing + using (var patch = repo.Diff.Compare(rootCommitTree, commitTreeWithUpdatedFile)) + { + PatchEntryChanges entryChanges = patch[file]; + Assert.Equal(2, entryChanges.LinesAdded); + Assert.Equal(1, entryChanges.LinesDeleted); + Assert.Equal(187, entryChanges.Patch.Length); + // Smoke test + Assert.Equal(Mode.NonExecutableFile, entryChanges.Mode); + Assert.Equal(new ObjectId("4625a3628cb78970c57e23a2fe2574514ba403c7"), entryChanges.Oid); + Assert.Equal(ChangeKind.Modified, entryChanges.Status); + Assert.Equal(file, entryChanges.OldPath); + Assert.Equal(Mode.NonExecutableFile, entryChanges.OldMode); + Assert.Equal(new ObjectId("7909961ae96accd75b6813d32e0fc1d6d52ec941"), entryChanges.OldOid); + } + } } - } } - } } diff --git a/LibGit2Sharp.Tests/PushFixture.cs b/LibGit2Sharp.Tests/PushFixture.cs index d8cf2befe..824c1d8c0 100644 --- a/LibGit2Sharp.Tests/PushFixture.cs +++ b/LibGit2Sharp.Tests/PushFixture.cs @@ -12,8 +12,7 @@ public class PushFixture : BaseFixture { private void OnPushStatusError(PushStatusError pushStatusErrors) { - Assert.True(false, string.Format("Failed to update reference '{0}': {1}", - pushStatusErrors.Reference, pushStatusErrors.Message)); + Assert.Fail(string.Format("Failed to update reference '{0}': {1}", pushStatusErrors.Reference, pushStatusErrors.Message)); } private void AssertPush(Action push) @@ -196,6 +195,33 @@ public void CanForcePush() } } + [Fact] + public void CanPushWithCustomHeaders() + { + const string knownHeader = "X-Hello: mygit-201"; + var options = new PushOptions { CustomHeaders = new string[] { knownHeader } }; + AssertPush(repo => + repo.Network.Push(repo.Network.Remotes["origin"], "HEAD", @"refs/heads/master", options)); + } + + [Fact] + public void CannotPushWithForbiddenCustomHeaders() + { + const string knownHeader = "User-Agent: mygit-201"; + var options = new PushOptions { CustomHeaders = new string[] { knownHeader } }; + Assert.Throws( + () => AssertPush(repo => repo.Network.Push(repo.Network.Remotes["origin"], "HEAD", @"refs/heads/master", options))); + } + + [Fact] + public void CannotPushWithMalformedCustomHeaders() + { + const string knownHeader = "Hello world"; + var options = new PushOptions { CustomHeaders = new string[] { knownHeader } }; + Assert.Throws( + () => AssertPush(repo => repo.Network.Push(repo.Network.Remotes["origin"], "HEAD", @"refs/heads/master", options))); + } + private static void AssertRemoteHeadTipEquals(IRepository localRepo, string sha) { var remoteReferences = localRepo.Network.ListReferences(localRepo.Network.Remotes.Single()); diff --git a/LibGit2Sharp.Tests/RebaseFixture.cs b/LibGit2Sharp.Tests/RebaseFixture.cs index 240ca8985..355e19295 100644 --- a/LibGit2Sharp.Tests/RebaseFixture.cs +++ b/LibGit2Sharp.Tests/RebaseFixture.cs @@ -62,7 +62,7 @@ public void CanRebase(string initialBranchName, RebaseOptions options = new RebaseOptions() { - RebaseStepStarting = x => + RebaseStepStarting = x => { beforeRebaseStepCountCorrect &= beforeStepCallCount == x.StepIndex; totalStepCountCorrect &= (x.TotalStepCount == stepCount); @@ -276,7 +276,7 @@ public void VerifyRebaseDetailed(string attributes, string lineEnding, string[] List rebasedCommits = repo.Commits.QueryBy(commitFilter).ToList(); Assert.Equal(3, rebasedCommits.Count); - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { Assert.Equal(expectedTreeIds[i], rebasedCommits[i].Tree.Id); Assert.Equal(Constants.Signature.Name, rebasedCommits[i].Author.Name); diff --git a/LibGit2Sharp.Tests/RefSpecFixture.cs b/LibGit2Sharp.Tests/RefSpecFixture.cs index 50bf3343b..e0639caa8 100644 --- a/LibGit2Sharp.Tests/RefSpecFixture.cs +++ b/LibGit2Sharp.Tests/RefSpecFixture.cs @@ -83,7 +83,7 @@ public void CanReplaceRefSpecs(string[] newFetchRefSpecs, string[] newPushRefSpe repo.Network.Remotes.Update("origin", r => r.FetchRefSpecs = newFetchRefSpecs, r => r.PushRefSpecs = newPushRefSpecs); - Assert.Equal(oldRefSpecs, remote.RefSpecs.ToList()); + Assert.Equal(oldRefSpecs, remote.RefSpecs.ToList()); } using (var newRemote = repo.Network.Remotes["origin"]) diff --git a/LibGit2Sharp.Tests/ReferenceFixture.cs b/LibGit2Sharp.Tests/ReferenceFixture.cs index 186d2e869..b4ec734d5 100644 --- a/LibGit2Sharp.Tests/ReferenceFixture.cs +++ b/LibGit2Sharp.Tests/ReferenceFixture.cs @@ -459,7 +459,7 @@ public void CanUpdateTargetOfADirectReferenceWithAnAbbreviatedSha() Reference master = repo.Refs[masterRef]; Assert.NotEqual(sha, master.ResolveToDirectReference().Target.Sha); - Reference updated = repo.Refs.UpdateTarget(masterRef, sha.Substring(0,4)); + Reference updated = repo.Refs.UpdateTarget(masterRef, sha.Substring(0, 4)); master = repo.Refs[masterRef]; Assert.Equal(updated, master); @@ -556,7 +556,7 @@ public void CanUpdateTargetOfADirectReferenceWithARevparseSpec() const string name = "refs/heads/master"; - var master = (DirectReference) repo.Refs[name]; + var master = (DirectReference)repo.Refs[name]; var @from = master.Target.Id; const string logMessage = "update target message"; @@ -894,7 +894,7 @@ public void CanHandleInvalidArguments() Assert.Throws(() => repo.Refs.ReachableFrom(null)); Assert.Throws(() => repo.Refs.ReachableFrom(null, repo.Commits.Take(2))); Assert.Throws(() => repo.Refs.ReachableFrom(repo.Refs, null)); - Assert.Empty(repo.Refs.ReachableFrom(new Commit[] { })); + Assert.Empty(repo.Refs.ReachableFrom(Array.Empty())); } } } diff --git a/LibGit2Sharp.Tests/ReflogFixture.cs b/LibGit2Sharp.Tests/ReflogFixture.cs index f93952e6e..52973454b 100644 --- a/LibGit2Sharp.Tests/ReflogFixture.cs +++ b/LibGit2Sharp.Tests/ReflogFixture.cs @@ -3,7 +3,6 @@ using System.Linq; using LibGit2Sharp.Tests.TestHelpers; using Xunit; -using Xunit.Extensions; namespace LibGit2Sharp.Tests { @@ -59,7 +58,7 @@ public void CommitShouldCreateReflogEntryOnHeadAndOnTargetedDirectReference() var identity = Constants.Identity; - using (var repo = new Repository(repoPath, new RepositoryOptions{ Identity = identity })) + using (var repo = new Repository(repoPath, new RepositoryOptions { Identity = identity })) { // setup refs as HEAD => unit_test => master var newRef = repo.Refs.Add("refs/heads/unit_test", "refs/heads/master"); @@ -84,8 +83,12 @@ public void CommitShouldCreateReflogEntryOnHeadAndOnTargetedDirectReference() Assert.Equal(identity.Name, reflogEntry.Committer.Name); Assert.Equal(identity.Email, reflogEntry.Committer.Email); - var now = DateTimeOffset.Now; - Assert.InRange(reflogEntry.Committer.When, before, now); + // When verifying the timestamp range, give a little more room on the range. + // Git or file system datetime truncation seems to cause these stamps to jump up to a second earlier + // than we expect. See https://github.com/libgit2/libgit2sharp/issues/1764 + var low = before - TimeSpan.FromSeconds(1); + var high = DateTimeOffset.Now.TruncateMilliseconds() + TimeSpan.FromSeconds(1); + Assert.InRange(reflogEntry.Committer.When, low, high); Assert.Equal(commit.Id, reflogEntry.To); Assert.Equal(ObjectId.Zero, reflogEntry.From); @@ -97,7 +100,7 @@ public void CommitShouldCreateReflogEntryOnHeadAndOnTargetedDirectReference() Assert.Equal(identity.Name, reflogEntry.Committer.Name); Assert.Equal(identity.Email, reflogEntry.Committer.Email); - Assert.InRange(reflogEntry.Committer.When, before, now); + Assert.InRange(reflogEntry.Committer.When, low, high); Assert.Equal(commit.Id, reflogEntry.To); Assert.Equal(ObjectId.Zero, reflogEntry.From); @@ -160,8 +163,12 @@ public void CommitOnDetachedHeadShouldInsertReflogEntry() Assert.Equal(identity.Name, reflogEntry.Committer.Name); Assert.Equal(identity.Email, reflogEntry.Committer.Email); - var now = DateTimeOffset.Now; - Assert.InRange(reflogEntry.Committer.When, before, now); + // When verifying the timestamp range, give a little more room on the range. + // Git or file system datetime truncation seems to cause these stamps to jump up to a second earlier + // than we expect. See https://github.com/libgit2/libgit2sharp/issues/1764 + var low = before - TimeSpan.FromSeconds(1); + var high = DateTimeOffset.Now.TruncateMilliseconds() + TimeSpan.FromSeconds(1); + Assert.InRange(reflogEntry.Committer.When, low, high); Assert.Equal(commit.Id, reflogEntry.To); Assert.Equal(string.Format("commit: {0}", commitMessage), repo.Refs.Log("HEAD").First().Message); @@ -202,7 +209,7 @@ public void AppendingToReflogDependsOnCoreLogAllRefUpdatesSetting(bool isBare, b public void UnsignedMethodsWriteCorrectlyToTheReflog() { var repoPath = InitNewRepository(true); - using (var repo = new Repository(repoPath, new RepositoryOptions{ Identity = Constants.Identity })) + using (var repo = new Repository(repoPath, new RepositoryOptions { Identity = Constants.Identity })) { EnableRefLog(repo); diff --git a/LibGit2Sharp.Tests/RemoveFixture.cs b/LibGit2Sharp.Tests/RemoveFixture.cs index e97636d9c..1b74995ca 100644 --- a/LibGit2Sharp.Tests/RemoveFixture.cs +++ b/LibGit2Sharp.Tests/RemoveFixture.cs @@ -28,7 +28,7 @@ public class RemoveFixture : BaseFixture * 'git rm ' fails ("error: '' has local modifications"). */ [InlineData(false, "modified_unstaged_file.txt", false, FileStatus.ModifiedInWorkdir, true, true, FileStatus.NewInWorkdir | FileStatus.DeletedFromIndex)] - [InlineData(true, "modified_unstaged_file.txt", true, FileStatus.ModifiedInWorkdir, true, true, FileStatus.Unaltered)] + [InlineData(true, "modified_unstaged_file.txt", true, FileStatus.ModifiedInWorkdir, true, true, FileStatus.Unaltered)] /*** * Test case: modified file in wd, the modifications have already been promoted to the index. * 'git rm --cached ' works (removes the file from the index) @@ -150,7 +150,7 @@ public void RemovingAnUnknownFileWithLaxExplicitPathsValidationDoesntThrow(strin Commands.Remove(repo, relativePath, i % 2 == 0); Commands.Remove(repo, relativePath, i % 2 == 0, - new ExplicitPathsOptions {ShouldFailOnUnmatchedPath = false}); + new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false }); } } } @@ -169,7 +169,7 @@ public void RemovingAnUnknownFileThrowsIfExplicitPath(string relativePath, FileS Assert.Equal(status, repo.RetrieveStatus(relativePath)); Assert.Throws( - () => Commands.Remove(repo, relativePath, i%2 == 0, new ExplicitPathsOptions())); + () => Commands.Remove(repo, relativePath, i % 2 == 0, new ExplicitPathsOptions())); } } } @@ -182,7 +182,7 @@ public void RemovingFileWithBadParamsThrows() { Assert.Throws(() => Commands.Remove(repo, string.Empty)); Assert.Throws(() => Commands.Remove(repo, (string)null)); - Assert.Throws(() => Commands.Remove(repo, new string[] { })); + Assert.Throws(() => Commands.Remove(repo, Array.Empty())); Assert.Throws(() => Commands.Remove(repo, new string[] { null })); } } diff --git a/LibGit2Sharp.Tests/RepositoryFixture.cs b/LibGit2Sharp.Tests/RepositoryFixture.cs index bf27b6091..ef3e72f07 100644 --- a/LibGit2Sharp.Tests/RepositoryFixture.cs +++ b/LibGit2Sharp.Tests/RepositoryFixture.cs @@ -212,13 +212,13 @@ public void CanFetchFromRemoteByName() } // Perform the actual fetch - Commands.Fetch(repo, remoteName, new string[0], new FetchOptions { OnUpdateTips = expectedFetchState.RemoteUpdateTipsHandler }, null); + Commands.Fetch(repo, remoteName, Array.Empty(), new FetchOptions { OnUpdateTips = expectedFetchState.RemoteUpdateTipsHandler }, null); // Verify the expected state expectedFetchState.CheckUpdatedReferences(repo); // Now fetch the rest of the tags - Commands.Fetch(repo, remoteName, new string[0], new FetchOptions { TagFetchMode = TagFetchMode.All }, null); + Commands.Fetch(repo, remoteName, Array.Empty(), new FetchOptions { TagFetchMode = TagFetchMode.All }, null); // Verify that the "nearly-dangling" tag is now in the repo. Tag nearlyDanglingTag = repo.Tags["nearly-dangling"]; diff --git a/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs b/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs index 707e0ecae..46863f44d 100644 --- a/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs +++ b/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs @@ -110,8 +110,8 @@ public void CanProvideADifferentIndexToAStandardRepo() public void OpeningABareRepoWithoutProvidingBothWorkDirAndIndexThrows() { string path = SandboxBareTestRepo(); - Assert.Throws(() => new Repository(path, new RepositoryOptions {IndexPath = newIndex})); - Assert.Throws(() => new Repository(path, new RepositoryOptions {WorkingDirectoryPath = newWorkdir})); + Assert.Throws(() => new Repository(path, new RepositoryOptions { IndexPath = newIndex })); + Assert.Throws(() => new Repository(path, new RepositoryOptions { WorkingDirectoryPath = newWorkdir })); } [Fact] diff --git a/LibGit2Sharp.Tests/ResetHeadFixture.cs b/LibGit2Sharp.Tests/ResetHeadFixture.cs index 83a7efcb9..5fb841ae0 100644 --- a/LibGit2Sharp.Tests/ResetHeadFixture.cs +++ b/LibGit2Sharp.Tests/ResetHeadFixture.cs @@ -94,7 +94,7 @@ private void AssertSoftReset(Func branchIdentifierRetriever, boo { string repoPath = InitNewRepository(); - using (var repo = new Repository(repoPath, new RepositoryOptions{ Identity = Constants.Identity })) + using (var repo = new Repository(repoPath, new RepositoryOptions { Identity = Constants.Identity })) { FeedTheRepository(repo); diff --git a/LibGit2Sharp.Tests/ResetIndexFixture.cs b/LibGit2Sharp.Tests/ResetIndexFixture.cs index 97a1eef88..d0228ae2b 100644 --- a/LibGit2Sharp.Tests/ResetIndexFixture.cs +++ b/LibGit2Sharp.Tests/ResetIndexFixture.cs @@ -1,4 +1,3 @@ -using System.IO; using System.Linq; using LibGit2Sharp.Tests.TestHelpers; using Xunit; @@ -62,7 +61,7 @@ public void ResetTheIndexWithTheHeadUnstagesEverything() repo.Index.Replace(repo.Head.Tip); RepositoryStatus newStatus = repo.RetrieveStatus(); - Assert.Empty(newStatus.Where(IsStaged)); + Assert.DoesNotContain(newStatus, IsStaged); // Assert that no reflog entry is created Assert.Equal(reflogEntriesCount, repo.Refs.Log(repo.Refs.Head).Count()); @@ -120,7 +119,7 @@ public void CanResetTheIndexWhenARenameExists() repo.Index.Replace(repo.Lookup("32eab9c")); RepositoryStatus status = repo.RetrieveStatus(); - Assert.Empty(status.Where(IsStaged)); + Assert.DoesNotContain(status, IsStaged); } } diff --git a/LibGit2Sharp.Tests/RevertFixture.cs b/LibGit2Sharp.Tests/RevertFixture.cs index b0f12b9dc..c43479f0f 100644 --- a/LibGit2Sharp.Tests/RevertFixture.cs +++ b/LibGit2Sharp.Tests/RevertFixture.cs @@ -157,7 +157,7 @@ public void RevertWithFileConflictStrategyOption(CheckoutFileConflictStrategy co FileConflictStrategy = conflictStrategy, }; - RevertResult result = repo.Revert(repo.Head.Tip.Parents.First(), Constants.Signature, options); + RevertResult result = repo.Revert(repo.Head.Tip.Parents.First(), Constants.Signature, options); Assert.Equal(RevertStatus.Conflicts, result.Status); // Verify there is a conflict. @@ -288,7 +288,7 @@ public void RevertFindsRenames(bool? findRenames) RevertResult result = repo.Revert(commitToRevert, Constants.Signature, options); Assert.NotNull(result); - if(!findRenames.HasValue || + if (!findRenames.HasValue || findRenames.Value == true) { Assert.Equal(RevertStatus.Reverted, result.Status); @@ -340,7 +340,7 @@ public void CanRevertMergeCommit(int mainline, string expectedId) Assert.Equal(RevertStatus.Reverted, result.Status); Assert.Equal(result.Commit.Sha, expectedId); - if(mainline == 1) + if (mainline == 1) { // In this case, we expect "d_renamed.txt" to be reverted (deleted), // and a.txt to match the tip of the "revert" branch. @@ -351,7 +351,7 @@ public void CanRevertMergeCommit(int mainline, string expectedId) Assert.NotNull(commit); Assert.Equal(commit["a.txt"].Target.Id, repo.Index["a.txt"].Id); } - else if(mainline == 2) + else if (mainline == 2) { // In this case, we expect "d_renamed.txt" to be preset, // and a.txt to match the tip of the master branch. @@ -488,7 +488,7 @@ public void RevertWithNothingToRevertInObjectDatabaseSucceeds() [Fact] public void RevertWithConflictReportsConflict() - { + { // The branch name to perform the revert on, // and the file whose contents we expect to be reverted. const string revertBranchName = "refs/heads/revert"; diff --git a/LibGit2Sharp.Tests/SetErrorFixture.cs b/LibGit2Sharp.Tests/SetErrorFixture.cs index e7e1dbed4..35ee15d26 100644 --- a/LibGit2Sharp.Tests/SetErrorFixture.cs +++ b/LibGit2Sharp.Tests/SetErrorFixture.cs @@ -108,7 +108,7 @@ private string IndentString(int level) return new string(' ', level * 4); } -#region ThrowingOdbBackend + #region ThrowingOdbBackend private class ThrowingOdbBackend : OdbBackend { @@ -180,7 +180,7 @@ public override int ForEach(ForEachCallback callback) } } -#endregion + #endregion } } diff --git a/LibGit2Sharp.Tests/StageFixture.cs b/LibGit2Sharp.Tests/StageFixture.cs index 51cb31a51..c087aa7be 100644 --- a/LibGit2Sharp.Tests/StageFixture.cs +++ b/LibGit2Sharp.Tests/StageFixture.cs @@ -265,7 +265,7 @@ public void StagingFileWithBadParamsThrows() { Assert.Throws(() => Commands.Stage(repo, string.Empty)); Assert.Throws(() => Commands.Stage(repo, (string)null)); - Assert.Throws(() => Commands.Stage(repo, new string[] { })); + Assert.Throws(() => Commands.Stage(repo, Array.Empty())); Assert.Throws(() => Commands.Stage(repo, new string[] { null })); } } @@ -362,7 +362,7 @@ public void IgnoredFilesAreOnlyStagedIfTheyreInTheRepo(string filename, FileStat using (var repo = new Repository(path)) { File.WriteAllText(Path.Combine(repo.Info.WorkingDirectory, ".gitignore"), - String.Format("{0}\n", filename)); + string.Format("{0}\n", filename)); Commands.Stage(repo, filename); Assert.Equal(expected, repo.RetrieveStatus(filename)); @@ -384,7 +384,7 @@ public void CanStageConflictedIgnoredFiles(string filename, FileStatus expected) using (var repo = new Repository(path)) { File.WriteAllText(Path.Combine(repo.Info.WorkingDirectory, ".gitignore"), - String.Format("{0}\n", filename)); + string.Format("{0}\n", filename)); Commands.Stage(repo, filename); Assert.Equal(expected, repo.RetrieveStatus(filename)); diff --git a/LibGit2Sharp.Tests/StashFixture.cs b/LibGit2Sharp.Tests/StashFixture.cs index 7ba379621..27a535e8e 100644 --- a/LibGit2Sharp.Tests/StashFixture.cs +++ b/LibGit2Sharp.Tests/StashFixture.cs @@ -287,9 +287,9 @@ public void StashFailsWithUncommittedChangesIntheIndex() Touch(repo.Info.WorkingDirectory, filename2, newContents); Assert.Equal(StashApplyStatus.UncommittedChanges, repo.Stashes.Pop(0, new StashApplyOptions - { - ApplyModifiers = StashApplyModifiers.ReinstateIndex, - })); + { + ApplyModifiers = StashApplyModifiers.ReinstateIndex, + })); Assert.Single(repo.Stashes); Assert.Equal(newContents, File.ReadAllText(Path.Combine(repo.Info.WorkingDirectory, filename))); Assert.Equal(newContents, File.ReadAllText(Path.Combine(repo.Info.WorkingDirectory, filename2))); @@ -317,9 +317,9 @@ public void StashCallsTheCallback() called = false; repo.Stashes.Apply(0, new StashApplyOptions - { - ProgressHandler = (progress) => { called = true; return true; } - }); + { + ProgressHandler = (progress) => { called = true; return true; } + }); Assert.True(called); @@ -327,9 +327,9 @@ public void StashCallsTheCallback() called = false; repo.Stashes.Pop(0, new StashApplyOptions - { - ProgressHandler = (progress) => { called = true; return true; } - }); + { + ProgressHandler = (progress) => { called = true; return true; } + }); Assert.True(called); } diff --git a/LibGit2Sharp.Tests/SubmoduleFixture.cs b/LibGit2Sharp.Tests/SubmoduleFixture.cs index 735bfd938..2d7f04e6d 100644 --- a/LibGit2Sharp.Tests/SubmoduleFixture.cs +++ b/LibGit2Sharp.Tests/SubmoduleFixture.cs @@ -3,7 +3,6 @@ using System.Linq; using LibGit2Sharp.Tests.TestHelpers; using Xunit; -using Xunit.Extensions; namespace LibGit2Sharp.Tests { @@ -240,9 +239,10 @@ public void CanUpdateSubmodule() OnCheckoutProgress = (x, y, z) => checkoutProgressCalled = true, OnCheckoutNotify = (x, y) => { checkoutNotifyCalled = true; return true; }, CheckoutNotifyFlags = CheckoutNotifyFlags.Updated, - OnUpdateTips = (x, y, z) => { updateTipsCalled = true; return true; }, }; + options.FetchOptions.OnUpdateTips = (x, y, z) => { updateTipsCalled = true; return true; }; + repo.Submodules.Init(submodule.Name, false); repo.Submodules.Update(submodule.Name, options); diff --git a/LibGit2Sharp.Tests/TagFixture.cs b/LibGit2Sharp.Tests/TagFixture.cs index 82a940640..9f125806c 100644 --- a/LibGit2Sharp.Tests/TagFixture.cs +++ b/LibGit2Sharp.Tests/TagFixture.cs @@ -164,7 +164,7 @@ public void CanAddAnAnnotatedTagFromObject() { GitObject obj = repo.Lookup(tagTestSha); - Tag newTag = repo.Tags.Add("unit_test",obj, signatureTim, "a new tag"); + Tag newTag = repo.Tags.Add("unit_test", obj, signatureTim, "a new tag"); Assert.NotNull(newTag); Assert.True(newTag.IsAnnotated); Assert.Equal(tagTestSha, newTag.Target.Sha); diff --git a/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs b/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs index 8d9b9ba0c..e9429d562 100644 --- a/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs +++ b/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs @@ -278,7 +278,7 @@ public virtual void Dispose() if (Core.LeaksContainer.TypeNames.Any()) { - Assert.False(true, string.Format("Some handles of the following types haven't been properly released: {0}.{1}" + Assert.Fail(string.Format("Some handles of the following types haven't been properly released: {0}.{1}" + "In order to get some help fixing those leaks, uncomment the define LEAKS_TRACKING in Libgit2Object.cs{1}" + "and run the tests locally.", string.Join(", ", Core.LeaksContainer.TypeNames), Environment.NewLine)); } @@ -471,10 +471,12 @@ protected static void AssertRefLogEntry(IRepository repo, string canonicalName, Assert.Equal(committer.Email, reflogEntry.Committer.Email); - // When verifying the timestamp range, give a little more room on the 'before' side. + // When verifying the timestamp range, give a little more room on the range. // Git or file system datetime truncation seems to cause these stamps to jump up to a second earlier // than we expect. See https://github.com/libgit2/libgit2sharp/issues/1764 - Assert.InRange(reflogEntry.Committer.When, before - TimeSpan.FromSeconds(1), DateTimeOffset.Now); + var low = before - TimeSpan.FromSeconds(1); + var high = DateTimeOffset.Now.TruncateMilliseconds() + TimeSpan.FromSeconds(1); + Assert.InRange(reflogEntry.Committer.When, low, high); } protected static void EnableRefLog(IRepository repository, bool enable = true) diff --git a/LibGit2Sharp.Tests/TestHelpers/Constants.cs b/LibGit2Sharp.Tests/TestHelpers/Constants.cs index b5cd96d7e..d8c14dbca 100644 --- a/LibGit2Sharp.Tests/TestHelpers/Constants.cs +++ b/LibGit2Sharp.Tests/TestHelpers/Constants.cs @@ -61,10 +61,10 @@ public static string BuildPath() if (Environment.GetEnvironmentVariables().Contains(LibGit2TestPath)) { Trace.TraceInformation("{0} environment variable detected", LibGit2TestPath); - tempPath = Environment.GetEnvironmentVariables()[LibGit2TestPath] as String; + tempPath = Environment.GetEnvironmentVariables()[LibGit2TestPath] as string; } - if (String.IsNullOrWhiteSpace(tempPath) || !Directory.Exists(tempPath)) + if (string.IsNullOrWhiteSpace(tempPath) || !Directory.Exists(tempPath)) { Trace.TraceInformation("Using default test path value"); tempPath = Path.GetTempPath(); diff --git a/LibGit2Sharp.Tests/TreeDefinitionFixture.cs b/LibGit2Sharp.Tests/TreeDefinitionFixture.cs index c31bd588e..6c0c0a41a 100644 --- a/LibGit2Sharp.Tests/TreeDefinitionFixture.cs +++ b/LibGit2Sharp.Tests/TreeDefinitionFixture.cs @@ -67,10 +67,10 @@ public void RequestingAnEntryWithBadParamsThrows() [Theory] [InlineData("1/branch_file.txt", "100755", TreeEntryTargetType.Blob, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057")] - [InlineData("README", "100644", TreeEntryTargetType.Blob, "a8233120f6ad708f843d861ce2b7228ec4e3dec6")] - [InlineData("branch_file.txt", "100644", TreeEntryTargetType.Blob, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057")] - [InlineData("new.txt", "100644", TreeEntryTargetType.Blob, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd")] - [InlineData("1", "040000", TreeEntryTargetType.Tree, "7f76480d939dc401415927ea7ef25c676b8ddb8f")] + [InlineData("README", "100644", TreeEntryTargetType.Blob, "a8233120f6ad708f843d861ce2b7228ec4e3dec6")] + [InlineData("branch_file.txt", "100644", TreeEntryTargetType.Blob, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057")] + [InlineData("new.txt", "100644", TreeEntryTargetType.Blob, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd")] + [InlineData("1", "040000", TreeEntryTargetType.Tree, "7f76480d939dc401415927ea7ef25c676b8ddb8f")] public void CanRetrieveEntries(string path, string expectedAttributes, TreeEntryTargetType expectedType, string expectedSha) { string repoPath = SandboxBareTestRepo(); @@ -587,5 +587,23 @@ public void CanAddAnExistingBlobEntryWithAnExistingTree() Assert.NotNull(td["1/branch_file.txt"]); } } + + [Fact] + public void CanRemoveADirectoryWithChildren() + { + const string blobSha = "a8233120f6ad708f843d861ce2b7228ec4e3dec6"; + string path = SandboxBareTestRepo(); + using (var repo = new Repository(path)) + { + TreeDefinition td = new TreeDefinition(); + var blob = repo.Lookup(blobSha); + td.Add("folder/subfolder/file1", blob, Mode.NonExecutableFile); + td.Add("folder/file1", blob, Mode.NonExecutableFile); + td.Remove("folder"); + Assert.Null(td["folder"]); + Tree t = repo.ObjectDatabase.CreateTree(td); + Assert.Null(t["folder"]); + } + } } } diff --git a/LibGit2Sharp.Tests/UnstageFixture.cs b/LibGit2Sharp.Tests/UnstageFixture.cs index a5dc143d3..1eeee0e72 100644 --- a/LibGit2Sharp.Tests/UnstageFixture.cs +++ b/LibGit2Sharp.Tests/UnstageFixture.cs @@ -251,7 +251,7 @@ public void UnstagingFileWithBadParamsThrows() { Assert.Throws(() => Commands.Unstage(repo, string.Empty)); Assert.Throws(() => Commands.Unstage(repo, (string)null)); - Assert.Throws(() => Commands.Unstage(repo, new string[] { })); + Assert.Throws(() => Commands.Unstage(repo, Array.Empty())); Assert.Throws(() => Commands.Unstage(repo, new string[] { null })); } } diff --git a/LibGit2Sharp.Tests/WorktreeFixture.cs b/LibGit2Sharp.Tests/WorktreeFixture.cs index 5a706515b..224a99dbe 100644 --- a/LibGit2Sharp.Tests/WorktreeFixture.cs +++ b/LibGit2Sharp.Tests/WorktreeFixture.cs @@ -1,10 +1,8 @@ -using LibGit2Sharp.Tests.TestHelpers; -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; +using LibGit2Sharp.Tests.TestHelpers; using Xunit; namespace LibGit2Sharp.Tests @@ -238,7 +236,7 @@ public void CanForcePruneLockedWorktree() } [Fact] - public void CanAddWorktree() + public void CanAddWorktree_WithUncommitedChanges() { var repoPath = SandboxWorktreeTestRepo(); using (var repo = new Repository(repoPath)) @@ -252,11 +250,54 @@ public void CanAddWorktree() Assert.False(worktree.IsLocked); Assert.Equal(3, repo.Worktrees.Count()); + + // Check that branch contains same number of files and folders + Assert.True(repo.RetrieveStatus().IsDirty); + var filesInMain = GetFilesOfRepo(repoPath); + var filesInBranch = GetFilesOfRepo(path); + Assert.NotEqual(filesInMain, filesInBranch); + + repo.Reset(ResetMode.Hard); + repo.RemoveUntrackedFiles(); + + Assert.False(repo.RetrieveStatus().IsDirty); + filesInMain = GetFilesOfRepo(repoPath); + filesInBranch = GetFilesOfRepo(path); + Assert.Equal(filesInMain, filesInBranch); } } [Fact] - public void CanAddLockedWorktree() + public void CanAddWorktree_WithCommitedChanges() + { + var repoPath = SandboxWorktreeTestRepo(); + using (var repo = new Repository(repoPath)) + { + // stage all changes + Commands.Stage(repo, "*"); + repo.Commit("Apply all changes", Constants.Signature, Constants.Signature); + + Assert.Equal(2, repo.Worktrees.Count()); + + var name = "blah"; + var path = Path.Combine(repo.Info.WorkingDirectory, "..", "worktrees", name); + var worktree = repo.Worktrees.Add(name, path, false); + Assert.Equal(name, worktree.Name); + Assert.False(worktree.IsLocked); + + Assert.Equal(3, repo.Worktrees.Count()); + + // Check that branch contains same number of files and folders + Assert.False(repo.RetrieveStatus().IsDirty); + var filesInMain = GetFilesOfRepo(repoPath); + var filesInBranch = GetFilesOfRepo(path); + + Assert.Equal(filesInMain, filesInBranch); + } + } + + [Fact] + public void CanAddLockedWorktree_WithUncommitedChanges() { var repoPath = SandboxWorktreeTestRepo(); using (var repo = new Repository(repoPath)) @@ -270,6 +311,48 @@ public void CanAddLockedWorktree() Assert.True(worktree.IsLocked); Assert.Equal(3, repo.Worktrees.Count()); + + // Check that branch contains same number of files and folders + Assert.True(repo.RetrieveStatus().IsDirty); + var filesInMain = GetFilesOfRepo(repoPath); + var filesInBranch = GetFilesOfRepo(path); + Assert.NotEqual(filesInMain, filesInBranch); + + repo.Reset(ResetMode.Hard); + repo.RemoveUntrackedFiles(); + + Assert.False(repo.RetrieveStatus().IsDirty); + filesInMain = GetFilesOfRepo(repoPath); + filesInBranch = GetFilesOfRepo(path); + Assert.Equal(filesInMain, filesInBranch); + } + } + + [Fact] + public void CanAddLockedWorktree_WithCommitedChanges() + { + var repoPath = SandboxWorktreeTestRepo(); + using (var repo = new Repository(repoPath)) + { + // stage all changes + Commands.Stage(repo, "*"); + repo.Commit("Apply all changes", Constants.Signature, Constants.Signature); + + Assert.Equal(2, repo.Worktrees.Count()); + + var name = "blah"; + var path = Path.Combine(repo.Info.WorkingDirectory, "..", "worktrees", name); + var worktree = repo.Worktrees.Add(name, path, true); + Assert.Equal(name, worktree.Name); + Assert.True(worktree.IsLocked); + + Assert.Equal(3, repo.Worktrees.Count()); + + // Check that branch contains same number of files and folders + Assert.False(repo.RetrieveStatus().IsDirty); + var filesInMain = GetFilesOfRepo(repoPath); + var filesInBranch = GetFilesOfRepo(path); + Assert.Equal(filesInMain, filesInBranch); } } @@ -292,7 +375,21 @@ public void CanAddWorktreeForCommittish() Assert.Equal(committish, repository.Head.FriendlyName); } Assert.Equal(3, repo.Worktrees.Count()); + + // Check that branch contains same number of files and folders + var filesInCommittish = new string[] { "numbers.txt", "super-file.txt" }; + var filesInBranch = GetFilesOfRepo(path); + Assert.Equal(filesInCommittish, filesInBranch); } } + + private static IEnumerable GetFilesOfRepo(string repoPath) + { + return Directory.GetFiles(repoPath, "*", SearchOption.AllDirectories) + .Where(fileName => !fileName.StartsWith(Path.Combine(repoPath, ".git"))) + .Select(fileName => fileName.Replace($"{repoPath}{Path.DirectorySeparatorChar}", "")) + .OrderBy(fileName => fileName) + .ToList(); + } } } diff --git a/LibGit2Sharp.Tests/desktop/SmartSubtransportFixture.cs b/LibGit2Sharp.Tests/desktop/SmartSubtransportFixture.cs index ff4d0fcd6..4e3b03ce3 100644 --- a/LibGit2Sharp.Tests/desktop/SmartSubtransportFixture.cs +++ b/LibGit2Sharp.Tests/desktop/SmartSubtransportFixture.cs @@ -61,7 +61,7 @@ public void CustomSmartSubtransportTest(string scheme, string url) } // Perform the actual fetch - Commands.Fetch(repo, remoteName, new string[0], + Commands.Fetch(repo, remoteName, Array.Empty(), new FetchOptions { OnUpdateTips = expectedFetchState.RemoteUpdateTipsHandler, TagFetchMode = TagFetchMode.Auto }, null); @@ -161,29 +161,29 @@ public void CannotUnregisterTwice() private class MockSmartSubtransport : RpcSmartSubtransport { - protected override SmartSubtransportStream Action(String url, GitSmartSubtransportAction action) + protected override SmartSubtransportStream Action(string url, GitSmartSubtransportAction action) { - String endpointUrl, contentType = null; + string endpointUrl, contentType = null; bool isPost = false; switch (action) { case GitSmartSubtransportAction.UploadPackList: - endpointUrl = String.Concat(url, "/info/refs?service=git-upload-pack"); + endpointUrl = string.Concat(url, "/info/refs?service=git-upload-pack"); break; case GitSmartSubtransportAction.UploadPack: - endpointUrl = String.Concat(url, "/git-upload-pack"); + endpointUrl = string.Concat(url, "/git-upload-pack"); contentType = "application/x-git-upload-pack-request"; isPost = true; break; case GitSmartSubtransportAction.ReceivePackList: - endpointUrl = String.Concat(url, "/info/refs?service=git-receive-pack"); + endpointUrl = string.Concat(url, "/info/refs?service=git-receive-pack"); break; case GitSmartSubtransportAction.ReceivePack: - endpointUrl = String.Concat(url, "/git-receive-pack"); + endpointUrl = string.Concat(url, "/git-receive-pack"); contentType = "application/x-git-receive-pack-request"; isPost = true; break; @@ -313,7 +313,7 @@ private HttpWebResponse GetResponseWithRedirects() } // rethrow if it's not 401 - throw ex; + throw; } if (response.StatusCode == HttpStatusCode.Moved || response.StatusCode == HttpStatusCode.Redirect) diff --git a/LibGit2Sharp/AfterRebaseStepInfo.cs b/LibGit2Sharp/AfterRebaseStepInfo.cs index 8e6e78e2d..54558b59d 100644 --- a/LibGit2Sharp/AfterRebaseStepInfo.cs +++ b/LibGit2Sharp/AfterRebaseStepInfo.cs @@ -27,7 +27,7 @@ internal AfterRebaseStepInfo(RebaseStepInfo stepInfo, Commit commit, long comple /// /// internal AfterRebaseStepInfo(RebaseStepInfo stepInfo, long completedStepIndex, long totalStepCount) - : this (stepInfo, null, completedStepIndex, totalStepCount) + : this(stepInfo, null, completedStepIndex, totalStepCount) { WasPatchAlreadyApplied = true; } diff --git a/LibGit2Sharp/AmbiguousSpecificationException.cs b/LibGit2Sharp/AmbiguousSpecificationException.cs index 16c77f6df..b5ddd7963 100644 --- a/LibGit2Sharp/AmbiguousSpecificationException.cs +++ b/LibGit2Sharp/AmbiguousSpecificationException.cs @@ -1,13 +1,17 @@ -using LibGit2Sharp.Core; using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif +using LibGit2Sharp.Core; namespace LibGit2Sharp { /// /// The exception that is thrown when the provided specification cannot uniquely identify a reference, an object or a path. /// +#if NETFRAMEWORK [Serializable] +#endif public class AmbiguousSpecificationException : NativeException { /// @@ -27,10 +31,10 @@ public AmbiguousSpecificationException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public AmbiguousSpecificationException(string format, params object[] args) - : base(String.Format(format, args)) + : base(string.Format(format, args)) { } @@ -43,6 +47,7 @@ public AmbiguousSpecificationException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -51,6 +56,7 @@ public AmbiguousSpecificationException(string message, Exception innerException) protected AmbiguousSpecificationException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif internal override GitErrorCode ErrorCode { diff --git a/LibGit2Sharp/BareRepositoryException.cs b/LibGit2Sharp/BareRepositoryException.cs index 7ee830a0c..412e5e4d4 100644 --- a/LibGit2Sharp/BareRepositoryException.cs +++ b/LibGit2Sharp/BareRepositoryException.cs @@ -1,5 +1,7 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif using LibGit2Sharp.Core; namespace LibGit2Sharp @@ -8,7 +10,9 @@ namespace LibGit2Sharp /// The exception that is thrown when an operation which requires a /// working directory is performed against a bare repository. /// +#if NETFRAMEWORK [Serializable] +#endif public class BareRepositoryException : NativeException { /// @@ -28,7 +32,7 @@ public BareRepositoryException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public BareRepositoryException(string format, params object[] args) : base(format, args) @@ -43,6 +47,7 @@ public BareRepositoryException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -51,6 +56,7 @@ public BareRepositoryException(string message, Exception innerException) protected BareRepositoryException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif internal BareRepositoryException(string message, GitErrorCategory category) : base(message, category) diff --git a/LibGit2Sharp/BlameHunk.cs b/LibGit2Sharp/BlameHunk.cs index 553efb14e..6350a9bbc 100644 --- a/LibGit2Sharp/BlameHunk.cs +++ b/LibGit2Sharp/BlameHunk.cs @@ -114,8 +114,8 @@ private string DebuggerDisplay return string.Format(CultureInfo.InvariantCulture, "{0}-{1} ({2})", FinalStartLineNumber, - FinalStartLineNumber+LineCount-1, - FinalCommit.ToString().Substring(0,7)); + FinalStartLineNumber + LineCount - 1, + FinalCommit.ToString().Substring(0, 7)); } } @@ -135,10 +135,10 @@ public bool Equals(BlameHunk other) } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as BlameHunk); diff --git a/LibGit2Sharp/BlameHunkCollection.cs b/LibGit2Sharp/BlameHunkCollection.cs index 869daf527..2766ee7a6 100644 --- a/LibGit2Sharp/BlameHunkCollection.cs +++ b/LibGit2Sharp/BlameHunkCollection.cs @@ -82,7 +82,7 @@ public virtual BlameHunk HunkForLine(int line) { return hunk; } - throw new ArgumentOutOfRangeException("line", "No hunk for that line"); + throw new ArgumentOutOfRangeException(nameof(line), "No hunk for that line"); } /// diff --git a/LibGit2Sharp/Blob.cs b/LibGit2Sharp/Blob.cs index d3cccf6ac..29ef8d812 100644 --- a/LibGit2Sharp/Blob.cs +++ b/LibGit2Sharp/Blob.cs @@ -13,7 +13,7 @@ namespace LibGit2Sharp /// public class Blob : GitObject { - private readonly ILazy lazySize; + private readonly ILazy lazySize; private readonly ILazy lazyIsBinary; /// diff --git a/LibGit2Sharp/CertificateSsh.cs b/LibGit2Sharp/CertificateSsh.cs index d72b69469..683c04402 100644 --- a/LibGit2Sharp/CertificateSsh.cs +++ b/LibGit2Sharp/CertificateSsh.cs @@ -38,7 +38,7 @@ protected CertificateSsh() internal unsafe CertificateSsh(git_certificate_ssh* cert) { - HasMD5 = cert->type.HasFlag(GitCertificateSshType.MD5); + HasMD5 = cert->type.HasFlag(GitCertificateSshType.MD5); HasSHA1 = cert->type.HasFlag(GitCertificateSshType.SHA1); HashMD5 = new byte[16]; @@ -72,7 +72,7 @@ internal unsafe IntPtr ToPointer() type = sshCertType, }; - fixed (byte *p = &HashMD5[0]) + fixed (byte* p = &HashMD5[0]) { for (var i = 0; i < HashMD5.Length; i++) { @@ -80,7 +80,7 @@ internal unsafe IntPtr ToPointer() } } - fixed (byte *p = &HashSHA1[0]) + fixed (byte* p = &HashSHA1[0]) { for (var i = 0; i < HashSHA1.Length; i++) { diff --git a/LibGit2Sharp/CertificateX509.cs b/LibGit2Sharp/CertificateX509.cs index da45eb43e..7b5b0fac6 100644 --- a/LibGit2Sharp/CertificateX509.cs +++ b/LibGit2Sharp/CertificateX509.cs @@ -23,7 +23,7 @@ protected CertificateX509() internal unsafe CertificateX509(git_certificate_x509* cert) { - int len = checked((int) cert->len.ToUInt32()); + int len = checked((int)cert->len.ToUInt32()); byte[] data = new byte[len]; Marshal.Copy(new IntPtr(cert->data), data, 0, len); Certificate = new X509Certificate(data); @@ -42,7 +42,7 @@ internal unsafe IntPtr ToPointers(out IntPtr dataPtr) var gitCert = new git_certificate_x509() { cert_type = GitCertificateType.X509, - data = (byte*) dataPtr.ToPointer(), + data = (byte*)dataPtr.ToPointer(), len = (UIntPtr)certData.Length, }; diff --git a/LibGit2Sharp/CheckoutConflictException.cs b/LibGit2Sharp/CheckoutConflictException.cs index f2f5092e9..67dc8d2cc 100644 --- a/LibGit2Sharp/CheckoutConflictException.cs +++ b/LibGit2Sharp/CheckoutConflictException.cs @@ -1,5 +1,7 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif using LibGit2Sharp.Core; namespace LibGit2Sharp @@ -9,7 +11,9 @@ namespace LibGit2Sharp /// because of a conflicting change staged in the index, or unstaged /// in the working directory. /// +#if NETFRAMEWORK [Serializable] +#endif public class CheckoutConflictException : NativeException { /// @@ -29,7 +33,7 @@ public CheckoutConflictException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public CheckoutConflictException(string format, params object[] args) : base(format, args) @@ -44,6 +48,7 @@ public CheckoutConflictException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -52,6 +57,7 @@ public CheckoutConflictException(string message, Exception innerException) protected CheckoutConflictException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif internal CheckoutConflictException(string message, GitErrorCategory category) : base(message, category) diff --git a/LibGit2Sharp/CloneOptions.cs b/LibGit2Sharp/CloneOptions.cs index f88ff58d7..12d47c9f3 100644 --- a/LibGit2Sharp/CloneOptions.cs +++ b/LibGit2Sharp/CloneOptions.cs @@ -4,12 +4,23 @@ namespace LibGit2Sharp { /// - /// Options to define clone behaviour + /// Options to define clone behavior /// - public sealed class CloneOptions : FetchOptionsBase, IConvertableToGitCheckoutOpts + public sealed class CloneOptions : IConvertableToGitCheckoutOpts { /// - /// Creates default for a non-bare clone + /// Creates with specified for a non-bare clone. + /// + /// The fetch options to use. + public CloneOptions(FetchOptions fetchOptions) : this() + { + Ensure.ArgumentNotNull(fetchOptions, "fetchOptions"); + + FetchOptions = fetchOptions; + } + + /// + /// Creates default for a non-bare clone. /// public CloneOptions() { @@ -46,7 +57,7 @@ public CloneOptions() /// /// Gets or sets the fetch options. /// - public FetchOptions FetchOptions { get; set; } + public FetchOptions FetchOptions { get; } = new(); #region IConvertableToGitCheckoutOpts diff --git a/LibGit2Sharp/Commands/Fetch.cs b/LibGit2Sharp/Commands/Fetch.cs index d61fca5a5..e531aac51 100644 --- a/LibGit2Sharp/Commands/Fetch.cs +++ b/LibGit2Sharp/Commands/Fetch.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using LibGit2Sharp; using LibGit2Sharp.Core; using LibGit2Sharp.Core.Handles; @@ -75,7 +74,7 @@ public static void Fetch(Repository repository, string remote, IEnumerable(), options.FetchOptions, null); return repository.MergeFetchedRefs(merger, options.MergeOptions); } } diff --git a/LibGit2Sharp/Commands/Stage.cs b/LibGit2Sharp/Commands/Stage.cs index a1febafcb..d11bf6f76 100644 --- a/LibGit2Sharp/Commands/Stage.cs +++ b/LibGit2Sharp/Commands/Stage.cs @@ -237,7 +237,7 @@ public static void Move(IRepository repository, IEnumerable sourcePaths, if (batch.Count == 0) { - throw new ArgumentNullException("sourcePaths"); + throw new ArgumentNullException(nameof(sourcePaths)); } foreach (KeyValuePair, Tuple> keyValuePair in batch) diff --git a/LibGit2Sharp/ConfigurationLevel.cs b/LibGit2Sharp/ConfigurationLevel.cs index 9fd57df28..f0971a1c1 100644 --- a/LibGit2Sharp/ConfigurationLevel.cs +++ b/LibGit2Sharp/ConfigurationLevel.cs @@ -5,6 +5,11 @@ /// public enum ConfigurationLevel { + /// + /// Worktree specific configuration file; $GIT_DIR/config.worktree + /// + Worktree = 6, + /// /// The local .git/config of the current repository. /// diff --git a/LibGit2Sharp/Conflict.cs b/LibGit2Sharp/Conflict.cs index 252535af1..705f66d15 100644 --- a/LibGit2Sharp/Conflict.cs +++ b/LibGit2Sharp/Conflict.cs @@ -61,12 +61,12 @@ public virtual IndexEntry Theirs } /// - /// Determines whether the specified is + /// Determines whether the specified is /// equal to the current . /// - /// The to compare with + /// The to compare with /// the current . - /// true if the specified is equal + /// true if the specified is equal /// to the current ; otherwise, /// false. public override bool Equals(object obj) diff --git a/LibGit2Sharp/Core/EncodingMarshaler.cs b/LibGit2Sharp/Core/EncodingMarshaler.cs index 0cafd9aa1..cb02c649b 100644 --- a/LibGit2Sharp/Core/EncodingMarshaler.cs +++ b/LibGit2Sharp/Core/EncodingMarshaler.cs @@ -32,7 +32,7 @@ public int GetNativeDataSize() return -1; } - public virtual IntPtr MarshalManagedToNative(Object managedObj) + public virtual IntPtr MarshalManagedToNative(object managedObj) { if (managedObj == null) { @@ -51,14 +51,14 @@ public virtual IntPtr MarshalManagedToNative(Object managedObj) return FromManaged(encoding, str); } - public virtual Object MarshalNativeToManaged(IntPtr pNativeData) + public virtual object MarshalNativeToManaged(IntPtr pNativeData) { return FromNative(encoding, pNativeData); } #endregion - public static unsafe IntPtr FromManaged(Encoding encoding, String value) + public static unsafe IntPtr FromManaged(Encoding encoding, string value) { if (encoding == null || value == null) { @@ -114,10 +114,10 @@ public static unsafe string FromNative(Encoding encoding, byte* pNativeData) if (walk == start) { - return String.Empty; + return string.Empty; } - return new String((sbyte*)pNativeData, 0, (int)(walk - start), encoding); + return new string((sbyte*)pNativeData, 0, (int)(walk - start), encoding); } public static unsafe string FromNative(Encoding encoding, IntPtr pNativeData, int length) @@ -129,10 +129,10 @@ public static unsafe string FromNative(Encoding encoding, IntPtr pNativeData, in if (length == 0) { - return String.Empty; + return string.Empty; } - return new String((sbyte*)pNativeData.ToPointer(), 0, length, encoding); + return new string((sbyte*)pNativeData.ToPointer(), 0, length, encoding); } public static string FromBuffer(Encoding encoding, byte[] buffer) @@ -160,7 +160,7 @@ public static string FromBuffer(Encoding encoding, byte[] buffer, int length) if (length == 0) { - return String.Empty; + return string.Empty; } return encoding.GetString(buffer, 0, length); diff --git a/LibGit2Sharp/Core/Ensure.cs b/LibGit2Sharp/Core/Ensure.cs index 3cf03d24b..cd681e4ba 100644 --- a/LibGit2Sharp/Core/Ensure.cs +++ b/LibGit2Sharp/Core/Ensure.cs @@ -49,7 +49,7 @@ public static void ArgumentNotNullOrEmptyString(string argumentValue, string arg { ArgumentNotNull(argumentValue, argumentName); - if (String.IsNullOrWhiteSpace (argumentValue)) + if (string.IsNullOrWhiteSpace(argumentValue)) { throw new ArgumentException("String cannot be empty", argumentName); } @@ -256,7 +256,7 @@ public static void GitObjectIsNotNull(GitObject gitObject, string identifier) } var messageFormat = "No valid git object identified by '{0}' exists in the repository."; - + if (string.Equals("HEAD", identifier, StringComparison.Ordinal)) { throw new UnbornBranchException(messageFormat, identifier); diff --git a/LibGit2Sharp/Core/FileHistory.cs b/LibGit2Sharp/Core/FileHistory.cs index 5c10a1a24..5775d0ab8 100644 --- a/LibGit2Sharp/Core/FileHistory.cs +++ b/LibGit2Sharp/Core/FileHistory.cs @@ -74,7 +74,7 @@ internal FileHistory(Repository repo, string path, CommitFilter queryFilter) if (!AllowedSortStrategies.Contains(queryFilter.SortBy)) { throw new ArgumentException("Unsupported sort strategy. Only 'Topological', 'Time', or 'Topological | Time' are allowed.", - "queryFilter"); + nameof(queryFilter)); } _repo = repo; diff --git a/LibGit2Sharp/Core/FilePathMarshaler.cs b/LibGit2Sharp/Core/FilePathMarshaler.cs index 209254ac5..af6afb048 100644 --- a/LibGit2Sharp/Core/FilePathMarshaler.cs +++ b/LibGit2Sharp/Core/FilePathMarshaler.cs @@ -57,7 +57,7 @@ internal class StrictFilePathMarshaler : StrictUtf8Marshaler #region ICustomMarshaler - public override IntPtr MarshalManagedToNative(Object managedObj) + public override IntPtr MarshalManagedToNative(object managedObj) { if (null == managedObj) { @@ -105,7 +105,7 @@ internal class LaxFilePathMarshaler : LaxUtf8Marshaler #region ICustomMarshaler - public override Object MarshalNativeToManaged(IntPtr pNativeData) + public override object MarshalNativeToManaged(IntPtr pNativeData) { return FromNative(pNativeData); } diff --git a/LibGit2Sharp/Core/GitBlame.cs b/LibGit2Sharp/Core/GitBlame.cs index df99f44b7..d484b0b4b 100644 --- a/LibGit2Sharp/Core/GitBlame.cs +++ b/LibGit2Sharp/Core/GitBlame.cs @@ -46,7 +46,7 @@ internal class git_blame_options public uint version = 1; public GitBlameOptionFlags flags; - public UInt16 min_match_characters; + public ushort min_match_characters; public git_oid newest_commit; public git_oid oldest_commit; public UIntPtr min_line; @@ -61,7 +61,7 @@ internal unsafe struct git_blame_hunk public git_oid final_commit_id; public UIntPtr final_start_line_number; public git_signature* final_signature; - + public git_oid orig_commit_id; public char* orig_path; public UIntPtr orig_start_line_number; diff --git a/LibGit2Sharp/Core/GitCertificateSshType.cs b/LibGit2Sharp/Core/GitCertificateSshType.cs index a5151123c..4fc432e9a 100644 --- a/LibGit2Sharp/Core/GitCertificateSshType.cs +++ b/LibGit2Sharp/Core/GitCertificateSshType.cs @@ -5,7 +5,7 @@ namespace LibGit2Sharp.Core [Flags] internal enum GitCertificateSshType { - MD5 = (1 << 0), + MD5 = (1 << 0), SHA1 = (1 << 1), } } diff --git a/LibGit2Sharp/Core/GitConfigEntry.cs b/LibGit2Sharp/Core/GitConfigEntry.cs index 9eaa9e468..7af657894 100644 --- a/LibGit2Sharp/Core/GitConfigEntry.cs +++ b/LibGit2Sharp/Core/GitConfigEntry.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; namespace LibGit2Sharp.Core @@ -8,9 +7,10 @@ internal unsafe struct GitConfigEntry { public char* namePtr; public char* valuePtr; + public char* backend_type; + public char* origin_path; public uint include_depth; public uint level; public void* freePtr; - public void* payloadPtr; } } diff --git a/LibGit2Sharp/Core/GitDiff.cs b/LibGit2Sharp/Core/GitDiff.cs index cc1ab1af1..44679124d 100644 --- a/LibGit2Sharp/Core/GitDiff.cs +++ b/LibGit2Sharp/Core/GitDiff.cs @@ -231,7 +231,7 @@ internal class GitDiffOptions : IDisposable public uint ContextLines; public uint InterhunkLines; public ushort IdAbbrev; - public Int64 MaxSize; + public long MaxSize; public IntPtr OldPrefixString; public IntPtr NewPrefixString; @@ -255,10 +255,10 @@ internal unsafe struct git_diff_file { public git_oid Id; public char* Path; - public Int64 Size; + public long Size; public GitDiffFlags Flags; - public UInt16 Mode; - public UInt16 IdAbbrev; + public ushort Mode; + public ushort IdAbbrev; } [StructLayout(LayoutKind.Sequential)] @@ -266,8 +266,8 @@ internal unsafe struct git_diff_delta { public ChangeKind status; public GitDiffFlags flags; - public UInt16 similarity; - public UInt16 nfiles; + public ushort similarity; + public ushort nfiles; public git_diff_file old_file; public git_diff_file new_file; } @@ -293,7 +293,7 @@ internal class GitDiffLine public int NewLineNo; public int NumLines; public UIntPtr contentLen; - public Int64 contentOffset; + public long contentOffset; public IntPtr content; } @@ -371,10 +371,10 @@ internal class GitDiffFindOptions { public uint Version = 1; public GitDiffFindFlags Flags; - public UInt16 RenameThreshold; - public UInt16 RenameFromRewriteThreshold; - public UInt16 CopyThreshold; - public UInt16 BreakRewriteThreshold; + public ushort RenameThreshold; + public ushort RenameFromRewriteThreshold; + public ushort CopyThreshold; + public ushort BreakRewriteThreshold; public UIntPtr RenameLimit; // TODO diff --git a/LibGit2Sharp/Core/GitFetchOptions.cs b/LibGit2Sharp/Core/GitFetchOptions.cs index d82e2f219..26f4c8c7e 100644 --- a/LibGit2Sharp/Core/GitFetchOptions.cs +++ b/LibGit2Sharp/Core/GitFetchOptions.cs @@ -11,6 +11,7 @@ internal class GitFetchOptions public bool UpdateFetchHead = true; public TagFetchMode download_tags; public GitProxyOptions ProxyOptions; + public int Depth = 0; // GIT_FETCH_DEPTH_FULL public RemoteRedirectMode FollowRedirects = RemoteRedirectMode.Initial; public GitStrArrayManaged CustomHeaders; } diff --git a/LibGit2Sharp/Core/GitFetchOptionsWrapper.cs b/LibGit2Sharp/Core/GitFetchOptionsWrapper.cs index 351947bbe..9c7f3952a 100644 --- a/LibGit2Sharp/Core/GitFetchOptionsWrapper.cs +++ b/LibGit2Sharp/Core/GitFetchOptionsWrapper.cs @@ -2,8 +2,8 @@ namespace LibGit2Sharp.Core { - /// - /// Git fetch options wrapper. Disposable wrapper for GitFetchOptions + /// + /// Git fetch options wrapper. Disposable wrapper for GitFetchOptions /// internal class GitFetchOptionsWrapper : IDisposable { @@ -11,7 +11,7 @@ public GitFetchOptionsWrapper() : this(new GitFetchOptions()) { } public GitFetchOptionsWrapper(GitFetchOptions fetchOptions) { - this.Options = fetchOptions; + Options = fetchOptions; } public GitFetchOptions Options { get; private set; } @@ -23,7 +23,8 @@ protected virtual void Dispose(bool disposing) if (disposedValue) return; - this.Options.CustomHeaders.Dispose(); + Options.CustomHeaders.Dispose(); + EncodingMarshaler.Cleanup(Options.ProxyOptions.Url); disposedValue = true; } diff --git a/LibGit2Sharp/Core/GitObjectLazyGroup.cs b/LibGit2Sharp/Core/GitObjectLazyGroup.cs index 11c83a81e..f00900837 100644 --- a/LibGit2Sharp/Core/GitObjectLazyGroup.cs +++ b/LibGit2Sharp/Core/GitObjectLazyGroup.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using LibGit2Sharp.Core.Handles; namespace LibGit2Sharp.Core @@ -21,7 +22,12 @@ protected override void EvaluateInternal(Action evaluator) } } +#if NET + public static ILazy Singleton<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TResult>(Repository repo, ObjectId id, Func resultSelector, bool throwIfMissing = false) +#else public static ILazy Singleton(Repository repo, ObjectId id, Func resultSelector, bool throwIfMissing = false) +#endif + { return Singleton(() => { diff --git a/LibGit2Sharp/Core/GitOdbBackend.cs b/LibGit2Sharp/Core/GitOdbBackend.cs index 6f017542d..c102c94eb 100644 --- a/LibGit2Sharp/Core/GitOdbBackend.cs +++ b/LibGit2Sharp/Core/GitOdbBackend.cs @@ -137,7 +137,7 @@ public delegate int write_callback( public delegate int writestream_callback( out IntPtr stream_out, IntPtr backend, - Int64 length, + long length, GitObjectType type); /// diff --git a/LibGit2Sharp/Core/GitOdbBackendStream.cs b/LibGit2Sharp/Core/GitOdbBackendStream.cs index 984274f04..14b126c7a 100644 --- a/LibGit2Sharp/Core/GitOdbBackendStream.cs +++ b/LibGit2Sharp/Core/GitOdbBackendStream.cs @@ -22,8 +22,8 @@ static GitOdbBackendStream() public GitOdbBackendStreamMode Mode; public IntPtr HashCtx; - public Int64 DeclaredSize; - public Int64 ReceivedBytes; + public long DeclaredSize; + public long ReceivedBytes; public read_callback Read; public write_callback Write; diff --git a/LibGit2Sharp/Core/GitProxyOptions.cs b/LibGit2Sharp/Core/GitProxyOptions.cs index b62b8e08f..85d4057ab 100644 --- a/LibGit2Sharp/Core/GitProxyOptions.cs +++ b/LibGit2Sharp/Core/GitProxyOptions.cs @@ -16,8 +16,8 @@ internal struct GitProxyOptions public uint Version; public GitProxyType Type; public IntPtr Url; - public IntPtr CredentialsCb; - public IntPtr CertificateCheck; - public IntPtr CbPayload; + public NativeMethods.git_cred_acquire_cb Credentials; + public NativeMethods.git_transport_certificate_check_cb CertificateCheck; + public IntPtr Payload; } } diff --git a/LibGit2Sharp/Core/GitProxyOptionsWrapper.cs b/LibGit2Sharp/Core/GitProxyOptionsWrapper.cs new file mode 100644 index 000000000..053213e96 --- /dev/null +++ b/LibGit2Sharp/Core/GitProxyOptionsWrapper.cs @@ -0,0 +1,32 @@ +using System; + +namespace LibGit2Sharp.Core +{ + internal class GitProxyOptionsWrapper : IDisposable + { + public GitProxyOptionsWrapper() : this(new GitProxyOptions()) { } + + public GitProxyOptionsWrapper(GitProxyOptions fetchOptions) + { + Options = fetchOptions; + } + + public GitProxyOptions Options { get; private set; } + + private bool disposedValue = false; + + protected virtual void Dispose(bool disposing) + { + if (disposedValue) + return; + + EncodingMarshaler.Cleanup(Options.Url); + disposedValue = true; + } + + public void Dispose() + { + Dispose(true); + } + } +} diff --git a/LibGit2Sharp/Core/GitPushOptions.cs b/LibGit2Sharp/Core/GitPushOptions.cs index ce1a58f7c..ac9a99e1e 100644 --- a/LibGit2Sharp/Core/GitPushOptions.cs +++ b/LibGit2Sharp/Core/GitPushOptions.cs @@ -11,5 +11,6 @@ internal class GitPushOptions public GitProxyOptions ProxyOptions; public RemoteRedirectMode FollowRedirects = RemoteRedirectMode.Initial; public GitStrArrayManaged CustomHeaders; + public GitStrArrayManaged remote_push_options; } } diff --git a/LibGit2Sharp/Core/GitPushOptionsWrapper.cs b/LibGit2Sharp/Core/GitPushOptionsWrapper.cs new file mode 100644 index 000000000..3ccffcf06 --- /dev/null +++ b/LibGit2Sharp/Core/GitPushOptionsWrapper.cs @@ -0,0 +1,37 @@ +using System; + +namespace LibGit2Sharp.Core +{ + /// + /// Git push options wrapper. Disposable wrapper for . + /// + internal class GitPushOptionsWrapper : IDisposable + { + public GitPushOptionsWrapper() : this(new GitPushOptions()) { } + + public GitPushOptionsWrapper(GitPushOptions pushOptions) + { + this.Options = pushOptions; + } + + public GitPushOptions Options { get; private set; } + + #region IDisposable + private bool disposedValue = false; // To detect redundant calls + protected virtual void Dispose(bool disposing) + { + if (disposedValue) + return; + + this.Options.CustomHeaders.Dispose(); + EncodingMarshaler.Cleanup(Options.ProxyOptions.Url); + disposedValue = true; + } + + public void Dispose() + { + Dispose(true); + } + #endregion + } +} diff --git a/LibGit2Sharp/Core/GitStrArrayNative.cs b/LibGit2Sharp/Core/GitStrArrayNative.cs index 8813f8e6e..01cd18e6e 100644 --- a/LibGit2Sharp/Core/GitStrArrayNative.cs +++ b/LibGit2Sharp/Core/GitStrArrayNative.cs @@ -15,11 +15,11 @@ internal struct GitStrArrayNative : IDisposable /// /// Enumerates each string from the array using the UTF-8 marshaler. /// - public String[] ReadStrings() + public string[] ReadStrings() { var count = checked((int)Array.Count.ToUInt32()); - String[] toReturn = new String[count]; + string[] toReturn = new string[count]; for (int i = 0; i < count; i++) { diff --git a/LibGit2Sharp/Core/GitSubmoduleOptions.cs b/LibGit2Sharp/Core/GitSubmoduleOptions.cs index 59c2b3f80..09a8e8265 100644 --- a/LibGit2Sharp/Core/GitSubmoduleOptions.cs +++ b/LibGit2Sharp/Core/GitSubmoduleOptions.cs @@ -11,8 +11,6 @@ internal struct GitSubmoduleUpdateOptions public GitFetchOptions FetchOptions; - public CheckoutStrategy CloneCheckoutStrategy; - public int AllowFetch; } } diff --git a/LibGit2Sharp/Core/GitWorktree.cs b/LibGit2Sharp/Core/GitWorktree.cs index b3200dd91..2e17bc20d 100644 --- a/LibGit2Sharp/Core/GitWorktree.cs +++ b/LibGit2Sharp/Core/GitWorktree.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; using System.Runtime.InteropServices; -using System.Text; namespace LibGit2Sharp.Core { @@ -36,9 +34,15 @@ internal class git_worktree_add_options public int locked; + public int checkout_existing; + public IntPtr @ref = IntPtr.Zero; - public GitCheckoutOpts checkoutOpts = new GitCheckoutOpts { version = 1 }; + public GitCheckoutOpts checkoutOpts = new GitCheckoutOpts + { + version = 1, + checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_SAFE + }; } [StructLayout(LayoutKind.Sequential)] diff --git a/LibGit2Sharp/Core/Handles/Libgit2Object.cs b/LibGit2Sharp/Core/Handles/Libgit2Object.cs index 892ebde90..a96d99e10 100644 --- a/LibGit2Sharp/Core/Handles/Libgit2Object.cs +++ b/LibGit2Sharp/Core/Handles/Libgit2Object.cs @@ -1,13 +1,13 @@ // This activates a lightweight mode which will help put under the light -// incorrectly released handles by outputing a warning message in the console. +// incorrectly released handles by outputting a warning message in the console. // // This should be activated when tests are being run on the CI server. // // Uncomment the line below or add a conditional symbol to activate this mode -// #define LEAKS_IDENTIFYING +//#define LEAKS_IDENTIFYING -// This activates a more throrough mode which will show the stack trace of the +// This activates a more thorough mode which will show the stack trace of the // allocation code path for each handle that has been improperly released. // // This should be manually activated when some warnings have been raised as @@ -15,17 +15,17 @@ // // Uncomment the line below or add a conditional symbol to activate this mode -// #define LEAKS_TRACKING +//#define LEAKS_TRACKING using System; -using System.Linq; -using System.Diagnostics; -using System.Globalization; -using System.Collections.Generic; +using Microsoft.Win32.SafeHandles; #if LEAKS_IDENTIFYING namespace LibGit2Sharp.Core { + using System.Collections.Generic; + using System.Linq; + /// /// Holds leaked handle type names reported by /// @@ -78,30 +78,27 @@ public static IEnumerable TypeNames namespace LibGit2Sharp.Core.Handles { - internal unsafe abstract class Libgit2Object : IDisposable +#if LEAKS_TRACKING + using System.Diagnostics; + using System.Globalization; +#endif + + internal unsafe abstract class Libgit2Object : SafeHandleZeroOrMinusOneIsInvalid { #if LEAKS_TRACKING private readonly string trace; private readonly Guid id; #endif - protected void* ptr; - - internal void* Handle + internal unsafe Libgit2Object(void* ptr, bool owned) + : this(new IntPtr(ptr), owned) { - get - { - return ptr; - } } - bool owned; - bool disposed; - - internal unsafe Libgit2Object(void* handle, bool owned) + internal unsafe Libgit2Object(IntPtr ptr, bool owned) + : base(owned) { - this.ptr = handle; - this.owned = owned; + SetHandle(ptr); #if LEAKS_TRACKING id = Guid.NewGuid(); @@ -111,35 +108,12 @@ internal unsafe Libgit2Object(void* handle, bool owned) #endif } - internal unsafe Libgit2Object(IntPtr ptr, bool owned) - : this(ptr.ToPointer(), owned) - { - } + internal IntPtr AsIntPtr() => DangerousGetHandle(); - ~Libgit2Object() - { - Dispose(false); - } - - internal bool IsNull - { - get - { - return ptr == null; - } - } - - internal IntPtr AsIntPtr() - { - return new IntPtr(ptr); - } - - public abstract void Free(); - - void Dispose(bool disposing) + protected override void Dispose(bool disposing) { #if LEAKS_IDENTIFYING - bool leaked = !disposing && ptr != null; + bool leaked = !disposing && DangerousGetHandle() != IntPtr.Zero; if (leaked) { @@ -147,17 +121,7 @@ void Dispose(bool disposing) } #endif - if (!disposed) - { - if (owned) - { - Free(); - } - - ptr = null; - } - - disposed = true; + base.Dispose(disposing); #if LEAKS_TRACKING if (!leaked) @@ -172,11 +136,6 @@ void Dispose(bool disposing) } #endif } - - public void Dispose() - { - Dispose(true); - } } } diff --git a/LibGit2Sharp/Core/Handles/Objects.cs b/LibGit2Sharp/Core/Handles/Objects.cs index 5f8db722e..ddca49bee 100644 --- a/LibGit2Sharp/Core/Handles/Objects.cs +++ b/LibGit2Sharp/Core/Handles/Objects.cs @@ -6,8 +6,8 @@ namespace LibGit2Sharp.Core.Handles internal unsafe class TreeEntryHandle : Libgit2Object { - internal TreeEntryHandle(git_tree_entry *ptr, bool owned) - : base((void *) ptr, owned) + internal TreeEntryHandle(git_tree_entry* ptr, bool owned) + : base(ptr, owned) { } @@ -16,21 +16,23 @@ internal TreeEntryHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_tree_entry_free((git_tree_entry*) ptr); + NativeMethods.git_tree_entry_free((git_tree_entry*)AsIntPtr()); + + return true; } public static implicit operator git_tree_entry*(TreeEntryHandle handle) { - return (git_tree_entry*) handle.Handle; + return (git_tree_entry*)handle.AsIntPtr(); } } internal unsafe class ReferenceHandle : Libgit2Object { - internal ReferenceHandle(git_reference *ptr, bool owned) - : base((void *) ptr, owned) + internal ReferenceHandle(git_reference* ptr, bool owned) + : base(ptr, owned) { } @@ -39,21 +41,23 @@ internal ReferenceHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_reference_free((git_reference*) ptr); + NativeMethods.git_reference_free((git_reference*)AsIntPtr()); + + return true; } public static implicit operator git_reference*(ReferenceHandle handle) { - return (git_reference*) handle.Handle; + return (git_reference*)handle.AsIntPtr(); } } internal unsafe class RepositoryHandle : Libgit2Object { - internal RepositoryHandle(git_repository *ptr, bool owned) - : base((void *) ptr, owned) + internal RepositoryHandle(git_repository* ptr, bool owned) + : base(ptr, owned) { } @@ -62,21 +66,23 @@ internal RepositoryHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_repository_free((git_repository*) ptr); + NativeMethods.git_repository_free((git_repository*)AsIntPtr()); + + return true; } public static implicit operator git_repository*(RepositoryHandle handle) { - return (git_repository*) handle.Handle; + return (git_repository*)handle.AsIntPtr(); } } internal unsafe class SignatureHandle : Libgit2Object { - internal SignatureHandle(git_signature *ptr, bool owned) - : base((void *) ptr, owned) + internal SignatureHandle(git_signature* ptr, bool owned) + : base(ptr, owned) { } @@ -85,21 +91,23 @@ internal SignatureHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_signature_free((git_signature*) ptr); + NativeMethods.git_signature_free((git_signature*)AsIntPtr()); + + return true; } public static implicit operator git_signature*(SignatureHandle handle) { - return (git_signature*) handle.Handle; + return (git_signature*)handle.AsIntPtr(); } } internal unsafe class StatusListHandle : Libgit2Object { - internal StatusListHandle(git_status_list *ptr, bool owned) - : base((void *) ptr, owned) + internal StatusListHandle(git_status_list* ptr, bool owned) + : base(ptr, owned) { } @@ -108,21 +116,23 @@ internal StatusListHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_status_list_free((git_status_list*) ptr); + NativeMethods.git_status_list_free((git_status_list*)AsIntPtr()); + + return true; } public static implicit operator git_status_list*(StatusListHandle handle) { - return (git_status_list*) handle.Handle; + return (git_status_list*)handle.AsIntPtr(); } } internal unsafe class BlameHandle : Libgit2Object { - internal BlameHandle(git_blame *ptr, bool owned) - : base((void *) ptr, owned) + internal BlameHandle(git_blame* ptr, bool owned) + : base(ptr, owned) { } @@ -131,21 +141,23 @@ internal BlameHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_blame_free((git_blame*) ptr); + NativeMethods.git_blame_free((git_blame*)AsIntPtr()); + + return true; } public static implicit operator git_blame*(BlameHandle handle) { - return (git_blame*) handle.Handle; + return (git_blame*)handle.AsIntPtr(); } } internal unsafe class DiffHandle : Libgit2Object { - internal DiffHandle(git_diff *ptr, bool owned) - : base((void *) ptr, owned) + internal DiffHandle(git_diff* ptr, bool owned) + : base(ptr, owned) { } @@ -154,21 +166,23 @@ internal DiffHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_diff_free((git_diff*) ptr); + NativeMethods.git_diff_free((git_diff*)AsIntPtr()); + + return true; } public static implicit operator git_diff*(DiffHandle handle) { - return (git_diff*) handle.Handle; + return (git_diff*)handle.AsIntPtr(); } } internal unsafe class PatchHandle : Libgit2Object { - internal PatchHandle(git_patch *ptr, bool owned) - : base((void *) ptr, owned) + internal PatchHandle(git_patch* ptr, bool owned) + : base(ptr, owned) { } @@ -177,21 +191,23 @@ internal PatchHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_patch_free((git_patch*) ptr); + NativeMethods.git_patch_free((git_patch*)AsIntPtr()); + + return true; } public static implicit operator git_patch*(PatchHandle handle) { - return (git_patch*) handle.Handle; + return (git_patch*)handle.AsIntPtr(); } } internal unsafe class ConfigurationHandle : Libgit2Object { - internal ConfigurationHandle(git_config *ptr, bool owned) - : base((void *) ptr, owned) + internal ConfigurationHandle(git_config* ptr, bool owned) + : base(ptr, owned) { } @@ -200,21 +216,23 @@ internal ConfigurationHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_config_free((git_config*) ptr); + NativeMethods.git_config_free((git_config*)AsIntPtr()); + + return true; } public static implicit operator git_config*(ConfigurationHandle handle) { - return (git_config*) handle.Handle; + return (git_config*)handle.AsIntPtr(); } } internal unsafe class ConflictIteratorHandle : Libgit2Object { - internal ConflictIteratorHandle(git_index_conflict_iterator *ptr, bool owned) - : base((void *) ptr, owned) + internal ConflictIteratorHandle(git_index_conflict_iterator* ptr, bool owned) + : base(ptr, owned) { } @@ -223,21 +241,23 @@ internal ConflictIteratorHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_index_conflict_iterator_free((git_index_conflict_iterator*) ptr); + NativeMethods.git_index_conflict_iterator_free((git_index_conflict_iterator*)AsIntPtr()); + + return true; } public static implicit operator git_index_conflict_iterator*(ConflictIteratorHandle handle) { - return (git_index_conflict_iterator*) handle.Handle; + return (git_index_conflict_iterator*)handle.AsIntPtr(); } } internal unsafe class IndexHandle : Libgit2Object { - internal IndexHandle(git_index *ptr, bool owned) - : base((void *) ptr, owned) + internal IndexHandle(git_index* ptr, bool owned) + : base(ptr, owned) { } @@ -246,21 +266,23 @@ internal IndexHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_index_free((git_index*) ptr); + NativeMethods.git_index_free((git_index*)AsIntPtr()); + + return true; } public static implicit operator git_index*(IndexHandle handle) { - return (git_index*) handle.Handle; + return (git_index*)handle.AsIntPtr(); } } internal unsafe class ReflogHandle : Libgit2Object { - internal ReflogHandle(git_reflog *ptr, bool owned) - : base((void *) ptr, owned) + internal ReflogHandle(git_reflog* ptr, bool owned) + : base(ptr, owned) { } @@ -269,21 +291,23 @@ internal ReflogHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_reflog_free((git_reflog*) ptr); + NativeMethods.git_reflog_free((git_reflog*)AsIntPtr()); + + return true; } public static implicit operator git_reflog*(ReflogHandle handle) { - return (git_reflog*) handle.Handle; + return (git_reflog*)handle.AsIntPtr(); } } internal unsafe class TreeBuilderHandle : Libgit2Object { - internal TreeBuilderHandle(git_treebuilder *ptr, bool owned) - : base((void *) ptr, owned) + internal TreeBuilderHandle(git_treebuilder* ptr, bool owned) + : base(ptr, owned) { } @@ -292,21 +316,23 @@ internal TreeBuilderHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_treebuilder_free((git_treebuilder*) ptr); + NativeMethods.git_treebuilder_free((git_treebuilder*)AsIntPtr()); + + return true; } public static implicit operator git_treebuilder*(TreeBuilderHandle handle) { - return (git_treebuilder*) handle.Handle; + return (git_treebuilder*)handle.AsIntPtr(); } } internal unsafe class PackBuilderHandle : Libgit2Object { - internal PackBuilderHandle(git_packbuilder *ptr, bool owned) - : base((void *) ptr, owned) + internal PackBuilderHandle(git_packbuilder* ptr, bool owned) + : base(ptr, owned) { } @@ -315,21 +341,23 @@ internal PackBuilderHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_packbuilder_free((git_packbuilder*) ptr); + NativeMethods.git_packbuilder_free((git_packbuilder*)AsIntPtr()); + + return true; } public static implicit operator git_packbuilder*(PackBuilderHandle handle) { - return (git_packbuilder*) handle.Handle; + return (git_packbuilder*)handle.AsIntPtr(); } } internal unsafe class NoteHandle : Libgit2Object { - internal NoteHandle(git_note *ptr, bool owned) - : base((void *) ptr, owned) + internal NoteHandle(git_note* ptr, bool owned) + : base(ptr, owned) { } @@ -338,21 +366,23 @@ internal NoteHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_note_free((git_note*) ptr); + NativeMethods.git_note_free((git_note*)AsIntPtr()); + + return true; } public static implicit operator git_note*(NoteHandle handle) { - return (git_note*) handle.Handle; + return (git_note*)handle.AsIntPtr(); } } internal unsafe class DescribeResultHandle : Libgit2Object { - internal DescribeResultHandle(git_describe_result *ptr, bool owned) - : base((void *) ptr, owned) + internal DescribeResultHandle(git_describe_result* ptr, bool owned) + : base(ptr, owned) { } @@ -361,21 +391,23 @@ internal DescribeResultHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_describe_result_free((git_describe_result*) ptr); + NativeMethods.git_describe_result_free((git_describe_result*)AsIntPtr()); + + return true; } public static implicit operator git_describe_result*(DescribeResultHandle handle) { - return (git_describe_result*) handle.Handle; + return (git_describe_result*)handle.AsIntPtr(); } } internal unsafe class SubmoduleHandle : Libgit2Object { - internal SubmoduleHandle(git_submodule *ptr, bool owned) - : base((void *) ptr, owned) + internal SubmoduleHandle(git_submodule* ptr, bool owned) + : base(ptr, owned) { } @@ -384,21 +416,23 @@ internal SubmoduleHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_submodule_free((git_submodule*) ptr); + NativeMethods.git_submodule_free((git_submodule*)AsIntPtr()); + + return true; } public static implicit operator git_submodule*(SubmoduleHandle handle) { - return (git_submodule*) handle.Handle; + return (git_submodule*)handle.AsIntPtr(); } } internal unsafe class AnnotatedCommitHandle : Libgit2Object { - internal AnnotatedCommitHandle(git_annotated_commit *ptr, bool owned) - : base((void *) ptr, owned) + internal AnnotatedCommitHandle(git_annotated_commit* ptr, bool owned) + : base(ptr, owned) { } @@ -407,21 +441,23 @@ internal AnnotatedCommitHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_annotated_commit_free((git_annotated_commit*) ptr); + NativeMethods.git_annotated_commit_free((git_annotated_commit*)AsIntPtr()); + + return true; } public static implicit operator git_annotated_commit*(AnnotatedCommitHandle handle) { - return (git_annotated_commit*) handle.Handle; + return (git_annotated_commit*)handle.AsIntPtr(); } } internal unsafe class ObjectDatabaseHandle : Libgit2Object { - internal ObjectDatabaseHandle(git_odb *ptr, bool owned) - : base((void *) ptr, owned) + internal ObjectDatabaseHandle(git_odb* ptr, bool owned) + : base(ptr, owned) { } @@ -430,21 +466,23 @@ internal ObjectDatabaseHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_odb_free((git_odb*) ptr); + NativeMethods.git_odb_free((git_odb*)AsIntPtr()); + + return true; } public static implicit operator git_odb*(ObjectDatabaseHandle handle) { - return (git_odb*) handle.Handle; + return (git_odb*)handle.AsIntPtr(); } } internal unsafe class RevWalkerHandle : Libgit2Object { - internal RevWalkerHandle(git_revwalk *ptr, bool owned) - : base((void *) ptr, owned) + internal RevWalkerHandle(git_revwalk* ptr, bool owned) + : base(ptr, owned) { } @@ -453,21 +491,23 @@ internal RevWalkerHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_revwalk_free((git_revwalk*) ptr); + NativeMethods.git_revwalk_free((git_revwalk*)AsIntPtr()); + + return true; } public static implicit operator git_revwalk*(RevWalkerHandle handle) { - return (git_revwalk*) handle.Handle; + return (git_revwalk*)handle.AsIntPtr(); } } internal unsafe class RemoteHandle : Libgit2Object { - internal RemoteHandle(git_remote *ptr, bool owned) - : base((void *) ptr, owned) + internal RemoteHandle(git_remote* ptr, bool owned) + : base(ptr, owned) { } @@ -476,21 +516,23 @@ internal RemoteHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_remote_free((git_remote*) ptr); + NativeMethods.git_remote_free((git_remote*)AsIntPtr()); + + return true; } public static implicit operator git_remote*(RemoteHandle handle) { - return (git_remote*) handle.Handle; + return (git_remote*)handle.AsIntPtr(); } } internal unsafe class ObjectHandle : Libgit2Object { - internal ObjectHandle(git_object *ptr, bool owned) - : base((void *) ptr, owned) + internal ObjectHandle(git_object* ptr, bool owned) + : base(ptr, owned) { } @@ -499,21 +541,23 @@ internal ObjectHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_object_free((git_object*) ptr); + NativeMethods.git_object_free((git_object*)AsIntPtr()); + + return true; } public static implicit operator git_object*(ObjectHandle handle) { - return (git_object*) handle.Handle; + return (git_object*)handle.AsIntPtr(); } } internal unsafe class RebaseHandle : Libgit2Object { - internal RebaseHandle(git_rebase *ptr, bool owned) - : base((void *) ptr, owned) + internal RebaseHandle(git_rebase* ptr, bool owned) + : base(ptr, owned) { } @@ -522,21 +566,23 @@ internal RebaseHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_rebase_free((git_rebase*) ptr); + NativeMethods.git_rebase_free((git_rebase*)AsIntPtr()); + + return true; } public static implicit operator git_rebase*(RebaseHandle handle) { - return (git_rebase*) handle.Handle; + return (git_rebase*)handle.AsIntPtr(); } } internal unsafe class OdbStreamHandle : Libgit2Object { - internal OdbStreamHandle(git_odb_stream *ptr, bool owned) - : base((void *) ptr, owned) + internal OdbStreamHandle(git_odb_stream* ptr, bool owned) + : base(ptr, owned) { } @@ -545,21 +591,23 @@ internal OdbStreamHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_odb_stream_free((git_odb_stream*) ptr); + NativeMethods.git_odb_stream_free((git_odb_stream*)AsIntPtr()); + + return true; } public static implicit operator git_odb_stream*(OdbStreamHandle handle) { - return (git_odb_stream*) handle.Handle; + return (git_odb_stream*)handle.AsIntPtr(); } } internal unsafe class WorktreeHandle : Libgit2Object { - internal WorktreeHandle(git_worktree *ptr, bool owned) - : base((void *) ptr, owned) + internal WorktreeHandle(git_worktree* ptr, bool owned) + : base(ptr, owned) { } @@ -568,14 +616,16 @@ internal WorktreeHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_worktree_free((git_worktree*) ptr); + NativeMethods.git_worktree_free((git_worktree*)AsIntPtr()); + + return true; } public static implicit operator git_worktree*(WorktreeHandle handle) { - return (git_worktree*) handle.Handle; + return (git_worktree*)handle.AsIntPtr(); } } diff --git a/LibGit2Sharp/Core/Handles/Objects.tt b/LibGit2Sharp/Core/Handles/Objects.tt index a6d1fa251..e522bd859 100644 --- a/LibGit2Sharp/Core/Handles/Objects.tt +++ b/LibGit2Sharp/Core/Handles/Objects.tt @@ -72,8 +72,8 @@ for (var i = 0; i < cNames.Length; i++) #> internal unsafe class <#= csNames[i] #> : Libgit2Object { - internal <#= csNames[i] #>(<#= cNames[i] #> *ptr, bool owned) - : base((void *) ptr, owned) + internal <#= csNames[i] #>(<#= cNames[i] #>* ptr, bool owned) + : base(ptr, owned) { } @@ -82,14 +82,16 @@ for (var i = 0; i < cNames.Length; i++) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.<#= cNames[i] #>_free((<#= cNames[i] #>*) ptr); + NativeMethods.<#= cNames[i] #>_free((<#= cNames[i] #>*)AsIntPtr()); + + return true; } public static implicit operator <#= cNames[i] #>*(<#= csNames[i] #> handle) { - return (<#= cNames[i] #>*) handle.Handle; + return (<#= cNames[i] #>*)handle.AsIntPtr(); } } diff --git a/LibGit2Sharp/Core/HistoryRewriter.cs b/LibGit2Sharp/Core/HistoryRewriter.cs index c4cc2be8b..094d5ca1c 100644 --- a/LibGit2Sharp/Core/HistoryRewriter.cs +++ b/LibGit2Sharp/Core/HistoryRewriter.cs @@ -170,7 +170,7 @@ private Reference RewriteReference( if (repo.Refs.Resolve(backupName) != null) { - throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Can't back up reference '{0}' - '{1}' already exists", oldRef.CanonicalName, backupName)); diff --git a/LibGit2Sharp/Core/LazyGroup.cs b/LibGit2Sharp/Core/LazyGroup.cs index d8b13fa42..bcd160290 100644 --- a/LibGit2Sharp/Core/LazyGroup.cs +++ b/LibGit2Sharp/Core/LazyGroup.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace LibGit2Sharp.Core { @@ -44,7 +45,11 @@ public void Evaluate() protected abstract void EvaluateInternal(Action evaluator); +#if NET + protected static ILazy Singleton<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TResult>(Func resultSelector) +#else protected static ILazy Singleton(Func resultSelector) +#endif { return new LazyWrapper(resultSelector); } @@ -90,7 +95,11 @@ void IEvaluator.Evaluate(TInput input) } } +#if NET + protected class LazyWrapper<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TType> : Lazy, ILazy +#else protected class LazyWrapper : Lazy, ILazy +#endif { public LazyWrapper(Func evaluator) : base(evaluator) diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index e20d755ba..cbb850b16 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -1,6 +1,8 @@ using System; using System.IO; +#if NET using System.Reflection; +#endif using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; @@ -102,7 +104,7 @@ private static IntPtr ResolveDll(string libraryName, Assembly assembly, DllImpor { // The libraries are located at 'runtimes//native/lib{libraryName}.so' // The ends with the processor architecture. e.g. fedora-x64. - string assemblyDirectory = Path.GetDirectoryName(typeof(NativeMethods).Assembly.Location); + string assemblyDirectory = Path.GetDirectoryName(AppContext.BaseDirectory); string processorArchitecture = RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant(); string runtimesDirectory = Path.Combine(assemblyDirectory, "runtimes"); @@ -177,11 +179,11 @@ internal static extern int git_error_set_str( internal static extern void git_error_set_oom(); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern unsafe UInt32 git_blame_get_hunk_count(git_blame* blame); + internal static extern unsafe uint git_blame_get_hunk_count(git_blame* blame); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] internal static extern unsafe git_blame_hunk* git_blame_get_hunk_byindex( - git_blame* blame, UInt32 index); + git_blame* blame, uint index); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] internal static extern unsafe int git_blame_file( @@ -227,7 +229,7 @@ internal static extern unsafe int git_blob_filtered_content( internal static extern unsafe IntPtr git_blob_rawcontent(git_object* blob); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern unsafe Int64 git_blob_rawsize(git_object* blob); + internal static extern unsafe long git_blob_rawsize(git_object* blob); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] internal static extern unsafe int git_branch_create_from_annotated( @@ -743,6 +745,7 @@ internal static extern int git_libgit2_opts(int option, uint level, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string path); // git_libgit2_opts(GIT_OPT_ENABLE_*, int enabled) + // git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, int enabled) [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] internal static extern int git_libgit2_opts(int option, int enabled); @@ -762,6 +765,10 @@ internal static extern int git_libgit2_opts(int option, // git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, git_strarray *out) [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] internal static extern int git_libgit2_opts(int option, out GitStrArray extensions); + + // git_libgit2_opts(GIT_OPT_GET_OWNER_VALIDATION, int *enabled) + [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] + internal static extern unsafe int git_libgit2_opts(int option, int* enabled); #endregion #region git_libgit2_opts_osxarm64 @@ -779,6 +786,7 @@ internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, In [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string path); // git_libgit2_opts(GIT_OPT_ENABLE_*, int enabled) + // git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, int enabled) [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")] internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8, int enabled); @@ -798,6 +806,10 @@ internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, In // git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, git_strarray *out) [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")] internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8, out GitStrArray extensions); + + // git_libgit2_opts(GIT_OPT_GET_OWNER_VALIDATION, int *enabled) + [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")] + internal static extern unsafe int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8, int* enabled); #endregion [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] @@ -1078,7 +1090,7 @@ internal static extern unsafe int git_odb_foreach( IntPtr payload); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern unsafe int git_odb_open_wstream(out git_odb_stream* stream, git_odb* odb, Int64 size, GitObjectType type); + internal static extern unsafe int git_odb_open_wstream(out git_odb_stream* stream, git_odb* odb, long size, GitObjectType type); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] internal static extern unsafe void git_odb_free(git_odb* odb); @@ -1175,7 +1187,7 @@ internal static extern unsafe int git_packbuilder_insert_tree( internal static extern unsafe UIntPtr git_packbuilder_object_count(git_packbuilder* packbuilder); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern unsafe UInt32 git_packbuilder_set_threads(git_packbuilder* packbuilder, UInt32 numThreads); + internal static extern unsafe uint git_packbuilder_set_threads(git_packbuilder* packbuilder, uint numThreads); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] internal static extern unsafe int git_packbuilder_write( diff --git a/LibGit2Sharp/Core/Opaques.cs b/LibGit2Sharp/Core/Opaques.cs index f5613a276..f83e8be10 100644 --- a/LibGit2Sharp/Core/Opaques.cs +++ b/LibGit2Sharp/Core/Opaques.cs @@ -2,31 +2,31 @@ namespace LibGit2Sharp.Core { - internal struct git_tree_entry {} + internal struct git_tree_entry { } internal struct git_reference { } - internal struct git_refspec {} - internal struct git_repository {} - internal struct git_status_list {} - internal struct git_blame {} - internal struct git_diff {} - internal struct git_patch {} - internal struct git_config {} - internal struct git_index_conflict_iterator {} - internal struct git_index {} - internal struct git_reflog {} - internal struct git_reflog_entry {} - internal struct git_treebuilder {} - internal struct git_packbuilder {} - internal struct git_note {} - internal struct git_describe_result {} - internal struct git_submodule {} - internal struct git_annotated_commit {} - internal struct git_odb {} - internal struct git_revwalk {} - internal struct git_remote {} - internal struct git_object {} - internal struct git_rebase {} - internal struct git_odb_stream {} + internal struct git_refspec { } + internal struct git_repository { } + internal struct git_status_list { } + internal struct git_blame { } + internal struct git_diff { } + internal struct git_patch { } + internal struct git_config { } + internal struct git_index_conflict_iterator { } + internal struct git_index { } + internal struct git_reflog { } + internal struct git_reflog_entry { } + internal struct git_treebuilder { } + internal struct git_packbuilder { } + internal struct git_note { } + internal struct git_describe_result { } + internal struct git_submodule { } + internal struct git_annotated_commit { } + internal struct git_odb { } + internal struct git_revwalk { } + internal struct git_remote { } + internal struct git_object { } + internal struct git_rebase { } + internal struct git_odb_stream { } internal struct git_worktree { } } diff --git a/LibGit2Sharp/Core/Platform.cs b/LibGit2Sharp/Core/Platform.cs index 42b752612..1fcb59faf 100644 --- a/LibGit2Sharp/Core/Platform.cs +++ b/LibGit2Sharp/Core/Platform.cs @@ -58,7 +58,11 @@ public static string GetNativeLibraryExtension() /// Returns true if the runtime is Mono. /// public static bool IsRunningOnMono() +#if NETFRAMEWORK => Type.GetType("Mono.Runtime") != null; +#else + => false; +#endif /// /// Returns true if the runtime is .NET Framework. diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index 50cefc0df..83d35e22c 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -86,7 +86,7 @@ public static unsafe UnmanagedMemoryStream git_blob_filtered_content_stream(Repo new[] { buf }); } - public static unsafe UnmanagedMemoryStream git_blob_rawcontent_stream(RepositoryHandle repo, ObjectId id, Int64 size) + public static unsafe UnmanagedMemoryStream git_blob_rawcontent_stream(RepositoryHandle repo, ObjectId id, long size) { var handle = new ObjectSafeWrapper(id, repo, throwIfMissing: true).ObjectPtr; return new RawContentStream(handle, h => NativeMethods.git_blob_rawcontent(h), h => size); @@ -274,7 +274,7 @@ public static unsafe RepositoryHandle git_clone( string workdir, ref GitCloneOptions opts) { - git_repository *repo; + git_repository* repo; int res = NativeMethods.git_clone(out repo, url, workdir, ref opts); Ensure.ZeroResult(res); return new RepositoryHandle(repo, true); @@ -341,13 +341,13 @@ public static unsafe string git_commit_create_buffer( using (var treeHandle = Proxy.git_object_lookup(tree.repo.Handle, tree.Id, GitObjectType.Tree)) using (var buf = new GitBuf()) { - ObjectHandle[] handles = new ObjectHandle[0]; + ObjectHandle[] handles = Array.Empty(); try { handles = parents.Select(c => Proxy.git_object_lookup(c.repo.Handle, c.Id, GitObjectType.Commit)).ToArray(); var ptrs = handles.Select(p => p.AsIntPtr()).ToArray(); int res; - fixed(IntPtr* objs = ptrs) + fixed (IntPtr* objs = ptrs) { res = NativeMethods.git_commit_create_buffer(buf, repo, @@ -497,7 +497,7 @@ public static FilePath git_config_find_programdata() return ConvertPath(NativeMethods.git_config_find_programdata); } - public static unsafe void git_config_free(git_config *config) + public static unsafe void git_config_free(git_config* config) { NativeMethods.git_config_free(config); } @@ -871,7 +871,7 @@ public static int git_error_set_str(GitErrorCategory error_class, Exception exce } } - public static int git_error_set_str(GitErrorCategory error_class, String errorString) + public static int git_error_set_str(GitErrorCategory error_class, string errorString) { return NativeMethods.git_error_set_str(error_class, errorString); } @@ -1615,7 +1615,7 @@ public static unsafe ObjectId git_odb_write(ObjectDatabaseHandle odb, byte[] dat { GitOid id; int res; - fixed(byte* p = data) + fixed (byte* p = data) { res = NativeMethods.git_odb_write(out id, odb, p, new UIntPtr((ulong)data.LongLength), type.ToGitObjectType()); } @@ -1624,9 +1624,9 @@ public static unsafe ObjectId git_odb_write(ObjectDatabaseHandle odb, byte[] dat return id; } -#endregion + #endregion -#region git_patch_ + #region git_patch_ public static unsafe PatchHandle git_patch_from_diff(DiffHandle diff, int idx) { @@ -1650,9 +1650,9 @@ public static unsafe Tuple git_patch_line_stats(PatchHandle patch) return new Tuple((int)add, (int)del); } -#endregion + #endregion -#region git_packbuilder_ + #region git_packbuilder_ public static unsafe PackBuilderHandle git_packbuilder_new(RepositoryHandle repo) { @@ -1716,9 +1716,9 @@ public static unsafe UIntPtr git_packbuilder_written(PackBuilderHandle packbuild { return NativeMethods.git_packbuilder_written(packbuilder); } -#endregion + #endregion -#region git_rebase + #region git_rebase public static unsafe RebaseHandle git_rebase_init( RepositoryHandle repo, @@ -1872,9 +1872,9 @@ public static unsafe void git_rebase_finish( } } -#endregion + #endregion -#region git_reference_ + #region git_reference_ public static unsafe ReferenceHandle git_reference_create( RepositoryHandle repo, @@ -2022,9 +2022,9 @@ public static unsafe void git_reference_ensure_log(RepositoryHandle repo, string Ensure.ZeroResult(res); } -#endregion + #endregion -#region git_reflog_ + #region git_reflog_ public static unsafe ReflogHandle git_reflog_read(RepositoryHandle repo, string canonicalName) { @@ -2066,9 +2066,9 @@ public static unsafe string git_reflog_entry_message(git_reflog_entry* entry) return NativeMethods.git_reflog_entry_message(entry); } -#endregion + #endregion -#region git_refspec + #region git_refspec public static unsafe string git_refspec_transform(IntPtr refSpecPtr, string name) { @@ -2127,9 +2127,9 @@ public static bool git_refspec_dst_matches(IntPtr refspec, string reference) return NativeMethods.git_refspec_dst_matches(refspec, reference); } -#endregion + #endregion -#region git_remote_ + #region git_remote_ public static unsafe TagFetchMode git_remote_autotag(RemoteHandle remote) { @@ -2368,7 +2368,7 @@ public static unsafe IEnumerable git_remote_ls(Repository repository, } var refs = directRefs.Values.ToList(); - refs.Sort((r1, r2) => String.CompareOrdinal(r1.CanonicalName, r2.CanonicalName)); + refs.Sort((r1, r2) => string.CompareOrdinal(r1.CanonicalName, r2.CanonicalName)); return refs; } @@ -2441,9 +2441,9 @@ public static unsafe string git_remote_pushurl(RemoteHandle remote) return NativeMethods.git_remote_pushurl(remote); } -#endregion + #endregion -#region git_repository_ + #region git_repository_ public static FilePath git_repository_discover(FilePath start_path) { @@ -2575,7 +2575,7 @@ public static unsafe RepositoryHandle git_repository_new() public static unsafe void git_repository_open_ext(string path, RepositoryOpenFlags flags, string ceilingDirs) { int res; - git_repository *repo; + git_repository* repo; res = NativeMethods.git_repository_open_ext(out repo, path, flags, ceilingDirs); NativeMethods.git_repository_free(repo); @@ -2652,9 +2652,9 @@ public static unsafe void git_repository_set_head(RepositoryHandle repo, string Ensure.ZeroResult(res); } -#endregion + #endregion -#region git_reset_ + #region git_reset_ public static unsafe void git_reset( RepositoryHandle repo, @@ -2669,9 +2669,9 @@ public static unsafe void git_reset( } } -#endregion + #endregion -#region git_revert_ + #region git_revert_ public static unsafe void git_revert( RepositoryHandle repo, @@ -2741,9 +2741,9 @@ public static ObjectHandle git_revparse_single(RepositoryHandle repo, string obj return handles.Item1; } -#endregion + #endregion -#region git_revwalk_ + #region git_revwalk_ public static unsafe void git_revwalk_hide(RevWalkerHandle walker, ObjectId commit_id) { @@ -2798,9 +2798,9 @@ public static unsafe int git_revwalk_simplify_first_parent(RevWalkerHandle walke return NativeMethods.git_revwalk_simplify_first_parent(walker); } -#endregion + #endregion -#region git_signature_ + #region git_signature_ public static unsafe SignatureHandle git_signature_new(string name, string email, DateTimeOffset when) { @@ -2830,9 +2830,9 @@ public static unsafe SignatureHandle git_signature_now(string name, string email return handle; } -#endregion + #endregion -#region git_stash_ + #region git_stash_ public static unsafe ObjectId git_stash_save( RepositoryHandle repo, @@ -2912,9 +2912,9 @@ public static unsafe StashApplyStatus git_stash_pop( return get_stash_status(NativeMethods.git_stash_pop(repo, (UIntPtr)index, opts)); } -#endregion + #endregion -#region git_status_ + #region git_status_ public static unsafe FileStatus git_status_file(RepositoryHandle repo, FilePath path) { @@ -2960,9 +2960,9 @@ public static unsafe int git_status_list_entrycount(StatusListHandle list) return NativeMethods.git_status_byindex(list, (UIntPtr)idx); } -#endregion + #endregion -#region git_submodule_ + #region git_submodule_ /// /// Returns a handle to the corresponding submodule, @@ -3074,9 +3074,9 @@ public static unsafe void git_submodule_init(SubmoduleHandle submodule, bool ove Ensure.ZeroResult(res); } -#endregion + #endregion -#region git_tag_ + #region git_tag_ public static unsafe ObjectId git_tag_annotation_create( RepositoryHandle repo, @@ -3185,9 +3185,9 @@ public static unsafe GitObjectType git_tag_target_type(ObjectHandle tag) return NativeMethods.git_tag_target_type(tag); } -#endregion + #endregion -#region git_trace_ + #region git_trace_ /// /// Install/Enable logging inside of LibGit2 to send messages back to LibGit2Sharp. @@ -3207,11 +3207,11 @@ public static void git_trace_set(LogLevel level, NativeMethods.git_trace_cb call Ensure.ZeroResult(res); } -#endregion + #endregion -#region git_transport_ + #region git_transport_ - public static void git_transport_register(String prefix, IntPtr transport_cb, IntPtr param) + public static void git_transport_register(string prefix, IntPtr transport_cb, IntPtr param) { int res = NativeMethods.git_transport_register(prefix, transport_cb, param); @@ -3224,7 +3224,7 @@ public static void git_transport_register(String prefix, IntPtr transport_cb, In Ensure.ZeroResult(res); } - public static void git_transport_unregister(String prefix) + public static void git_transport_unregister(string prefix) { int res = NativeMethods.git_transport_unregister(prefix); @@ -3236,18 +3236,18 @@ public static void git_transport_unregister(String prefix) Ensure.ZeroResult(res); } -#endregion + #endregion -#region git_transport_smart_ + #region git_transport_smart_ public static int git_transport_smart_credentials(out IntPtr cred, IntPtr transport, string user, int methods) { return NativeMethods.git_transport_smart_credentials(out cred, transport, user, methods); } -#endregion + #endregion -#region git_tree_ + #region git_tree_ public static unsafe Mode git_tree_entry_attributes(git_tree_entry* entry) { @@ -3303,9 +3303,9 @@ public static unsafe int git_tree_entrycount(ObjectHandle tree) return (int)NativeMethods.git_tree_entrycount(tree); } -#endregion + #endregion -#region git_treebuilder_ + #region git_treebuilder_ public static unsafe TreeBuilderHandle git_treebuilder_new(RepositoryHandle repo) { @@ -3333,9 +3333,9 @@ public static unsafe ObjectId git_treebuilder_write(TreeBuilderHandle bld) return oid; } -#endregion + #endregion -#region git_transaction_ + #region git_transaction_ public static void git_transaction_commit(IntPtr txn) { @@ -3347,9 +3347,9 @@ public static void git_transaction_free(IntPtr txn) NativeMethods.git_transaction_free(txn); } -#endregion + #endregion -#region git_libgit2_ + #region git_libgit2_ /// /// Returns the features with which libgit2 was compiled. @@ -3397,6 +3397,8 @@ private enum LibGit2Option SetOdbLoosePriority, // GIT_OPT_SET_ODB_LOOSE_PRIORITY, GetExtensions, // GIT_OPT_GET_EXTENSIONS, SetExtensions, // GIT_OPT_SET_EXTENSIONS + GetOwnerValidation, // GIT_OPT_GET_OWNER_VALIDATION + SetOwnerValidation, // GIT_OPT_SET_OWNER_VALIDATION } /// @@ -3444,10 +3446,10 @@ public static void git_libgit2_opts_enable_strict_hash_verification(bool enabled public static void git_libgit2_opts_set_search_path(ConfigurationLevel level, string path) { int res; - if (isOSXArm64) - res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.SetSearchPath, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, (uint)level, path); - else - res = NativeMethods.git_libgit2_opts((int)LibGit2Option.SetSearchPath, (uint)level, path); + if (isOSXArm64) + res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.SetSearchPath, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, (uint)level, path); + else + res = NativeMethods.git_libgit2_opts((int)LibGit2Option.SetSearchPath, (uint)level, path); Ensure.ZeroResult(res); } @@ -3459,10 +3461,10 @@ public static void git_libgit2_opts_set_enable_caching(bool enabled) { // libgit2 expects non-zero value for true int res; - if (isOSXArm64) - res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.EnableCaching, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, enabled ? 1 : 0); - else - res = NativeMethods.git_libgit2_opts((int)LibGit2Option.EnableCaching, enabled ? 1 : 0); + if (isOSXArm64) + res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.EnableCaching, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, enabled ? 1 : 0); + else + res = NativeMethods.git_libgit2_opts((int)LibGit2Option.EnableCaching, enabled ? 1 : 0); Ensure.ZeroResult(res); } @@ -3474,10 +3476,10 @@ public static void git_libgit2_opts_set_enable_ofsdelta(bool enabled) { // libgit2 expects non-zero value for true int res; - if (isOSXArm64) - res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.EnableOfsDelta, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, enabled ? 1 : 0); - else - res = NativeMethods.git_libgit2_opts((int)LibGit2Option.EnableOfsDelta, enabled ? 1 : 0); + if (isOSXArm64) + res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.EnableOfsDelta, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, enabled ? 1 : 0); + else + res = NativeMethods.git_libgit2_opts((int)LibGit2Option.EnableOfsDelta, enabled ? 1 : 0); Ensure.ZeroResult(res); } @@ -3489,10 +3491,10 @@ public static void git_libgit2_opts_set_enable_strictobjectcreation(bool enabled { // libgit2 expects non-zero value for true int res; - if (isOSXArm64) - res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.EnableStrictObjectCreation, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, enabled ? 1 : 0); - else - res = NativeMethods.git_libgit2_opts((int)LibGit2Option.EnableStrictObjectCreation, enabled ? 1 : 0); + if (isOSXArm64) + res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.EnableStrictObjectCreation, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, enabled ? 1 : 0); + else + res = NativeMethods.git_libgit2_opts((int)LibGit2Option.EnableStrictObjectCreation, enabled ? 1 : 0); Ensure.ZeroResult(res); } @@ -3504,10 +3506,10 @@ public static void git_libgit2_opts_set_enable_strictobjectcreation(bool enabled public static void git_libgit2_opts_set_user_agent(string userAgent) { int res; - if (isOSXArm64) - res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.SetUserAgent, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, userAgent); - else - res = NativeMethods.git_libgit2_opts((int)LibGit2Option.SetUserAgent, userAgent); + if (isOSXArm64) + res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.SetUserAgent, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, userAgent); + else + res = NativeMethods.git_libgit2_opts((int)LibGit2Option.SetUserAgent, userAgent); Ensure.ZeroResult(res); } @@ -3570,6 +3572,47 @@ public static string[] git_libgit2_opts_get_extensions() } } + /// + /// Gets the value of owner validation + /// + public static unsafe bool git_libgit2_opts_get_owner_validation() + { + int res; + int enabled; + + if (isOSXArm64) + { + res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.GetOwnerValidation, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, &enabled); + } + else + { + res = NativeMethods.git_libgit2_opts((int)LibGit2Option.GetOwnerValidation, &enabled); + } + + Ensure.ZeroResult(res); + + return enabled != 0; + } + + /// + /// Enable or disable owner validation + /// + /// true to enable owner validation, false otherwise + public static void git_libgit2_opts_set_owner_validation(bool enabled) + { + int res; + + if (isOSXArm64) + { + res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.SetOwnerValidation, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, enabled ? 1 : 0); + } + else + { + res = NativeMethods.git_libgit2_opts((int)LibGit2Option.SetOwnerValidation, enabled ? 1 : 0); + } + + Ensure.ZeroResult(res); + } #endregion #region git_worktree_ @@ -3635,7 +3678,7 @@ public static unsafe WorktreeLock git_worktree_is_locked(WorktreeHandle worktree { int res = NativeMethods.git_worktree_is_locked(buf, worktree); - if(res < 0) + if (res < 0) { // error return null; @@ -3707,7 +3750,7 @@ private static ICollection git_foreach( if (ignoredErrorCodes != null && ignoredErrorCodes.Contains((GitErrorCode)res)) { - return new TResult[0]; + return Array.Empty(); } Ensure.ZeroResult(res); @@ -3728,7 +3771,7 @@ private static ICollection git_foreach( if (ignoredErrorCodes != null && ignoredErrorCodes.Contains((GitErrorCode)res)) { - return new TResult[0]; + return Array.Empty(); } Ensure.ZeroResult(res); @@ -3749,7 +3792,7 @@ private static ICollection git_foreach( if (ignoredErrorCodes != null && ignoredErrorCodes.Contains((GitErrorCode)res)) { - return new TResult[0]; + return Array.Empty(); } Ensure.ZeroResult(res); @@ -3772,7 +3815,7 @@ private static ICollection git_foreach( if (ignoredErrorCodes != null && ignoredErrorCodes.Contains((GitErrorCode)res)) { - return new TResult[0]; + return Array.Empty(); } Ensure.ZeroResult(res); diff --git a/LibGit2Sharp/Core/TarWriter.cs b/LibGit2Sharp/Core/TarWriter.cs index 609449316..0a051b9e6 100644 --- a/LibGit2Sharp/Core/TarWriter.cs +++ b/LibGit2Sharp/Core/TarWriter.cs @@ -301,31 +301,31 @@ public UsTarHeader( if (userName.Length > 32) { - throw new ArgumentException("ustar userName cannot be longer than 32 characters.", "userName"); + throw new ArgumentException("ustar userName cannot be longer than 32 characters.", nameof(userName)); } if (groupName.Length > 32) { - throw new ArgumentException("ustar groupName cannot be longer than 32 characters.", "groupName"); + throw new ArgumentException("ustar groupName cannot be longer than 32 characters.", nameof(groupName)); } if (userId.Length > 7) { - throw new ArgumentException("ustar userId cannot be longer than 7 characters.", "userId"); + throw new ArgumentException("ustar userId cannot be longer than 7 characters.", nameof(userId)); } if (groupId.Length > 7) { - throw new ArgumentException("ustar groupId cannot be longer than 7 characters.", "groupId"); + throw new ArgumentException("ustar groupId cannot be longer than 7 characters.", nameof(groupId)); } if (deviceMajorNumber.Length > 7) { - throw new ArgumentException("ustar deviceMajorNumber cannot be longer than 7 characters.", "deviceMajorNumber"); + throw new ArgumentException("ustar deviceMajorNumber cannot be longer than 7 characters.", nameof(deviceMajorNumber)); } if (deviceMinorNumber.Length > 7) { - throw new ArgumentException("ustar deviceMinorNumber cannot be longer than 7 characters.", "deviceMinorNumber"); + throw new ArgumentException("ustar deviceMinorNumber cannot be longer than 7 characters.", nameof(deviceMinorNumber)); } if (link.Length > 100) { - throw new ArgumentException("ustar link cannot be longer than 100 characters.", "link"); + throw new ArgumentException("ustar link cannot be longer than 100 characters.", nameof(link)); } #endregion diff --git a/LibGit2Sharp/Core/Utf8Marshaler.cs b/LibGit2Sharp/Core/Utf8Marshaler.cs index a6fddb808..54e0086cb 100644 --- a/LibGit2Sharp/Core/Utf8Marshaler.cs +++ b/LibGit2Sharp/Core/Utf8Marshaler.cs @@ -67,7 +67,7 @@ public static ICustomMarshaler GetInstance(string cookie) #region ICustomMarshaler - public override Object MarshalNativeToManaged(IntPtr pNativeData) + public override object MarshalNativeToManaged(IntPtr pNativeData) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "{0} cannot be used to retrieve data from libgit2.", @@ -76,7 +76,7 @@ public override Object MarshalNativeToManaged(IntPtr pNativeData) #endregion - public static IntPtr FromManaged(String value) + public static IntPtr FromManaged(string value) { return FromManaged(encoding, value); } diff --git a/LibGit2Sharp/Diff.cs b/LibGit2Sharp/Diff.cs index 087ee8d6d..857eb8ed1 100644 --- a/LibGit2Sharp/Diff.cs +++ b/LibGit2Sharp/Diff.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; using System.Text; using LibGit2Sharp.Core; @@ -546,7 +545,7 @@ private DiffHandle BuildDiffList( MatchedPathsAggregator matchedPaths = null; - // We can't match paths unless we've got something to match + // We can't match paths unless we've got something to match // against and we're told to do so. if (filePaths != null && explicitPathsOptions != null) { @@ -653,7 +652,7 @@ private static void DispatchUnmatchedPaths( List unmatchedPaths = (filePaths != null ? filePaths.Except(matchedPaths) : Enumerable.Empty()).ToList(); - if (!unmatchedPaths.Any()) + if (unmatchedPaths.Count == 0) { return; } diff --git a/LibGit2Sharp/DiffTargets.cs b/LibGit2Sharp/DiffTargets.cs index 58e3f2f4d..40203ee60 100644 --- a/LibGit2Sharp/DiffTargets.cs +++ b/LibGit2Sharp/DiffTargets.cs @@ -18,4 +18,4 @@ public enum DiffTargets /// WorkingDirectory = 2, } -} \ No newline at end of file +} diff --git a/LibGit2Sharp/EmptyCommitException.cs b/LibGit2Sharp/EmptyCommitException.cs index 8cd48e49f..00d1081e5 100644 --- a/LibGit2Sharp/EmptyCommitException.cs +++ b/LibGit2Sharp/EmptyCommitException.cs @@ -1,5 +1,7 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif namespace LibGit2Sharp { @@ -7,7 +9,9 @@ namespace LibGit2Sharp /// The exception that is thrown when a commit would create an "empty" /// commit that is treesame to its parent without an explicit override. /// +#if NETFRAMEWORK [Serializable] +#endif public class EmptyCommitException : LibGit2SharpException { /// @@ -27,7 +31,7 @@ public EmptyCommitException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public EmptyCommitException(string format, params object[] args) : base(format, args) @@ -42,6 +46,7 @@ public EmptyCommitException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -50,5 +55,6 @@ public EmptyCommitException(string message, Exception innerException) protected EmptyCommitException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif } } diff --git a/LibGit2Sharp/EntryExistsException.cs b/LibGit2Sharp/EntryExistsException.cs index 2c46e4acd..3ebfbdfba 100644 --- a/LibGit2Sharp/EntryExistsException.cs +++ b/LibGit2Sharp/EntryExistsException.cs @@ -1,5 +1,8 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif + using LibGit2Sharp.Core; namespace LibGit2Sharp @@ -7,7 +10,9 @@ namespace LibGit2Sharp /// /// The exception that is thrown attempting to create a resource that already exists. /// +#if NETFRAMEWORK [Serializable] +#endif public class EntryExistsException : LibGit2SharpException { /// @@ -27,7 +32,7 @@ public EntryExistsException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public EntryExistsException(string format, params object[] args) : base(format, args) @@ -42,6 +47,7 @@ public EntryExistsException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -50,6 +56,7 @@ public EntryExistsException(string message, Exception innerException) protected EntryExistsException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif internal EntryExistsException(string message, GitErrorCode code, GitErrorCategory category) : base(message, code, category) diff --git a/LibGit2Sharp/FetchHead.cs b/LibGit2Sharp/FetchHead.cs index 456abedc2..812865cf3 100644 --- a/LibGit2Sharp/FetchHead.cs +++ b/LibGit2Sharp/FetchHead.cs @@ -61,7 +61,7 @@ public virtual GitObject Target /// The URL of the remote repository this /// has been built from. /// - public virtual String Url { get; private set; } + public virtual string Url { get; private set; } /// /// Determines if this fetch head entry has been explicitly fetched. diff --git a/LibGit2Sharp/FetchOptions.cs b/LibGit2Sharp/FetchOptions.cs index 487baed97..6f354a5d5 100644 --- a/LibGit2Sharp/FetchOptions.cs +++ b/LibGit2Sharp/FetchOptions.cs @@ -26,16 +26,24 @@ public sealed class FetchOptions : FetchOptionsBase /// public bool? Prune { get; set; } + /// + /// Specifies the depth of the fetch to perform. + /// + /// Default value is 0 (full fetch). + /// + /// + public int Depth { get; set; } = 0; + /// /// Get/Set the custom headers. - /// - /// - /// This allows you to set custom headers (e.g. X-Forwarded-For, + /// + /// + /// This allows you to set custom headers (e.g. X-Forwarded-For, /// X-Request-Id, etc), /// /// /// - /// Libgit2 sets some headers for HTTP requests (User-Agent, Host, + /// Libgit2 sets some headers for HTTP requests (User-Agent, Host, /// Accept, Content-Type, Transfer-Encoding, Content-Length, Accept) that /// cannot be overriden. /// diff --git a/LibGit2Sharp/FetchOptionsBase.cs b/LibGit2Sharp/FetchOptionsBase.cs index 751678cf9..0e548652f 100644 --- a/LibGit2Sharp/FetchOptionsBase.cs +++ b/LibGit2Sharp/FetchOptionsBase.cs @@ -35,7 +35,7 @@ internal FetchOptionsBase() /// /// This handler will be called to let the user make a decision on whether to allow - /// the connection to preoceed based on the certificate presented by the server. + /// the connection to proceed based on the certificate presented by the server. /// public CertificateCheckHandler CertificateCheck { get; set; } @@ -48,5 +48,10 @@ internal FetchOptionsBase() /// Completed operating on the current repository. /// public RepositoryOperationCompleted RepositoryOperationCompleted { get; set; } + + /// + /// Options for connecting through a proxy. + /// + public ProxyOptions ProxyOptions { get; } = new(); } } diff --git a/LibGit2Sharp/Filter.cs b/LibGit2Sharp/Filter.cs index 5a46e12b5..0ab999f19 100644 --- a/LibGit2Sharp/Filter.cs +++ b/LibGit2Sharp/Filter.cs @@ -165,10 +165,10 @@ protected virtual void Smudge(string path, string root, Stream input, Stream out } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as Filter); @@ -304,9 +304,9 @@ int StreamCloseCallback(IntPtr stream) { Ensure.ArgumentNotZeroIntPtr(stream, "stream"); - if(!activeStreams.TryGetValue(stream, out state)) + if (!activeStreams.TryGetValue(stream, out state)) { - throw new ArgumentException("Unknown stream pointer", "stream"); + throw new ArgumentException("Unknown stream pointer", nameof(stream)); } Ensure.ArgumentIsExpectedIntPtr(stream, state.thisPtr, "stream"); @@ -339,7 +339,7 @@ void StreamFreeCallback(IntPtr stream) if (!activeStreams.TryRemove(stream, out state)) { - throw new ArgumentException("Double free or invalid stream pointer", "stream"); + throw new ArgumentException("Double free or invalid stream pointer", nameof(stream)); } Ensure.ArgumentIsExpectedIntPtr(stream, state.thisPtr, "stream"); @@ -365,7 +365,7 @@ unsafe int StreamWriteCallback(IntPtr stream, IntPtr buffer, UIntPtr len) if (!activeStreams.TryGetValue(stream, out state)) { - throw new ArgumentException("Invalid or already freed stream pointer", "stream"); + throw new ArgumentException("Invalid or already freed stream pointer", nameof(stream)); } Ensure.ArgumentIsExpectedIntPtr(stream, state.thisPtr, "stream"); diff --git a/LibGit2Sharp/FilterSource.cs b/LibGit2Sharp/FilterSource.cs index ed551aba8..ab1dcb35c 100644 --- a/LibGit2Sharp/FilterSource.cs +++ b/LibGit2Sharp/FilterSource.cs @@ -28,7 +28,7 @@ internal unsafe FilterSource(FilePath path, FilterMode mode, git_filter_source* /// internal static unsafe FilterSource FromNativePtr(IntPtr ptr) { - return FromNativePtr((git_filter_source*) ptr.ToPointer()); + return FromNativePtr((git_filter_source*)ptr.ToPointer()); } /// diff --git a/LibGit2Sharp/GitObject.cs b/LibGit2Sharp/GitObject.cs index 539fe6f8b..f9813a3ea 100644 --- a/LibGit2Sharp/GitObject.cs +++ b/LibGit2Sharp/GitObject.cs @@ -129,10 +129,10 @@ public virtual T Peel() where T : GitObject } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as GitObject); @@ -180,7 +180,7 @@ public override int GetHashCode() } /// - /// Returns the , a representation of the current . + /// Returns the , a representation of the current . /// /// The that represents the current . public override string ToString() diff --git a/LibGit2Sharp/GlobalSettings.cs b/LibGit2Sharp/GlobalSettings.cs index 31cba0965..9807155e7 100644 --- a/LibGit2Sharp/GlobalSettings.cs +++ b/LibGit2Sharp/GlobalSettings.cs @@ -247,9 +247,9 @@ public static FilterRegistration RegisterFilter(Filter filter, int priority) Ensure.ArgumentNotNull(filter, "filter"); if (priority < FilterRegistration.FilterPriorityMin || priority > FilterRegistration.FilterPriorityMax) { - throw new ArgumentOutOfRangeException("priority", + throw new ArgumentOutOfRangeException(nameof(priority), priority, - String.Format(System.Globalization.CultureInfo.InvariantCulture, + string.Format(System.Globalization.CultureInfo.InvariantCulture, "Filter priorities must be within the inclusive range of [{0}, {1}].", FilterRegistration.FilterPriorityMin, FilterRegistration.FilterPriorityMax)); @@ -417,5 +417,26 @@ public static string GetUserAgent() { return Proxy.git_libgit2_opts_get_user_agent(); } + + /// + /// Gets the owner validation setting for repository directories. + /// + /// + public static bool GetOwnerValidation() + { + return Proxy.git_libgit2_opts_get_owner_validation(); + } + + /// + /// Sets whether repository directories should be owned by the current user. The default is to validate ownership. + /// + /// + /// Disabling owner validation can lead to security vulnerabilities (see CVE-2022-24765). + /// + /// true to enable owner validation; otherwise, false. + public static void SetOwnerValidation(bool enabled) + { + Proxy.git_libgit2_opts_set_owner_validation(enabled); + } } } diff --git a/LibGit2Sharp/IDiffResult.cs b/LibGit2Sharp/IDiffResult.cs index ed6e521fd..5090de88e 100644 --- a/LibGit2Sharp/IDiffResult.cs +++ b/LibGit2Sharp/IDiffResult.cs @@ -5,6 +5,6 @@ namespace LibGit2Sharp /// /// Marker interface to identify Diff results. /// - public interface IDiffResult: IDisposable + public interface IDiffResult : IDisposable { } } diff --git a/LibGit2Sharp/Index.cs b/LibGit2Sharp/Index.cs index 46d756e04..321673606 100644 --- a/LibGit2Sharp/Index.cs +++ b/LibGit2Sharp/Index.cs @@ -247,7 +247,7 @@ private unsafe void AddEntryToTheIndex(string path, ObjectId id, Mode mode) var indexEntry = new git_index_entry { mode = (uint)mode, - path = (char*) pathPtr, + path = (char*)pathPtr, }; Marshal.Copy(id.RawId, 0, new IntPtr(indexEntry.id.Id), GitOid.Size); diff --git a/LibGit2Sharp/IndexEntry.cs b/LibGit2Sharp/IndexEntry.cs index e07e284b7..554d9a9f1 100644 --- a/LibGit2Sharp/IndexEntry.cs +++ b/LibGit2Sharp/IndexEntry.cs @@ -60,10 +60,10 @@ internal static unsafe IndexEntry BuildFromPtr(git_index_entry* entry) } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as IndexEntry); diff --git a/LibGit2Sharp/IndexNameEntry.cs b/LibGit2Sharp/IndexNameEntry.cs index 79b3f6993..40c202acc 100644 --- a/LibGit2Sharp/IndexNameEntry.cs +++ b/LibGit2Sharp/IndexNameEntry.cs @@ -63,10 +63,10 @@ internal static unsafe IndexNameEntry BuildFromPtr(git_index_name_entry* entry) public virtual string Theirs { get; private set; } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as IndexNameEntry); diff --git a/LibGit2Sharp/IndexReucEntry.cs b/LibGit2Sharp/IndexReucEntry.cs index 583df95ba..becd20122 100644 --- a/LibGit2Sharp/IndexReucEntry.cs +++ b/LibGit2Sharp/IndexReucEntry.cs @@ -88,10 +88,10 @@ internal static unsafe IndexReucEntry BuildFromPtr(git_index_reuc_entry* entry) public virtual Mode TheirMode { get; private set; } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as IndexReucEntry); diff --git a/LibGit2Sharp/IndexReucEntryCollection.cs b/LibGit2Sharp/IndexReucEntryCollection.cs index 61af48b18..818bce70c 100644 --- a/LibGit2Sharp/IndexReucEntryCollection.cs +++ b/LibGit2Sharp/IndexReucEntryCollection.cs @@ -40,7 +40,7 @@ public virtual unsafe IndexReucEntry this[string path] } } - private unsafe IndexReucEntry this[int idx] + private unsafe IndexReucEntry this[int idx] { get { diff --git a/LibGit2Sharp/InvalidSpecificationException.cs b/LibGit2Sharp/InvalidSpecificationException.cs index 3d34571a4..d9625dc32 100644 --- a/LibGit2Sharp/InvalidSpecificationException.cs +++ b/LibGit2Sharp/InvalidSpecificationException.cs @@ -1,5 +1,7 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif using LibGit2Sharp.Core; namespace LibGit2Sharp @@ -10,7 +12,9 @@ namespace LibGit2Sharp /// if the spec refers to an object of an incorrect type (e.g. asking to /// create a branch from a blob, or peeling a blob to a commit). /// +#if NETFRAMEWORK [Serializable] +#endif public class InvalidSpecificationException : NativeException { /// @@ -30,7 +34,7 @@ public InvalidSpecificationException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public InvalidSpecificationException(string format, params object[] args) : base(format, args) @@ -45,6 +49,7 @@ public InvalidSpecificationException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -53,6 +58,7 @@ public InvalidSpecificationException(string message, Exception innerException) protected InvalidSpecificationException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif internal InvalidSpecificationException(string message, GitErrorCategory category) : base(message, category) diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index 6aa70519c..1c4abef7b 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -1,7 +1,8 @@  - net472;net6.0 + net472;net8.0 + 12.0 true LibGit2Sharp brings all the might and speed of libgit2, a native Git implementation, to the managed world of .NET LibGit2Sharp contributors @@ -15,12 +16,23 @@ true ..\libgit2sharp.snk square-logo.png + App_Readme/README.md App_Readme/LICENSE.md true + $(ArtifactsPath)\package preview.0 libgit2-$(libgit2_hash.Substring(0,7)) + + true + + + + + + + @@ -31,12 +43,6 @@ - - - - - - @@ -46,4 +52,10 @@ + + + $(MinVerMajor).$(MinVerMinor).0.0 + + + diff --git a/LibGit2Sharp/LibGit2SharpException.cs b/LibGit2Sharp/LibGit2SharpException.cs index 5d1c33f25..0518fa757 100644 --- a/LibGit2Sharp/LibGit2SharpException.cs +++ b/LibGit2Sharp/LibGit2SharpException.cs @@ -1,14 +1,17 @@ using System; using System.Globalization; +#if NETFRAMEWORK using System.Runtime.Serialization; -using LibGit2Sharp.Core; +#endif namespace LibGit2Sharp { /// /// The exception that is thrown when an error occurs during application execution. /// +#if NETFRAMEWORK [Serializable] +#endif public class LibGit2SharpException : Exception { /// @@ -37,13 +40,14 @@ public LibGit2SharpException(string message, Exception innerException) /// /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public LibGit2SharpException(string format, params object[] args) - : base(String.Format(CultureInfo.InvariantCulture, format, args)) + : base(string.Format(CultureInfo.InvariantCulture, format, args)) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -52,5 +56,6 @@ public LibGit2SharpException(string format, params object[] args) protected LibGit2SharpException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif } } diff --git a/LibGit2Sharp/LockedFileException.cs b/LibGit2Sharp/LockedFileException.cs index 44fd65b02..b38f40496 100644 --- a/LibGit2Sharp/LockedFileException.cs +++ b/LibGit2Sharp/LockedFileException.cs @@ -1,5 +1,7 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif using LibGit2Sharp.Core; namespace LibGit2Sharp @@ -7,7 +9,9 @@ namespace LibGit2Sharp /// /// The exception that is thrown attempting to open a locked file. /// +#if NETFRAMEWORK [Serializable] +#endif public class LockedFileException : NativeException { /// @@ -27,7 +31,7 @@ public LockedFileException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public LockedFileException(string format, params object[] args) : base(format, args) @@ -42,6 +46,7 @@ public LockedFileException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -50,6 +55,7 @@ public LockedFileException(string message, Exception innerException) protected LockedFileException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif internal LockedFileException(string message, GitErrorCategory category) : base(message, category) diff --git a/LibGit2Sharp/MergeFetchHeadNotFoundException.cs b/LibGit2Sharp/MergeFetchHeadNotFoundException.cs index a86bf5caf..d7d761c1d 100644 --- a/LibGit2Sharp/MergeFetchHeadNotFoundException.cs +++ b/LibGit2Sharp/MergeFetchHeadNotFoundException.cs @@ -1,12 +1,16 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif namespace LibGit2Sharp { /// /// The exception that is thrown when the ref to merge with was as part of a pull operation not fetched. /// +#if NETFRAMEWORK [Serializable] +#endif public class MergeFetchHeadNotFoundException : NotFoundException { /// @@ -26,7 +30,7 @@ public MergeFetchHeadNotFoundException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public MergeFetchHeadNotFoundException(string format, params object[] args) : base(format, args) @@ -41,6 +45,7 @@ public MergeFetchHeadNotFoundException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -49,5 +54,6 @@ public MergeFetchHeadNotFoundException(string message, Exception innerException) protected MergeFetchHeadNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif } } diff --git a/LibGit2Sharp/NameConflictException.cs b/LibGit2Sharp/NameConflictException.cs index 0dcffc648..0517f2550 100644 --- a/LibGit2Sharp/NameConflictException.cs +++ b/LibGit2Sharp/NameConflictException.cs @@ -1,5 +1,7 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif using LibGit2Sharp.Core; namespace LibGit2Sharp @@ -7,7 +9,9 @@ namespace LibGit2Sharp /// /// The exception that is thrown when a reference, a remote, a submodule... with the same name already exists in the repository /// +#if NETFRAMEWORK [Serializable] +#endif public class NameConflictException : NativeException { /// @@ -27,7 +31,7 @@ public NameConflictException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public NameConflictException(string format, params object[] args) : base(format, args) @@ -42,6 +46,7 @@ public NameConflictException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -50,6 +55,7 @@ public NameConflictException(string message, Exception innerException) protected NameConflictException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif internal NameConflictException(string message, GitErrorCategory category) : base(message, category) diff --git a/LibGit2Sharp/NativeException.cs b/LibGit2Sharp/NativeException.cs index 292372db7..66dc03c57 100644 --- a/LibGit2Sharp/NativeException.cs +++ b/LibGit2Sharp/NativeException.cs @@ -1,16 +1,17 @@ -using LibGit2Sharp.Core; -using System; -using System.Collections.Generic; -using System.Globalization; +using System; +#if NETFRAMEWORK using System.Runtime.Serialization; -using System.Text; +#endif +using LibGit2Sharp.Core; namespace LibGit2Sharp { /// /// An exception thrown that corresponds to a libgit2 (native library) error. /// +#if NETFRAMEWORK [Serializable] +#endif public abstract class NativeException : LibGit2SharpException { /// @@ -32,9 +33,11 @@ internal NativeException(string format, params object[] args) { } +#if NETFRAMEWORK internal NativeException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif internal NativeException(string message, GitErrorCategory category) : this(message) { diff --git a/LibGit2Sharp/Network.cs b/LibGit2Sharp/Network.cs index d5f032058..ba0a33144 100644 --- a/LibGit2Sharp/Network.cs +++ b/LibGit2Sharp/Network.cs @@ -52,7 +52,26 @@ public virtual IEnumerable ListReferences(Remote remote) { Ensure.ArgumentNotNull(remote, "remote"); - return ListReferencesInternal(remote.Url, null); + return ListReferencesInternal(remote.Url, null, new ProxyOptions()); + } + + /// + /// List references in a repository. + /// + /// When the remote tips are ahead of the local ones, the retrieved + /// s may point to non existing + /// s in the local repository. In that + /// case, will return null. + /// + /// + /// The to list from. + /// Options for connecting through a proxy. + /// The references in the repository. + public virtual IEnumerable ListReferences(Remote remote, ProxyOptions proxyOptions) + { + Ensure.ArgumentNotNull(remote, "remote"); + + return ListReferencesInternal(remote.Url, null, proxyOptions); } /// @@ -72,7 +91,28 @@ public virtual IEnumerable ListReferences(Remote remote, CredentialsH Ensure.ArgumentNotNull(remote, "remote"); Ensure.ArgumentNotNull(credentialsProvider, "credentialsProvider"); - return ListReferencesInternal(remote.Url, credentialsProvider); + return ListReferencesInternal(remote.Url, credentialsProvider, new ProxyOptions()); + } + + /// + /// List references in a repository. + /// + /// When the remote tips are ahead of the local ones, the retrieved + /// s may point to non existing + /// s in the local repository. In that + /// case, will return null. + /// + /// + /// The to list from. + /// The used to connect to remote repository. + /// Options for connecting through a proxy. + /// The references in the repository. + public virtual IEnumerable ListReferences(Remote remote, CredentialsHandler credentialsProvider, ProxyOptions proxyOptions) + { + Ensure.ArgumentNotNull(remote, "remote"); + Ensure.ArgumentNotNull(credentialsProvider, "credentialsProvider"); + + return ListReferencesInternal(remote.Url, credentialsProvider, proxyOptions); } /// @@ -90,7 +130,26 @@ public virtual IEnumerable ListReferences(string url) { Ensure.ArgumentNotNull(url, "url"); - return ListReferencesInternal(url, null); + return ListReferencesInternal(url, null, new ProxyOptions()); + } + + /// + /// List references in a remote repository. + /// + /// When the remote tips are ahead of the local ones, the retrieved + /// s may point to non existing + /// s in the local repository. In that + /// case, will return null. + /// + /// + /// The url to list from. + /// Options for connecting through a proxy. + /// The references in the remote repository. + public virtual IEnumerable ListReferences(string url, ProxyOptions proxyOptions) + { + Ensure.ArgumentNotNull(url, "url"); + + return ListReferencesInternal(url, null, proxyOptions); } /// @@ -110,34 +169,58 @@ public virtual IEnumerable ListReferences(string url, CredentialsHand Ensure.ArgumentNotNull(url, "url"); Ensure.ArgumentNotNull(credentialsProvider, "credentialsProvider"); - return ListReferencesInternal(url, credentialsProvider); + return ListReferencesInternal(url, credentialsProvider, new ProxyOptions()); + } + + /// + /// List references in a remote repository. + /// + /// When the remote tips are ahead of the local ones, the retrieved + /// s may point to non existing + /// s in the local repository. In that + /// case, will return null. + /// + /// + /// The url to list from. + /// The used to connect to remote repository. + /// Options for connecting through a proxy. + /// The references in the remote repository. + public virtual IEnumerable ListReferences(string url, CredentialsHandler credentialsProvider, ProxyOptions proxyOptions) + { + Ensure.ArgumentNotNull(url, "url"); + Ensure.ArgumentNotNull(credentialsProvider, "credentialsProvider"); + + return ListReferencesInternal(url, credentialsProvider, new ProxyOptions()); } - private IEnumerable ListReferencesInternal(string url, CredentialsHandler credentialsProvider) + private IEnumerable ListReferencesInternal(string url, CredentialsHandler credentialsProvider, ProxyOptions proxyOptions) { - using (RemoteHandle remoteHandle = BuildRemoteHandle(repository.Handle, url)) - { - GitRemoteCallbacks gitCallbacks = new GitRemoteCallbacks { version = 1 }; - GitProxyOptions proxyOptions = new GitProxyOptions { Version = 1 }; + proxyOptions ??= new(); - if (credentialsProvider != null) - { - var callbacks = new RemoteCallbacks(credentialsProvider); - gitCallbacks = callbacks.GenerateCallbacks(); - } + using RemoteHandle remoteHandle = BuildRemoteHandle(repository.Handle, url); + using var proxyOptionsWrapper = new GitProxyOptionsWrapper(proxyOptions.CreateGitProxyOptions()); + + GitRemoteCallbacks gitCallbacks = new GitRemoteCallbacks { version = 1 }; - Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch, ref gitCallbacks, ref proxyOptions); - return Proxy.git_remote_ls(repository, remoteHandle); + if (credentialsProvider != null) + { + var callbacks = new RemoteCallbacks(credentialsProvider); + gitCallbacks = callbacks.GenerateCallbacks(); } + + var gitProxyOptions = proxyOptionsWrapper.Options; + + Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch, ref gitCallbacks, ref gitProxyOptions); + return Proxy.git_remote_ls(repository, remoteHandle); } static RemoteHandle BuildRemoteHandle(RepositoryHandle repoHandle, string url) { - Debug.Assert(repoHandle != null && !repoHandle.IsNull); + Debug.Assert(repoHandle != null && !repoHandle.IsInvalid); Debug.Assert(url != null); RemoteHandle remoteHandle = Proxy.git_remote_create_anonymous(repoHandle, url); - Debug.Assert(remoteHandle != null && !(remoteHandle.IsNull)); + Debug.Assert(remoteHandle != null && !remoteHandle.IsInvalid); return remoteHandle; } @@ -365,18 +448,27 @@ public virtual void Push(Remote remote, IEnumerable pushRefSpecs, PushOp // Load the remote. using (RemoteHandle remoteHandle = Proxy.git_remote_lookup(repository.Handle, remote.Name, true)) + + // Create a git options wrapper so managed strings are disposed. + using (var pushOptionsWrapper = new GitPushOptionsWrapper()) { var callbacks = new RemoteCallbacks(pushOptions); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); + var gitPushOptions = pushOptionsWrapper.Options; + gitPushOptions.PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism; + gitPushOptions.RemoteCallbacks = gitCallbacks; + gitPushOptions.ProxyOptions = pushOptions.ProxyOptions.CreateGitProxyOptions(); + + // If there are custom headers, create a managed string array. + if (pushOptions.CustomHeaders != null && pushOptions.CustomHeaders.Length > 0) + { + gitPushOptions.CustomHeaders = GitStrArrayManaged.BuildFrom(pushOptions.CustomHeaders); + } + Proxy.git_remote_push(remoteHandle, pushRefSpecs, - new GitPushOptions() - { - PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism, - RemoteCallbacks = gitCallbacks, - ProxyOptions = new GitProxyOptions { Version = 1 }, - }); + gitPushOptions); } } diff --git a/LibGit2Sharp/NonFastForwardException.cs b/LibGit2Sharp/NonFastForwardException.cs index b5a858f47..d8ed8f474 100644 --- a/LibGit2Sharp/NonFastForwardException.cs +++ b/LibGit2Sharp/NonFastForwardException.cs @@ -1,5 +1,7 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif using LibGit2Sharp.Core; namespace LibGit2Sharp @@ -8,7 +10,9 @@ namespace LibGit2Sharp /// The exception that is thrown when push cannot be performed /// against the remote without losing commits. /// +#if NETFRAMEWORK [Serializable] +#endif public class NonFastForwardException : NativeException { /// @@ -28,7 +32,7 @@ public NonFastForwardException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public NonFastForwardException(string format, params object[] args) : base(format, args) @@ -43,6 +47,7 @@ public NonFastForwardException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -51,6 +56,7 @@ public NonFastForwardException(string message, Exception innerException) protected NonFastForwardException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif internal NonFastForwardException(string message, GitErrorCategory category) : base(message, category) diff --git a/LibGit2Sharp/NotFoundException.cs b/LibGit2Sharp/NotFoundException.cs index f8c49cc91..f282c4340 100644 --- a/LibGit2Sharp/NotFoundException.cs +++ b/LibGit2Sharp/NotFoundException.cs @@ -1,5 +1,7 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif using LibGit2Sharp.Core; namespace LibGit2Sharp @@ -7,7 +9,9 @@ namespace LibGit2Sharp /// /// The exception that is thrown attempting to reference a resource that does not exist. /// +#if NETFRAMEWORK [Serializable] +#endif public class NotFoundException : NativeException { /// @@ -27,7 +31,7 @@ public NotFoundException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public NotFoundException(string format, params object[] args) : base(format, args) @@ -42,6 +46,7 @@ public NotFoundException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -50,6 +55,7 @@ public NotFoundException(string message, Exception innerException) protected NotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif internal NotFoundException(string message, GitErrorCategory category) : base(message, category) diff --git a/LibGit2Sharp/Note.cs b/LibGit2Sharp/Note.cs index 1df0125e4..2ffc89690 100644 --- a/LibGit2Sharp/Note.cs +++ b/LibGit2Sharp/Note.cs @@ -59,10 +59,10 @@ internal static Note BuildFromPtr(NoteHandle note, string @namespace, ObjectId t } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as Note); diff --git a/LibGit2Sharp/ObjectDatabase.cs b/LibGit2Sharp/ObjectDatabase.cs index b48c72a99..1bad9c907 100644 --- a/LibGit2Sharp/ObjectDatabase.cs +++ b/LibGit2Sharp/ObjectDatabase.cs @@ -199,10 +199,10 @@ public virtual ObjectId Write(Stream stream, long numberOfBytesToConsume) whe if (!stream.CanRead) { - throw new ArgumentException("The stream cannot be read from.", "stream"); + throw new ArgumentException("The stream cannot be read from.", nameof(stream)); } - using (var odbStream = Proxy.git_odb_open_wstream(handle, numberOfBytesToConsume, GitObjectType.Blob)) + using (var odbStream = Proxy.git_odb_open_wstream(handle, numberOfBytesToConsume, GitObject.TypeToGitKindMap[typeof(T)])) { var buffer = new byte[4 * 1024]; long totalRead = 0; @@ -274,7 +274,7 @@ private unsafe Blob CreateBlob(Stream stream, string hintpath, long? numberOfByt if (!stream.CanRead) { - throw new ArgumentException("The stream cannot be read from.", "stream"); + throw new ArgumentException("The stream cannot be read from.", nameof(stream)); } IntPtr writestream_ptr = Proxy.git_blob_create_from_stream(repo.Handle, hintpath); @@ -588,7 +588,7 @@ public virtual MergeTreeResult CherryPickCommit(Commit cherryPickCommit, Commit // Stopped due to FailOnConflict so there's no index or conflict list if (earlyStop) { - return new MergeTreeResult(new Conflict[] { }); + return new MergeTreeResult(Array.Empty()); } if (Proxy.git_index_has_conflicts(indexHandle)) @@ -639,7 +639,7 @@ public virtual string ShortenObjectId(GitObject gitObject, int minLength) if (minLength <= 0 || minLength > ObjectId.HexSize) { - throw new ArgumentOutOfRangeException("minLength", + throw new ArgumentOutOfRangeException(nameof(minLength), minLength, string.Format("Expected value should be greater than zero and less than or equal to {0}.", ObjectId.HexSize)); @@ -714,7 +714,7 @@ public virtual Commit FindMergeBase(IEnumerable commits, MergeBaseFindin { if (commit == null) { - throw new ArgumentException("Enumerable contains null at position: " + count.ToString(CultureInfo.InvariantCulture), "commits"); + throw new ArgumentException("Enumerable contains null at position: " + count.ToString(CultureInfo.InvariantCulture), nameof(commits)); } ids.Add(commit.Id.Oid); count++; @@ -722,7 +722,7 @@ public virtual Commit FindMergeBase(IEnumerable commits, MergeBaseFindin if (count < 2) { - throw new ArgumentException("The enumerable must contains at least two commits.", "commits"); + throw new ArgumentException("The enumerable must contains at least two commits.", nameof(commits)); } switch (strategy) @@ -736,7 +736,7 @@ public virtual Commit FindMergeBase(IEnumerable commits, MergeBaseFindin break; default: - throw new ArgumentException("", "strategy"); + throw new ArgumentException("", nameof(strategy)); } return id == null ? null : repo.Lookup(id); @@ -780,7 +780,7 @@ public virtual MergeTreeResult MergeCommits(Commit ours, Commit theirs, MergeTre // Stopped due to FailOnConflict so there's no index or conflict list if (earlyStop) { - return new MergeTreeResult(new Conflict[] { }); + return new MergeTreeResult(Array.Empty()); } if (Proxy.git_index_has_conflicts(indexHandle)) @@ -1063,7 +1063,7 @@ public virtual MergeTreeResult RevertCommit(Commit revertCommit, Commit revertOn // Stopped due to FailOnConflict so there's no index or conflict list if (earlyStop) { - return new MergeTreeResult(new Conflict[] { }); + return new MergeTreeResult(Array.Empty()); } if (Proxy.git_index_has_conflicts(indexHandle)) diff --git a/LibGit2Sharp/ObjectId.cs b/LibGit2Sharp/ObjectId.cs index 9d754781c..d87bbcb34 100644 --- a/LibGit2Sharp/ObjectId.cs +++ b/LibGit2Sharp/ObjectId.cs @@ -39,7 +39,7 @@ internal ObjectId(GitOid oid) { if (oid.Id == null || oid.Id.Length != rawSize) { - throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "A non null array of {0} bytes is expected.", rawSize), "oid"); + throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "A non null array of {0} bytes is expected.", rawSize), nameof(oid)); } this.oid = oid; @@ -59,7 +59,7 @@ public ObjectId(byte[] rawId) internal static unsafe ObjectId BuildFromPtr(IntPtr ptr) { - return BuildFromPtr((git_oid*) ptr.ToPointer()); + return BuildFromPtr((git_oid*)ptr.ToPointer()); } internal static unsafe ObjectId BuildFromPtr(git_oid* id) @@ -71,7 +71,7 @@ internal unsafe ObjectId(byte* rawId) { byte[] id = new byte[GitOid.Size]; - fixed(byte* p = id) + fixed (byte* p = id) { for (int i = 0; i < rawSize; i++) { @@ -145,10 +145,10 @@ public static bool TryParse(string sha, out ObjectId result) } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as ObjectId); @@ -174,7 +174,7 @@ public override int GetHashCode() } /// - /// Returns the , a representation of the current . + /// Returns the , a representation of the current . /// /// The that represents the current . public override string ToString() @@ -183,7 +183,7 @@ public override string ToString() } /// - /// Returns the , a representation of the current . + /// Returns the , a representation of the current . /// /// The number of chars the should be truncated to. /// The that represents the current . @@ -327,7 +327,7 @@ private static bool LooksValid(string objectId, bool throwIfInvalid) "'{0}' is not a valid object identifier. Its length should be {1}.", objectId, HexSize), - "objectId"); + nameof(objectId)); } return objectId.All(c => hexDigits.IndexOf(c) >= 0); diff --git a/LibGit2Sharp/OdbBackend.cs b/LibGit2Sharp/OdbBackend.cs index 9736ed803..645d0ac5f 100644 --- a/LibGit2Sharp/OdbBackend.cs +++ b/LibGit2Sharp/OdbBackend.cs @@ -63,7 +63,7 @@ protected unsafe UnmanagedMemoryStream Allocate(long size) { if (size < 0 || (UIntPtr.Size == sizeof(int) && size > int.MaxValue)) { - throw new ArgumentOutOfRangeException("size"); + throw new ArgumentOutOfRangeException(nameof(size)); } IntPtr buffer = Proxy.git_odb_backend_malloc(this.GitOdbBackendPointer, new UIntPtr((ulong)size)); diff --git a/LibGit2Sharp/PackBuilder.cs b/LibGit2Sharp/PackBuilder.cs index dcaa2617a..2ede4ab7b 100644 --- a/LibGit2Sharp/PackBuilder.cs +++ b/LibGit2Sharp/PackBuilder.cs @@ -189,7 +189,7 @@ public int MaximumNumberOfThreads { if (value < 0) { - throw new ArgumentException("Argument can not be negative", "value"); + throw new ArgumentException("Argument can not be negative", nameof(value)); } nThreads = value; diff --git a/LibGit2Sharp/PeelException.cs b/LibGit2Sharp/PeelException.cs index d7758d7c9..b5a3d628b 100644 --- a/LibGit2Sharp/PeelException.cs +++ b/LibGit2Sharp/PeelException.cs @@ -1,5 +1,7 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif using LibGit2Sharp.Core; namespace LibGit2Sharp @@ -8,7 +10,9 @@ namespace LibGit2Sharp /// The exception that is thrown when a tag cannot be peeled to the /// target type due to the object model. /// +#if NETFRAMEWORK [Serializable] +#endif public class PeelException : NativeException { /// @@ -28,7 +32,7 @@ public PeelException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public PeelException(string format, params object[] args) : base(format, args) @@ -43,6 +47,7 @@ public PeelException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -51,6 +56,7 @@ public PeelException(string message, Exception innerException) protected PeelException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif internal PeelException(string message, GitErrorCategory category) : base(message, category) diff --git a/LibGit2Sharp/ProxyOptions.cs b/LibGit2Sharp/ProxyOptions.cs new file mode 100644 index 000000000..076c4e357 --- /dev/null +++ b/LibGit2Sharp/ProxyOptions.cs @@ -0,0 +1,119 @@ +using System; +using LibGit2Sharp.Core; +using LibGit2Sharp.Handlers; + +namespace LibGit2Sharp +{ + /// + /// Options for connecting through a proxy. + /// + public sealed class ProxyOptions + { + /// + /// The type of proxy to use. Set to Auto by default. + /// + public ProxyType ProxyType { get; set; } = ProxyType.Auto; + + /// + /// The URL of the proxy when is set to Specified. + /// + public string Url { get; set; } + + /// + /// Handler to generate for authentication. + /// + public CredentialsHandler CredentialsProvider { get; set; } + + /// + /// This handler will be called to let the user make a decision on whether to allow + /// the connection to proceed based on the certificate presented by the server. + /// + public CertificateCheckHandler CertificateCheck { get; set; } + + internal unsafe GitProxyOptions CreateGitProxyOptions() + { + var gitProxyOptions = new GitProxyOptions + { + Version = 1, + Type = (GitProxyType)ProxyType + }; + + if (Url is not null) + { + gitProxyOptions.Url = StrictUtf8Marshaler.FromManaged(Url); + } + + if (CredentialsProvider is not null) + { + gitProxyOptions.Credentials = GitCredentialHandler; + } + + if (CertificateCheck is not null) + { + gitProxyOptions.CertificateCheck = GitCertificateCheck; + } + + return gitProxyOptions; + } + + private int GitCredentialHandler(out IntPtr ptr, IntPtr cUrl, IntPtr usernameFromUrl, GitCredentialType credTypes, IntPtr payload) + { + string url = LaxUtf8Marshaler.FromNative(cUrl); + string username = LaxUtf8Marshaler.FromNative(usernameFromUrl); + + SupportedCredentialTypes types = default(SupportedCredentialTypes); + if (credTypes.HasFlag(GitCredentialType.UserPassPlaintext)) + { + types |= SupportedCredentialTypes.UsernamePassword; + } + if (credTypes.HasFlag(GitCredentialType.Default)) + { + types |= SupportedCredentialTypes.Default; + } + + ptr = IntPtr.Zero; + try + { + var cred = CredentialsProvider(url, username, types); + if (cred == null) + { + return (int)GitErrorCode.PassThrough; + } + return cred.GitCredentialHandler(out ptr); + } + catch (Exception exception) + { + Proxy.git_error_set_str(GitErrorCategory.Callback, exception); + return (int)GitErrorCode.Error; + } + } + + private unsafe int GitCertificateCheck(git_certificate* certPtr, int valid, IntPtr cHostname, IntPtr payload) + { + string hostname = LaxUtf8Marshaler.FromNative(cHostname); + Certificate cert = null; + + switch (certPtr->type) + { + case GitCertificateType.X509: + cert = new CertificateX509((git_certificate_x509*)certPtr); + break; + case GitCertificateType.Hostkey: + cert = new CertificateSsh((git_certificate_ssh*)certPtr); + break; + } + + bool result = false; + try + { + result = CertificateCheck(cert, valid != 0, hostname); + } + catch (Exception exception) + { + Proxy.git_error_set_str(GitErrorCategory.Callback, exception); + } + + return Proxy.ConvertResultToCancelFlag(result); + } + } +} diff --git a/LibGit2Sharp/ProxyType.cs b/LibGit2Sharp/ProxyType.cs new file mode 100644 index 000000000..13ec705ee --- /dev/null +++ b/LibGit2Sharp/ProxyType.cs @@ -0,0 +1,23 @@ +namespace LibGit2Sharp +{ + /// + /// The type of proxy to use. + /// + public enum ProxyType + { + /// + /// Do not attempt to connect through a proxy. + /// + None, + + /// + /// Try to auto-detect the proxy from the git configuration. + /// + Auto, + + /// + /// Connect via the URL given in the options. + /// + Specified + } +} diff --git a/LibGit2Sharp/PushOptions.cs b/LibGit2Sharp/PushOptions.cs index 99c65dd8b..829eb0d60 100644 --- a/LibGit2Sharp/PushOptions.cs +++ b/LibGit2Sharp/PushOptions.cs @@ -51,5 +51,30 @@ public sealed class PushOptions /// information about what updates will be performed. /// public PrePushHandler OnNegotiationCompletedBeforePush { get; set; } + + /// + /// Get/Set the custom headers. + /// + /// This allows you to set custom headers (e.g. X-Forwarded-For, + /// X-Request-Id, etc), + /// + /// + /// + /// Libgit2 sets some headers for HTTP requests (User-Agent, Host, + /// Accept, Content-Type, Transfer-Encoding, Content-Length, Accept) that + /// cannot be overriden. + /// + /// + /// var pushOptions - new PushOptions() { + /// CustomHeaders = new String[] {"X-Request-Id: 12345"} + /// }; + /// + /// The custom headers string array + public string[] CustomHeaders { get; set; } + + /// + /// Options for connecting through a proxy. + /// + public ProxyOptions ProxyOptions { get; set; } = new(); } } diff --git a/LibGit2Sharp/PushUpdate.cs b/LibGit2Sharp/PushUpdate.cs index bbabb6817..0aa915dc0 100644 --- a/LibGit2Sharp/PushUpdate.cs +++ b/LibGit2Sharp/PushUpdate.cs @@ -29,9 +29,9 @@ internal unsafe PushUpdate(git_push_update* update) protected PushUpdate() { DestinationObjectId = ObjectId.Zero; - DestinationRefName = String.Empty; + DestinationRefName = string.Empty; SourceObjectId = ObjectId.Zero; - SourceRefName = String.Empty; + SourceRefName = string.Empty; } /// diff --git a/LibGit2Sharp/Rebase.cs b/LibGit2Sharp/Rebase.cs index 00dc3f267..c573ffa65 100644 --- a/LibGit2Sharp/Rebase.cs +++ b/LibGit2Sharp/Rebase.cs @@ -88,7 +88,7 @@ public virtual RebaseResult Start(Branch branch, Branch upstream, Branch onto, I if (this.repository.Info.CurrentOperation != CurrentOperation.None) { - throw new LibGit2SharpException("A {0} operation is already in progress.", + throw new LibGit2SharpException("A {0} operation is already in progress.", this.repository.Info.CurrentOperation); } diff --git a/LibGit2Sharp/RecurseSubmodulesException.cs b/LibGit2Sharp/RecurseSubmodulesException.cs index cf4479701..2269f0d16 100644 --- a/LibGit2Sharp/RecurseSubmodulesException.cs +++ b/LibGit2Sharp/RecurseSubmodulesException.cs @@ -1,5 +1,7 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif namespace LibGit2Sharp { @@ -8,7 +10,9 @@ namespace LibGit2Sharp /// through submodules. The inner exception contains the exception that was /// initially thrown while operating on the submodule. /// +#if NETFRAMEWORK [Serializable] +#endif public class RecurseSubmodulesException : LibGit2SharpException { /// @@ -34,6 +38,7 @@ public RecurseSubmodulesException(string message, Exception innerException, stri InitialRepositoryPath = initialRepositoryPath; } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -42,5 +47,6 @@ public RecurseSubmodulesException(string message, Exception innerException, stri protected RecurseSubmodulesException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif } } diff --git a/LibGit2Sharp/RefSpec.cs b/LibGit2Sharp/RefSpec.cs index 5819820eb..4d9e28fbe 100644 --- a/LibGit2Sharp/RefSpec.cs +++ b/LibGit2Sharp/RefSpec.cs @@ -13,9 +13,9 @@ namespace LibGit2Sharp public class RefSpec { // This is here to keep the pointer alive - #pragma warning disable 0414 +#pragma warning disable 0414 readonly Remote remote; - #pragma warning restore 0414 +#pragma warning restore 0414 readonly IntPtr handle; internal unsafe RefSpec(Remote remote, git_refspec* handle) diff --git a/LibGit2Sharp/RefSpecCollection.cs b/LibGit2Sharp/RefSpecCollection.cs index 6ba813e47..a35710719 100644 --- a/LibGit2Sharp/RefSpecCollection.cs +++ b/LibGit2Sharp/RefSpecCollection.cs @@ -16,10 +16,10 @@ namespace LibGit2Sharp public class RefSpecCollection : IEnumerable { // These are here to keep the pointer alive - #pragma warning disable 0414 +#pragma warning disable 0414 readonly Remote remote; readonly RemoteHandle handle; - #pragma warning restore 0414 +#pragma warning restore 0414 readonly Lazy> refspecs; /// diff --git a/LibGit2Sharp/Reference.cs b/LibGit2Sharp/Reference.cs index 40a85f79f..9a86195d1 100644 --- a/LibGit2Sharp/Reference.cs +++ b/LibGit2Sharp/Reference.cs @@ -25,11 +25,7 @@ public abstract class Reference : IEquatable, IBelongToARepository protected Reference() { } - /// - /// This would be protected+internal, were that supported by C#. - /// Do not use except in subclasses. - /// - internal Reference(IRepository repo, string canonicalName, string targetIdentifier) + private protected Reference(IRepository repo, string canonicalName, string targetIdentifier) { this.repo = repo; this.canonicalName = canonicalName; @@ -39,7 +35,7 @@ internal Reference(IRepository repo, string canonicalName, string targetIdentifi // This overload lets public-facing methods avoid having to use the pointers directly internal static unsafe T BuildFromPtr(ReferenceHandle handle, Repository repo) where T : Reference { - return BuildFromPtr((git_reference*) handle.Handle, repo); + return BuildFromPtr((git_reference*)handle.AsIntPtr(), repo); } internal static unsafe T BuildFromPtr(git_reference* handle, Repository repo) where T : Reference @@ -153,10 +149,10 @@ public virtual string TargetIdentifier } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as Reference); @@ -204,7 +200,7 @@ public override int GetHashCode() } /// - /// Returns the , a representation of the current . + /// Returns the , a representation of the current . /// /// The that represents the current . public override string ToString() diff --git a/LibGit2Sharp/ReferenceCollection.cs b/LibGit2Sharp/ReferenceCollection.cs index 602a20f17..92bf85426 100644 --- a/LibGit2Sharp/ReferenceCollection.cs +++ b/LibGit2Sharp/ReferenceCollection.cs @@ -404,7 +404,7 @@ public virtual Reference Rename(string currentName, string newName, if (reference == null) { - throw new LibGit2SharpException("Reference '{0}' doesn't exist. One cannot move a non existing reference.", + throw new LibGit2SharpException("Reference '{0}' doesn't exist. One cannot move a non existing reference.", currentName); } @@ -539,7 +539,7 @@ public virtual Reference UpdateTarget(string name, string canonicalRefNameOrObje if (refState == RefState.DoesNotLookValid) { - throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The reference specified by {0} is a Symbolic reference, you must provide a reference canonical name as the target.", name), "canonicalRefNameOrObjectish"); + throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The reference specified by {0} is a Symbolic reference, you must provide a reference canonical name as the target.", name), nameof(canonicalRefNameOrObjectish)); } return UpdateTarget(symbolicReference, targetRef, logMessage); diff --git a/LibGit2Sharp/ReferenceWrapper.cs b/LibGit2Sharp/ReferenceWrapper.cs index 3e4243a7e..7fb8497c6 100644 --- a/LibGit2Sharp/ReferenceWrapper.cs +++ b/LibGit2Sharp/ReferenceWrapper.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using LibGit2Sharp.Core; @@ -10,7 +11,11 @@ namespace LibGit2Sharp /// /// The type of the referenced Git object. [DebuggerDisplay("{DebuggerDisplay,nq}")] +#if NET + public abstract class ReferenceWrapper<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TObject> : IEquatable>, IBelongToARepository where TObject : GitObject +#else public abstract class ReferenceWrapper : IEquatable>, IBelongToARepository where TObject : GitObject +#endif { /// /// The repository. @@ -124,10 +129,10 @@ public bool Equals(ReferenceWrapper other) } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as ReferenceWrapper); diff --git a/LibGit2Sharp/Remote.cs b/LibGit2Sharp/Remote.cs index 3bf957866..401a7ddd0 100644 --- a/LibGit2Sharp/Remote.cs +++ b/LibGit2Sharp/Remote.cs @@ -83,7 +83,8 @@ public virtual string Name /// public virtual string Url { - get { return Proxy.git_remote_url(handle); } } + get { return Proxy.git_remote_url(handle); } + } /// /// Gets the distinct push url for this remote repository, if set. diff --git a/LibGit2Sharp/RemoteCallbacks.cs b/LibGit2Sharp/RemoteCallbacks.cs index ce5dccf81..6061b10e1 100644 --- a/LibGit2Sharp/RemoteCallbacks.cs +++ b/LibGit2Sharp/RemoteCallbacks.cs @@ -310,10 +310,10 @@ private unsafe int GitCertificateCheck(git_certificate* certPtr, int valid, IntP switch (certPtr->type) { case GitCertificateType.X509: - cert = new CertificateX509((git_certificate_x509*) certPtr); + cert = new CertificateX509((git_certificate_x509*)certPtr); break; case GitCertificateType.Hostkey: - cert = new CertificateSsh((git_certificate_ssh*) certPtr); + cert = new CertificateSsh((git_certificate_ssh*)certPtr); break; } @@ -355,7 +355,7 @@ private int GitPushNegotiationHandler(IntPtr updates, UIntPtr len, IntPtr payloa throw new NullReferenceException("Unexpected null git_push_update pointer was encountered"); } - PushUpdate pushUpdate = new PushUpdate((git_push_update*) ptr[i].ToPointer()); + PushUpdate pushUpdate = new PushUpdate((git_push_update*)ptr[i].ToPointer()); pushUpdates[i] = pushUpdate; } diff --git a/LibGit2Sharp/RemoteCollection.cs b/LibGit2Sharp/RemoteCollection.cs index 634f6e770..45e71c8b2 100644 --- a/LibGit2Sharp/RemoteCollection.cs +++ b/LibGit2Sharp/RemoteCollection.cs @@ -58,7 +58,8 @@ public virtual void Update(string remote, params Action[] actions { var updater = new RemoteUpdater(repository, remote); - repository.Config.WithinTransaction(() => { + repository.Config.WithinTransaction(() => + { foreach (Action action in actions) { action(updater); diff --git a/LibGit2Sharp/RemoveFromIndexException.cs b/LibGit2Sharp/RemoveFromIndexException.cs index 6d9718c18..847e4026e 100644 --- a/LibGit2Sharp/RemoveFromIndexException.cs +++ b/LibGit2Sharp/RemoveFromIndexException.cs @@ -1,13 +1,16 @@ using System; -using System.Globalization; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif namespace LibGit2Sharp { /// /// The exception that is thrown when a file cannot be removed from the index. /// +#if NETFRAMEWORK [Serializable] +#endif public class RemoveFromIndexException : LibGit2SharpException { /// @@ -27,7 +30,7 @@ public RemoveFromIndexException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public RemoveFromIndexException(string format, params object[] args) : base(format, args) @@ -43,6 +46,7 @@ public RemoveFromIndexException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -51,5 +55,6 @@ public RemoveFromIndexException(string message, Exception innerException) protected RemoveFromIndexException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif } } diff --git a/LibGit2Sharp/RenameDetails.cs b/LibGit2Sharp/RenameDetails.cs index b866aac60..8742ff0d3 100644 --- a/LibGit2Sharp/RenameDetails.cs +++ b/LibGit2Sharp/RenameDetails.cs @@ -56,10 +56,10 @@ public virtual int Similarity } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as RenameDetails); diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index 41aaecfbf..9ac5e2424 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -575,7 +575,7 @@ internal GitObject LookupInternal(ObjectId id, GitObjectType type, string knownP using (ObjectHandle obj = Proxy.git_object_lookup(handle, id, type)) { - if (obj == null || obj.IsNull) + if (obj == null || obj.IsInvalid) { return null; } @@ -656,7 +656,18 @@ internal Commit LookupCommit(string committish) /// The references in the remote repository. public static IEnumerable ListRemoteReferences(string url) { - return ListRemoteReferences(url, null); + return ListRemoteReferences(url, null, new ProxyOptions()); + } + + /// + /// Lists the Remote Repository References. + /// + /// The url to list from. + /// Options for connecting through a proxy. + /// The references in the remote repository. + public static IEnumerable ListRemoteReferences(string url, ProxyOptions proxyOptions) + { + return ListRemoteReferences(url, null, proxyOptions); } /// @@ -671,24 +682,44 @@ public static IEnumerable ListRemoteReferences(string url) /// The used to connect to remote repository. /// The references in the remote repository. public static IEnumerable ListRemoteReferences(string url, CredentialsHandler credentialsProvider) + { + return ListRemoteReferences(url, credentialsProvider, new ProxyOptions()); + } + + /// + /// Lists the Remote Repository References. + /// + /// + /// Does not require a local Repository. The retrieved + /// + /// throws in this case. + /// + /// The url to list from. + /// The used to connect to remote repository. + /// Options for connecting through a proxy. + /// The references in the remote repository. + public static IEnumerable ListRemoteReferences(string url, CredentialsHandler credentialsProvider, ProxyOptions proxyOptions) { Ensure.ArgumentNotNull(url, "url"); - using (RepositoryHandle repositoryHandle = Proxy.git_repository_new()) - using (RemoteHandle remoteHandle = Proxy.git_remote_create_anonymous(repositoryHandle, url)) - { - var gitCallbacks = new GitRemoteCallbacks { version = 1 }; - var proxyOptions = new GitProxyOptions { Version = 1 }; + proxyOptions ??= new(); - if (credentialsProvider != null) - { - var callbacks = new RemoteCallbacks(credentialsProvider); - gitCallbacks = callbacks.GenerateCallbacks(); - } + using RepositoryHandle repositoryHandle = Proxy.git_repository_new(); + using RemoteHandle remoteHandle = Proxy.git_remote_create_anonymous(repositoryHandle, url); + using var proxyOptionsWrapper = new GitProxyOptionsWrapper(proxyOptions.CreateGitProxyOptions()); - Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch, ref gitCallbacks, ref proxyOptions); - return Proxy.git_remote_ls(null, remoteHandle); + var gitCallbacks = new GitRemoteCallbacks { version = 1 }; + + if (credentialsProvider != null) + { + var callbacks = new RemoteCallbacks(credentialsProvider); + gitCallbacks = callbacks.GenerateCallbacks(); } + + var gitProxyOptions = proxyOptionsWrapper.Options; + + Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch, ref gitCallbacks, ref gitProxyOptions); + return Proxy.git_remote_ls(null, remoteHandle); } /// @@ -741,21 +772,19 @@ public static string Clone(string sourceUrl, string workdirPath) /// Local path to clone into /// controlling clone behavior /// The path to the created repository. - public static string Clone(string sourceUrl, string workdirPath, - CloneOptions options) + public static string Clone(string sourceUrl, string workdirPath, CloneOptions options) { Ensure.ArgumentNotNull(sourceUrl, "sourceUrl"); Ensure.ArgumentNotNull(workdirPath, "workdirPath"); - options = options ?? new CloneOptions(); + options ??= new CloneOptions(); // context variable that contains information on the repository that // we are cloning. var context = new RepositoryOperationContext(Path.GetFullPath(workdirPath), sourceUrl); // Notify caller that we are starting to work with the current repository. - bool continueOperation = OnRepositoryOperationStarting(options.RepositoryOperationStarting, - context); + bool continueOperation = OnRepositoryOperationStarting(options.FetchOptions.RepositoryOperationStarting, context); if (!continueOperation) { @@ -768,12 +797,13 @@ public static string Clone(string sourceUrl, string workdirPath, var gitCheckoutOptions = checkoutOptionsWrapper.Options; var gitFetchOptions = fetchOptionsWrapper.Options; - gitFetchOptions.ProxyOptions = new GitProxyOptions { Version = 1 }; - gitFetchOptions.RemoteCallbacks = new RemoteCallbacks(options).GenerateCallbacks(); + gitFetchOptions.Depth = options.FetchOptions.Depth; + gitFetchOptions.ProxyOptions = options.FetchOptions.ProxyOptions.CreateGitProxyOptions(); + gitFetchOptions.RemoteCallbacks = new RemoteCallbacks(options.FetchOptions).GenerateCallbacks(); + if (options.FetchOptions != null && options.FetchOptions.CustomHeaders != null) { - gitFetchOptions.CustomHeaders = - GitStrArrayManaged.BuildFrom(options.FetchOptions.CustomHeaders); + gitFetchOptions.CustomHeaders = GitStrArrayManaged.BuildFrom(options.FetchOptions.CustomHeaders); } var cloneOpts = new GitCloneOptions @@ -801,8 +831,7 @@ public static string Clone(string sourceUrl, string workdirPath, } // Notify caller that we are done with the current repository. - OnRepositoryOperationCompleted(options.RepositoryOperationCompleted, - context); + OnRepositoryOperationCompleted(options.FetchOptions.RepositoryOperationCompleted, context); // Recursively clone submodules if requested. try @@ -811,9 +840,7 @@ public static string Clone(string sourceUrl, string workdirPath, } catch (Exception ex) { - throw new RecurseSubmodulesException("The top level repository was cloned, but there was an error cloning its submodules.", - ex, - clonedRepoPath); + throw new RecurseSubmodulesException("The top level repository was cloned, but there was an error cloning its submodules.", ex, clonedRepoPath); } return clonedRepoPath; @@ -834,14 +861,11 @@ private static void RecursivelyCloneSubmodules(CloneOptions options, string repo using (Repository repo = new Repository(repoPath)) { - SubmoduleUpdateOptions updateOptions = new SubmoduleUpdateOptions() + var updateOptions = new SubmoduleUpdateOptions() { Init = true, - CredentialsProvider = options.CredentialsProvider, OnCheckoutProgress = options.OnCheckoutProgress, - OnProgress = options.OnProgress, - OnTransferProgress = options.OnTransferProgress, - OnUpdateTips = options.OnUpdateTips, + FetchOptions = options.FetchOptions }; string parentRepoWorkDir = repo.Info.WorkingDirectory; @@ -862,7 +886,7 @@ private static void RecursivelyCloneSubmodules(CloneOptions options, string repo sm.Name, recursionDepth); - bool continueOperation = OnRepositoryOperationStarting(options.RepositoryOperationStarting, + bool continueOperation = OnRepositoryOperationStarting(options.FetchOptions.RepositoryOperationStarting, context); if (!continueOperation) @@ -872,7 +896,7 @@ private static void RecursivelyCloneSubmodules(CloneOptions options, string repo repo.Submodules.Update(sm.Name, updateOptions); - OnRepositoryOperationCompleted(options.RepositoryOperationCompleted, + OnRepositoryOperationCompleted(options.FetchOptions.RepositoryOperationCompleted, context); submodules.Add(Path.Combine(repo.Info.WorkingDirectory, sm.Path)); @@ -1050,7 +1074,7 @@ public Commit Commit(string message, Signature author, Signature committer, Comm if (treesame && !amendMergeCommit) { - throw (options.AmendPreviousCommit ? + throw (options.AmendPreviousCommit ? new EmptyCommitException("Amending this commit would produce a commit that is identical to its parent (id = {0})", parents[0].Id) : new EmptyCommitException("No changes; nothing to commit.")); } @@ -1241,7 +1265,7 @@ public MergeResult MergeFetchedRefs(Signature merger, MergeOptions options) if (fetchHeads.Length == 0) { var expectedRef = this.Head.UpstreamBranchCanonicalName; - throw new MergeFetchHeadNotFoundException("The current branch is configured to merge with the reference '{0}' from the remote, but this reference was not fetched.", + throw new MergeFetchHeadNotFoundException("The current branch is configured to merge with the reference '{0}' from the remote, but this reference was not fetched.", expectedRef); } @@ -1428,7 +1452,7 @@ private FastForwardStrategy FastForwardStrategyFromMergePreference(GitMergePrefe case GitMergePreference.GIT_MERGE_PREFERENCE_NO_FASTFORWARD: return FastForwardStrategy.NoFastForward; default: - throw new InvalidOperationException(String.Format("Unknown merge preference: {0}", preference)); + throw new InvalidOperationException(string.Format("Unknown merge preference: {0}", preference)); } } @@ -1646,7 +1670,7 @@ internal FilePath[] ToFilePaths(IEnumerable paths) { if (string.IsNullOrEmpty(path)) { - throw new ArgumentException("At least one provided path is either null or empty.", "paths"); + throw new ArgumentException("At least one provided path is either null or empty.", nameof(paths)); } filePaths.Add(this.BuildRelativePathFrom(path)); @@ -1654,7 +1678,7 @@ internal FilePath[] ToFilePaths(IEnumerable paths) if (filePaths.Count == 0) { - throw new ArgumentException("No path has been provided.", "paths"); + throw new ArgumentException("No path has been provided.", nameof(paths)); } return filePaths.ToArray(); @@ -1753,7 +1777,7 @@ public void RevParse(string revision, out Reference reference, out GitObject obj using (var objH = handles.Item1) using (var refH = handles.Item2) { - reference = refH.IsNull ? null : Reference.BuildFromPtr(refH, this); + reference = refH.IsInvalid ? null : Reference.BuildFromPtr(refH, this); obj = GitObject.BuildFrom(this, Proxy.git_object_id(objH), Proxy.git_object_type(objH), PathFromRevparseSpec(revision)); } } diff --git a/LibGit2Sharp/RepositoryExtensions.cs b/LibGit2Sharp/RepositoryExtensions.cs index edeb6b93f..5d0788c8a 100644 --- a/LibGit2Sharp/RepositoryExtensions.cs +++ b/LibGit2Sharp/RepositoryExtensions.cs @@ -24,7 +24,7 @@ public static T Lookup(this IRepository repository, string objectish) where T { EnsureNoGitLink(); - if (typeof (T) == typeof (GitObject)) + if (typeof(T) == typeof(GitObject)) { return (T)repository.Lookup(objectish); } diff --git a/LibGit2Sharp/RepositoryNotFoundException.cs b/LibGit2Sharp/RepositoryNotFoundException.cs index 2255c0891..e2bc63d8b 100644 --- a/LibGit2Sharp/RepositoryNotFoundException.cs +++ b/LibGit2Sharp/RepositoryNotFoundException.cs @@ -1,5 +1,7 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif namespace LibGit2Sharp { @@ -7,7 +9,9 @@ namespace LibGit2Sharp /// The exception that is thrown when a is being built with /// a path that doesn't point at a valid Git repository or workdir. /// +#if NETFRAMEWORK [Serializable] +#endif public class RepositoryNotFoundException : LibGit2SharpException { /// @@ -27,7 +31,7 @@ public RepositoryNotFoundException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public RepositoryNotFoundException(string format, params object[] args) : base(format, args) @@ -42,6 +46,7 @@ public RepositoryNotFoundException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -50,5 +55,6 @@ public RepositoryNotFoundException(string message, Exception innerException) protected RepositoryNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif } } diff --git a/LibGit2Sharp/RepositoryStatus.cs b/LibGit2Sharp/RepositoryStatus.cs index 490dc6798..cc1c6e7e0 100644 --- a/LibGit2Sharp/RepositoryStatus.cs +++ b/LibGit2Sharp/RepositoryStatus.cs @@ -64,7 +64,7 @@ internal unsafe RepositoryStatus(Repository repo, StatusOptions options) for (int i = 0; i < count; i++) { - git_status_entry *entry = Proxy.git_status_byindex(list, i); + git_status_entry* entry = Proxy.git_status_byindex(list, i); AddStatusEntryForDelta(entry->status, entry->head_to_index, entry->index_to_workdir); } diff --git a/LibGit2Sharp/RevertResult.cs b/LibGit2Sharp/RevertResult.cs index da54046a4..8f9a270d3 100644 --- a/LibGit2Sharp/RevertResult.cs +++ b/LibGit2Sharp/RevertResult.cs @@ -34,7 +34,7 @@ internal RevertResult(RevertStatus status, Commit commit = null) public virtual RevertStatus Status { get; private set; } } - /// + /// /// The status of what happened as a result of a revert. /// public enum RevertStatus diff --git a/LibGit2Sharp/Signature.cs b/LibGit2Sharp/Signature.cs index bad656d05..7ed7a4916 100644 --- a/LibGit2Sharp/Signature.cs +++ b/LibGit2Sharp/Signature.cs @@ -86,10 +86,10 @@ public DateTimeOffset When } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as Signature); diff --git a/LibGit2Sharp/SimilarityOptions.cs b/LibGit2Sharp/SimilarityOptions.cs index 13d26abf2..4d2b0cd95 100644 --- a/LibGit2Sharp/SimilarityOptions.cs +++ b/LibGit2Sharp/SimilarityOptions.cs @@ -81,7 +81,7 @@ public SimilarityOptions() /// public static SimilarityOptions None { - get { return new SimilarityOptions {RenameDetectionMode = RenameDetectionMode.None}; } + get { return new SimilarityOptions { RenameDetectionMode = RenameDetectionMode.None }; } } /// @@ -89,7 +89,7 @@ public static SimilarityOptions None /// public static SimilarityOptions Renames { - get { return new SimilarityOptions {RenameDetectionMode = RenameDetectionMode.Renames}; } + get { return new SimilarityOptions { RenameDetectionMode = RenameDetectionMode.Renames }; } } /// @@ -97,7 +97,7 @@ public static SimilarityOptions Renames /// public static SimilarityOptions Exact { - get { return new SimilarityOptions {RenameDetectionMode = RenameDetectionMode.Exact}; } + get { return new SimilarityOptions { RenameDetectionMode = RenameDetectionMode.Exact }; } } /// @@ -105,7 +105,7 @@ public static SimilarityOptions Exact /// public static SimilarityOptions Copies { - get { return new SimilarityOptions {RenameDetectionMode = RenameDetectionMode.Copies}; } + get { return new SimilarityOptions { RenameDetectionMode = RenameDetectionMode.Copies }; } } /// @@ -113,7 +113,7 @@ public static SimilarityOptions Copies /// public static SimilarityOptions CopiesHarder { - get { return new SimilarityOptions {RenameDetectionMode = RenameDetectionMode.CopiesHarder}; } + get { return new SimilarityOptions { RenameDetectionMode = RenameDetectionMode.CopiesHarder }; } } /// @@ -121,7 +121,7 @@ public static SimilarityOptions CopiesHarder /// public static SimilarityOptions Default { - get { return new SimilarityOptions {RenameDetectionMode = RenameDetectionMode.Default}; } + get { return new SimilarityOptions { RenameDetectionMode = RenameDetectionMode.Default }; } } /// diff --git a/LibGit2Sharp/SmartSubtransport.cs b/LibGit2Sharp/SmartSubtransport.cs index 66fcd12bf..6160c849b 100644 --- a/LibGit2Sharp/SmartSubtransport.cs +++ b/LibGit2Sharp/SmartSubtransport.cs @@ -73,7 +73,9 @@ public int CertificateCheck(Certificate cert, bool valid, string hostname) var certPtr = sshCert.ToPointer(); ret = NativeMethods.git_transport_smart_certificate_check(Transport, certPtr, valid ? 1 : 0, hostname); Marshal.FreeHGlobal(certPtr); - } else { + } + else + { IntPtr certPtr, dataPtr; certPtr = x509Cert.ToPointers(out dataPtr); ret = NativeMethods.git_transport_smart_certificate_check(Transport, certPtr, valid ? 1 : 0, hostname); @@ -131,11 +133,11 @@ public int AcquireCredentials(out Credentials cred, string user, params Type[] m unsafe { - var baseCred = (GitCredential*) credHandle; + var baseCred = (GitCredential*)credHandle; switch (baseCred->credtype) { case GitCredentialType.UserPassPlaintext: - cred = UsernamePasswordCredentials.FromNative((GitCredentialUserpass*) credHandle); + cred = UsernamePasswordCredentials.FromNative((GitCredentialUserpass*)credHandle); return 0; case GitCredentialType.Default: cred = new DefaultCredentials(); @@ -158,7 +160,7 @@ public int AcquireCredentials(out Credentials cred, string user, params Type[] m /// The endpoint to connect to /// The type of connection to create /// A SmartSubtransportStream representing the connection - protected abstract SmartSubtransportStream Action(String url, GitSmartSubtransportAction action); + protected abstract SmartSubtransportStream Action(string url, GitSmartSubtransportAction action); /// /// Invoked by libgit2 when this subtransport is no longer needed, but may be re-used in the future. @@ -225,7 +227,7 @@ private static int Action( stream = IntPtr.Zero; SmartSubtransport t = GCHandle.FromIntPtr(Marshal.ReadIntPtr(subtransport, GitSmartSubtransport.GCHandleOffset)).Target as SmartSubtransport; - String urlAsString = LaxUtf8Marshaler.FromNative(url); + string urlAsString = LaxUtf8Marshaler.FromNative(url); if (t == null) { @@ -233,12 +235,12 @@ private static int Action( return (int)GitErrorCode.Error; } - if (String.IsNullOrEmpty(urlAsString)) + if (string.IsNullOrEmpty(urlAsString)) { urlAsString = t.LastActionUrl; } - if (String.IsNullOrEmpty(urlAsString)) + if (string.IsNullOrEmpty(urlAsString)) { Proxy.git_error_set_str(GitErrorCategory.Net, "no url provided"); return (int)GitErrorCode.Error; diff --git a/LibGit2Sharp/StashCollection.cs b/LibGit2Sharp/StashCollection.cs index 5fe775eba..42162ada5 100644 --- a/LibGit2Sharp/StashCollection.cs +++ b/LibGit2Sharp/StashCollection.cs @@ -67,7 +67,7 @@ public virtual Stash this[int index] { if (index < 0) { - throw new ArgumentOutOfRangeException("index", "The passed index must be a positive integer."); + throw new ArgumentOutOfRangeException(nameof(index), "The passed index must be a positive integer."); } GitObject stashCommit = repo.Lookup(string.Format(CultureInfo.InvariantCulture, @@ -146,7 +146,7 @@ public virtual StashApplyStatus Apply(int index, StashApplyOptions options) { if (index < 0) { - throw new ArgumentException("The passed index must be a positive integer.", "index"); + throw new ArgumentException("The passed index must be a positive integer.", nameof(index)); } if (options == null) @@ -189,7 +189,7 @@ public virtual StashApplyStatus Pop(int index, StashApplyOptions options) { if (index < 0) { - throw new ArgumentException("The passed index must be a positive integer.", "index"); + throw new ArgumentException("The passed index must be a positive integer.", nameof(index)); } if (options == null) @@ -231,7 +231,7 @@ public virtual void Remove(int index) { if (index < 0) { - throw new ArgumentException("The passed index must be a positive integer.", "index"); + throw new ArgumentException("The passed index must be a positive integer.", nameof(index)); } Proxy.git_stash_drop(repo.Handle, index); diff --git a/LibGit2Sharp/StatusEntry.cs b/LibGit2Sharp/StatusEntry.cs index 7008712c6..bd2ef8883 100644 --- a/LibGit2Sharp/StatusEntry.cs +++ b/LibGit2Sharp/StatusEntry.cs @@ -66,10 +66,10 @@ public virtual RenameDetails IndexToWorkDirRenameDetails } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as StatusEntry); diff --git a/LibGit2Sharp/Submodule.cs b/LibGit2Sharp/Submodule.cs index ace995205..f8193af13 100644 --- a/LibGit2Sharp/Submodule.cs +++ b/LibGit2Sharp/Submodule.cs @@ -107,10 +107,10 @@ public virtual SubmoduleStatus RetrieveStatus() } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as Submodule); @@ -136,7 +136,7 @@ public override int GetHashCode() } /// - /// Returns the , a representation of the current . + /// Returns the , a representation of the current . /// /// The that represents the current . public override string ToString() diff --git a/LibGit2Sharp/SubmoduleCollection.cs b/LibGit2Sharp/SubmoduleCollection.cs index fc508107a..061196c7d 100644 --- a/LibGit2Sharp/SubmoduleCollection.cs +++ b/LibGit2Sharp/SubmoduleCollection.cs @@ -74,43 +74,41 @@ public virtual void Init(string name, bool overwrite) /// Update specified submodule. /// /// This will: - /// 1) Optionally initialize the if it not already initialzed, + /// 1) Optionally initialize the if it not already initialized, /// 2) clone the sub repository if it has not already been cloned, and /// 3) checkout the commit ID for the submodule in the sub repository. /// /// /// The name of the submodule to update. - /// Options controlling submodule udpate behavior and callbacks. + /// Options controlling submodule update behavior and callbacks. public virtual void Update(string name, SubmoduleUpdateOptions options) { - options = options ?? new SubmoduleUpdateOptions(); + options ??= new SubmoduleUpdateOptions(); - using (var handle = Proxy.git_submodule_lookup(repo.Handle, name)) - { - if (handle == null) - { - throw new NotFoundException("Submodule lookup failed for '{0}'.", - name); - } + using var handle = Proxy.git_submodule_lookup(repo.Handle, name) ?? throw new NotFoundException("Submodule lookup failed for '{0}'.", name); + using var checkoutOptionsWrapper = new GitCheckoutOptsWrapper(options); + using var fetchOptionsWrapper = new GitFetchOptionsWrapper(); - using (GitCheckoutOptsWrapper checkoutOptionsWrapper = new GitCheckoutOptsWrapper(options)) - { - var gitCheckoutOptions = checkoutOptionsWrapper.Options; + var gitCheckoutOptions = checkoutOptionsWrapper.Options; - var remoteCallbacks = new RemoteCallbacks(options); - var gitRemoteCallbacks = remoteCallbacks.GenerateCallbacks(); + var gitFetchOptions = fetchOptionsWrapper.Options; + gitFetchOptions.ProxyOptions = options.FetchOptions.ProxyOptions.CreateGitProxyOptions(); + gitFetchOptions.RemoteCallbacks = new RemoteCallbacks(options.FetchOptions).GenerateCallbacks(); - var gitSubmoduleUpdateOpts = new GitSubmoduleUpdateOptions - { - Version = 1, - CheckoutOptions = gitCheckoutOptions, - FetchOptions = new GitFetchOptions { ProxyOptions = new GitProxyOptions { Version = 1 }, RemoteCallbacks = gitRemoteCallbacks }, - CloneCheckoutStrategy = CheckoutStrategy.GIT_CHECKOUT_SAFE - }; - - Proxy.git_submodule_update(handle, options.Init, ref gitSubmoduleUpdateOpts); - } + if (options.FetchOptions != null && options.FetchOptions.CustomHeaders != null) + { + gitFetchOptions.CustomHeaders = + GitStrArrayManaged.BuildFrom(options.FetchOptions.CustomHeaders); } + + var gitSubmoduleUpdateOpts = new GitSubmoduleUpdateOptions + { + Version = 1, + CheckoutOptions = gitCheckoutOptions, + FetchOptions = gitFetchOptions + }; + + Proxy.git_submodule_update(handle, options.Init, ref gitSubmoduleUpdateOpts); } /// diff --git a/LibGit2Sharp/SubmoduleUpdateOptions.cs b/LibGit2Sharp/SubmoduleUpdateOptions.cs index 89f895d75..082e17338 100644 --- a/LibGit2Sharp/SubmoduleUpdateOptions.cs +++ b/LibGit2Sharp/SubmoduleUpdateOptions.cs @@ -6,7 +6,7 @@ namespace LibGit2Sharp /// /// Options controlling Submodule Update behavior and callbacks. /// - public sealed class SubmoduleUpdateOptions : FetchOptionsBase, IConvertableToGitCheckoutOpts + public sealed class SubmoduleUpdateOptions : IConvertableToGitCheckoutOpts { /// /// Initialize the submodule if it is not already initialized. @@ -30,6 +30,11 @@ public sealed class SubmoduleUpdateOptions : FetchOptionsBase, IConvertableToGit /// public CheckoutNotifyFlags CheckoutNotifyFlags { get; set; } + /// + /// Collection of parameters controlling Fetch behavior. + /// + public FetchOptions FetchOptions { get; internal set; } = new(); + CheckoutCallbacks IConvertableToGitCheckoutOpts.GenerateCallbacks() { return CheckoutCallbacks.From(OnCheckoutProgress, OnCheckoutNotify); diff --git a/LibGit2Sharp/TagCollection.cs b/LibGit2Sharp/TagCollection.cs index 8bd9168b0..98bfd257d 100644 --- a/LibGit2Sharp/TagCollection.cs +++ b/LibGit2Sharp/TagCollection.cs @@ -114,7 +114,7 @@ public virtual Tag Add(string name, string objectish) /// The name. /// Revparse spec for the target object. /// True to allow silent overwriting a potentially existing tag, false otherwise. - public virtual Tag Add( string name, string objectish, bool allowOverwrite) + public virtual Tag Add(string name, string objectish, bool allowOverwrite) { Ensure.ArgumentNotNullOrEmptyString(objectish, "objectish"); diff --git a/LibGit2Sharp/TransientIndex.cs b/LibGit2Sharp/TransientIndex.cs index 65b7b7872..b62678c83 100644 --- a/LibGit2Sharp/TransientIndex.cs +++ b/LibGit2Sharp/TransientIndex.cs @@ -7,7 +7,7 @@ namespace LibGit2Sharp /// An implementation of with disposal managed by the caller /// (instead of automatically disposing when the repository is disposed) /// - public class TransientIndex: Index, IDisposable + public class TransientIndex : Index, IDisposable { /// /// Needed for mocking purposes. diff --git a/LibGit2Sharp/Tree.cs b/LibGit2Sharp/Tree.cs index f8494ad8b..30f534a99 100644 --- a/LibGit2Sharp/Tree.cs +++ b/LibGit2Sharp/Tree.cs @@ -90,7 +90,7 @@ internal static string CombinePath(string a, string b) { var bld = new StringBuilder(); bld.Append(a); - if (!String.IsNullOrEmpty(a) && + if (!string.IsNullOrEmpty(a) && !a.EndsWith("/", StringComparison.Ordinal) && !b.StartsWith("/", StringComparison.Ordinal)) { @@ -110,7 +110,8 @@ public virtual IEnumerator GetEnumerator() { using (var obj = new ObjectSafeWrapper(Id, repo.Handle, throwIfMissing: true)) { - for (uint i = 0; i < Count; i++) { + for (uint i = 0; i < Count; i++) + { yield return byIndex(obj, i, Id, repo, path); } } diff --git a/LibGit2Sharp/TreeChanges.cs b/LibGit2Sharp/TreeChanges.cs index 6e8a0eff5..6a54d9c09 100644 --- a/LibGit2Sharp/TreeChanges.cs +++ b/LibGit2Sharp/TreeChanges.cs @@ -55,7 +55,7 @@ private IEnumerable GetChangesOfKind(ChangeKind changeKind) private unsafe bool TryGetEntryWithChangeTypeAt(int index, ChangeKind changeKind, out TreeEntryChanges entry) { if (index < 0 || index > count.Value) - throw new ArgumentOutOfRangeException("index", "Index was out of range. Must be non-negative and less than the size of the collection."); + throw new ArgumentOutOfRangeException(nameof(index), "Index was out of range. Must be non-negative and less than the size of the collection."); var delta = Proxy.git_diff_get_delta(diff, index); @@ -90,7 +90,7 @@ public virtual IEnumerator GetEnumerator() private unsafe TreeEntryChanges GetEntryAt(int index) { if (index < 0 || index > count.Value) - throw new ArgumentOutOfRangeException("index", "Index was out of range. Must be non-negative and less than the size of the collection."); + throw new ArgumentOutOfRangeException(nameof(index), "Index was out of range. Must be non-negative and less than the size of the collection."); return new TreeEntryChanges(Proxy.git_diff_get_delta(diff, index)); } diff --git a/LibGit2Sharp/TreeDefinition.cs b/LibGit2Sharp/TreeDefinition.cs index 73c21aac7..91389f6e3 100644 --- a/LibGit2Sharp/TreeDefinition.cs +++ b/LibGit2Sharp/TreeDefinition.cs @@ -94,6 +94,7 @@ public virtual TreeDefinition Remove(string treeEntryPath) if (segments.Item2 == null) { entries.Remove(segments.Item1); + unwrappedTrees.Remove(segments.Item1); } if (!unwrappedTrees.ContainsKey(segments.Item1)) diff --git a/LibGit2Sharp/TreeEntry.cs b/LibGit2Sharp/TreeEntry.cs index e500a8ee1..943e14570 100644 --- a/LibGit2Sharp/TreeEntry.cs +++ b/LibGit2Sharp/TreeEntry.cs @@ -93,10 +93,10 @@ private GitObject RetrieveTreeEntryTarget() } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as TreeEntry); diff --git a/LibGit2Sharp/TreeEntryDefinition.cs b/LibGit2Sharp/TreeEntryDefinition.cs index 2a3ceb35f..d32cc722c 100644 --- a/LibGit2Sharp/TreeEntryDefinition.cs +++ b/LibGit2Sharp/TreeEntryDefinition.cs @@ -112,10 +112,10 @@ internal static TreeEntryDefinition From(Tree tree) } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as TreeEntryDefinition); diff --git a/LibGit2Sharp/UnbornBranchException.cs b/LibGit2Sharp/UnbornBranchException.cs index 34ef437cb..8f01a63ab 100644 --- a/LibGit2Sharp/UnbornBranchException.cs +++ b/LibGit2Sharp/UnbornBranchException.cs @@ -1,5 +1,7 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif namespace LibGit2Sharp { @@ -7,7 +9,9 @@ namespace LibGit2Sharp /// The exception that is thrown when a operation requiring an existing /// branch is performed against an unborn branch. /// +#if NETFRAMEWORK [Serializable] +#endif public class UnbornBranchException : LibGit2SharpException { /// @@ -27,7 +31,7 @@ public UnbornBranchException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public UnbornBranchException(string format, params object[] args) : base(format, args) @@ -42,6 +46,7 @@ public UnbornBranchException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -50,5 +55,6 @@ public UnbornBranchException(string message, Exception innerException) protected UnbornBranchException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif } } diff --git a/LibGit2Sharp/UnmatchedPathException.cs b/LibGit2Sharp/UnmatchedPathException.cs index 7d118346d..96e5654c7 100644 --- a/LibGit2Sharp/UnmatchedPathException.cs +++ b/LibGit2Sharp/UnmatchedPathException.cs @@ -1,12 +1,16 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif namespace LibGit2Sharp { /// /// The exception that is thrown when an explicit path or a list of explicit paths could not be matched. /// +#if NETFRAMEWORK [Serializable] +#endif public class UnmatchedPathException : LibGit2SharpException { /// @@ -26,7 +30,7 @@ public UnmatchedPathException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public UnmatchedPathException(string format, params object[] args) : base(format, args) @@ -41,6 +45,7 @@ public UnmatchedPathException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -49,5 +54,6 @@ public UnmatchedPathException(string message, Exception innerException) protected UnmatchedPathException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif } } diff --git a/LibGit2Sharp/UnmergedIndexEntriesException.cs b/LibGit2Sharp/UnmergedIndexEntriesException.cs index 7594049b1..f9f1a834b 100644 --- a/LibGit2Sharp/UnmergedIndexEntriesException.cs +++ b/LibGit2Sharp/UnmergedIndexEntriesException.cs @@ -1,5 +1,7 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif using LibGit2Sharp.Core; namespace LibGit2Sharp @@ -8,7 +10,9 @@ namespace LibGit2Sharp /// The exception that is thrown when an operation that requires a fully merged index /// is performed against an index with unmerged entries /// +#if NETFRAMEWORK [Serializable] +#endif public class UnmergedIndexEntriesException : NativeException { /// @@ -28,7 +32,7 @@ public UnmergedIndexEntriesException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public UnmergedIndexEntriesException(string format, params object[] args) : base(format, args) @@ -43,6 +47,7 @@ public UnmergedIndexEntriesException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -51,6 +56,7 @@ public UnmergedIndexEntriesException(string message, Exception innerException) protected UnmergedIndexEntriesException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif internal UnmergedIndexEntriesException(string message, GitErrorCategory category) : base(message, category) diff --git a/LibGit2Sharp/UserCanceledException.cs b/LibGit2Sharp/UserCanceledException.cs index ba6458049..f3c6af7dd 100644 --- a/LibGit2Sharp/UserCanceledException.cs +++ b/LibGit2Sharp/UserCanceledException.cs @@ -1,5 +1,7 @@ using System; +#if NETFRAMEWORK using System.Runtime.Serialization; +#endif using LibGit2Sharp.Core; namespace LibGit2Sharp @@ -7,7 +9,9 @@ namespace LibGit2Sharp /// /// The exception that is thrown when an operation is canceled. /// +#if NETFRAMEWORK [Serializable] +#endif public class UserCancelledException : NativeException { /// @@ -27,7 +31,7 @@ public UserCancelledException(string message) /// /// Initializes a new instance of the class with a specified error message. /// - /// A composite format string for use in . + /// A composite format string for use in . /// An object array that contains zero or more objects to format. public UserCancelledException(string format, params object[] args) : base(format, args) @@ -42,6 +46,7 @@ public UserCancelledException(string message, Exception innerException) : base(message, innerException) { } +#if NETFRAMEWORK /// /// Initializes a new instance of the class with a serialized data. /// @@ -50,6 +55,7 @@ public UserCancelledException(string message, Exception innerException) protected UserCancelledException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif internal UserCancelledException(string message, GitErrorCategory category) : base(message, category) diff --git a/LibGit2Sharp/Worktree.cs b/LibGit2Sharp/Worktree.cs index 13fea072b..ca7f5ef16 100644 --- a/LibGit2Sharp/Worktree.cs +++ b/LibGit2Sharp/Worktree.cs @@ -65,10 +65,10 @@ internal WorktreeHandle GetWorktreeHandle() public virtual string LockReason { get { return worktreeLock == null ? null : worktreeLock.Reason; } } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as Worktree); @@ -95,7 +95,7 @@ public virtual void Unlock() this.worktreeLock = Proxy.git_worktree_is_locked(handle); } } - + /// /// Lock the worktree /// @@ -118,7 +118,7 @@ public override int GetHashCode() } /// - /// Returns the , a representation of the current . + /// Returns the , a representation of the current . /// /// The that represents the current . public override string ToString() diff --git a/LibGit2Sharp/WorktreeCollection.cs b/LibGit2Sharp/WorktreeCollection.cs index 9822e882c..d99e11d7a 100644 --- a/LibGit2Sharp/WorktreeCollection.cs +++ b/LibGit2Sharp/WorktreeCollection.cs @@ -1,12 +1,10 @@ -using LibGit2Sharp.Core; -using LibGit2Sharp.Core.Handles; -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Globalization; -using System.IO; using System.Linq; -using System.Text; +using LibGit2Sharp.Core; +using LibGit2Sharp.Core.Handles; namespace LibGit2Sharp { @@ -48,22 +46,21 @@ public virtual Worktree this[string name] } /// - /// + /// Creates a worktree. /// - /// - /// - /// + /// The committish to checkout into the new worktree. + /// Name of the worktree. + /// Location of the worktree. /// - /// public virtual Worktree Add(string committishOrBranchSpec, string name, string path, bool isLocked) { - if(string.Equals(committishOrBranchSpec, name)) + if (string.Equals(committishOrBranchSpec, name)) { // Proxy.git_worktree_add() creates a new branch of name = name, so if we want to checkout a given branch then the 'name' cannot be the same as the target branch return null; } - git_worktree_add_options options = new git_worktree_add_options + var options = new git_worktree_add_options { version = 1, locked = Convert.ToInt32(isLocked) @@ -83,20 +80,18 @@ public virtual Worktree Add(string committishOrBranchSpec, string name, string p } } - - - return this[name]; + return this[name]; } /// - /// + /// Creates a worktree. /// - /// - /// + /// Name of the worktree. + /// Location of the worktree. /// public virtual Worktree Add(string name, string path, bool isLocked) { - git_worktree_add_options options = new git_worktree_add_options + var options = new git_worktree_add_options { version = 1, locked = Convert.ToInt32(isLocked) @@ -112,7 +107,7 @@ public virtual Worktree Add(string name, string path, bool isLocked) } /// - /// + /// /// /// /// @@ -122,7 +117,7 @@ public virtual bool Prune(Worktree worktree) } /// - /// + /// /// /// /// diff --git a/NativeLibraryLoadTestApp/Directory.Build.props b/NativeLibraryLoadTestApp/Directory.Build.props deleted file mode 100644 index c55b35c72..000000000 --- a/NativeLibraryLoadTestApp/Directory.Build.props +++ /dev/null @@ -1,7 +0,0 @@ - - - - false - - - diff --git a/TrimmingTestApp/Program.cs b/TrimmingTestApp/Program.cs new file mode 100644 index 000000000..e568c227b --- /dev/null +++ b/TrimmingTestApp/Program.cs @@ -0,0 +1,3 @@ +using LibGit2Sharp; + +_ = new Repository(); diff --git a/TrimmingTestApp/TrimmingTestApp.csproj b/TrimmingTestApp/TrimmingTestApp.csproj new file mode 100644 index 000000000..3c6d341f6 --- /dev/null +++ b/TrimmingTestApp/TrimmingTestApp.csproj @@ -0,0 +1,18 @@ + + + + net9.0 + Exe + enable + enable + true + true + true + + + + + + + +