diff --git a/CHANGES.md b/CHANGES.md index 4c71613e1..235187e8e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,10 @@ ### Changes + - The native libraries are now expected to be in the `lib` directory, + instead of `NativeBinaries` for improved mono compatibility. In + addition, the names of platform architectures now better reflect + the vendor naming (eg, `x86_64` instead of `amd64` on Linux). - Obsolete the config paths in RepositoryOptions ### Fixes diff --git a/CI/build.msbuild b/CI/build.msbuild index 97c503354..ad2b5f573 100644 --- a/CI/build.msbuild +++ b/CI/build.msbuild @@ -49,10 +49,10 @@ DestinationFiles="@(OutputFiles->'$(DeployFolder)\%(RecursiveDir)%(Filename)%(Extension)')" /> - + + DestinationFiles="@(NativeBinaries->'$(DeployFolder)\lib\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" /> diff --git a/LibGit2Sharp.Tests/GlobalSettingsFixture.cs b/LibGit2Sharp.Tests/GlobalSettingsFixture.cs index 698595042..8055a98d1 100644 --- a/LibGit2Sharp.Tests/GlobalSettingsFixture.cs +++ b/LibGit2Sharp.Tests/GlobalSettingsFixture.cs @@ -19,7 +19,7 @@ public void CanGetMinimumCompiledInFeatures() public void CanRetrieveValidVersionString() { // Version string format is: - // Major.Minor.Patch[-preDateTime]-LibGit2Sharp_abbrev_hash-libgit2_abbrev_hash (x86|amd64 - features) + // Major.Minor.Patch[-preDateTime]-LibGit2Sharp_abbrev_hash-libgit2_abbrev_hash (x86|x64 - features) // Example output: // "0.17.0[-pre20170914123547]-deadcafe-06d772d (x86 - Threads, Https)" @@ -29,7 +29,7 @@ public void CanRetrieveValidVersionString() // version: '0.17.0[-pre20170914123547]' LibGit2Sharp version number. // git2SharpHash:'unknown' ( when compiled from source ) else LibGit2Sharp library hash. // git2hash: '06d772d' LibGit2 library hash. - // arch: 'x86' or 'amd64' LibGit2 target. + // arch: 'x86' or 'x64' LibGit2 target. // git2Features: 'Threads, Ssh' LibGit2 features compiled with. string regex = @"^(?\d{1,}\.\d{1,2}\.\d{1,3}(-(pre|dev)\d{14})?)-(?\w+)-(?\w+) \((?\w+) - (?(?:\w*(?:, )*\w+)*)\)$"; @@ -38,7 +38,7 @@ public void CanRetrieveValidVersionString() Match regexResult = Regex.Match(versionInfo, regex); Assert.True(regexResult.Success, "The following version string format is enforced:" + - "Major.Minor.Patch[-preDateTime]-LibGit2Sharp_abbrev_hash-libgit2_abbrev_hash (x86|amd64 - features)"); + "Major.Minor.Patch[-preDateTime]-LibGit2Sharp_abbrev_hash-libgit2_abbrev_hash (x86|x64 - features)"); GroupCollection matchGroups = regexResult.Groups; diff --git a/LibGit2Sharp.Tests/ShadowCopyFixture.cs b/LibGit2Sharp.Tests/ShadowCopyFixture.cs index f394e987e..dd3fdbaab 100644 --- a/LibGit2Sharp.Tests/ShadowCopyFixture.cs +++ b/LibGit2Sharp.Tests/ShadowCopyFixture.cs @@ -59,14 +59,14 @@ public void CanProbeForNativeBinariesFromAShadowCopiedAssembly() if (!Constants.IsRunningOnUnix) { - // ...that this cache doesn't contain the `NativeBinaries` folder + // ...that this cache doesn't contain the `lib` folder string cachedAssemblyParentPath = Path.GetDirectoryName(cachedAssemblyLocation); - Assert.False(Directory.Exists(Path.Combine(cachedAssemblyParentPath, "NativeBinaries"))); + Assert.False(Directory.Exists(Path.Combine(cachedAssemblyParentPath, "lib"))); - // ...whereas `NativeBinaries` of course exists next to the source assembly + // ...whereas `lib` of course exists next to the source assembly string sourceAssemblyParentPath = Path.GetDirectoryName(new Uri(sourceAssembly.EscapedCodeBase).LocalPath); - Assert.True(Directory.Exists(Path.Combine(sourceAssemblyParentPath, "NativeBinaries"))); + Assert.True(Directory.Exists(Path.Combine(sourceAssemblyParentPath, "lib"))); } AppDomain.Unload(domain); diff --git a/LibGit2Sharp/Core/GitMergeOpts.cs b/LibGit2Sharp/Core/GitMergeOpts.cs index 59a9040df..48675a2d0 100644 --- a/LibGit2Sharp/Core/GitMergeOpts.cs +++ b/LibGit2Sharp/Core/GitMergeOpts.cs @@ -35,6 +35,12 @@ internal struct GitMergeOpts /// public uint RecursionLimit; + /// + /// Default merge driver to be used when both sides of a merge have + /// changed. The default is the `text` driver. + /// + public string DefaultDriver; + /// /// Flags for automerging content. /// diff --git a/LibGit2Sharp/Core/GitWriteStream.cs b/LibGit2Sharp/Core/GitWriteStream.cs index 6739fd32e..a53e7bd74 100644 --- a/LibGit2Sharp/Core/GitWriteStream.cs +++ b/LibGit2Sharp/Core/GitWriteStream.cs @@ -4,7 +4,7 @@ namespace LibGit2Sharp.Core { [StructLayout(LayoutKind.Sequential)] - internal class GitWriteStream + internal struct GitWriteStream { [MarshalAs(UnmanagedType.FunctionPtr)] public write_fn write; diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index 326e8997e..3e2f8825c 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -126,6 +126,17 @@ internal delegate int source_callback( int max_length, IntPtr data); + [DllImport(libgit2)] + internal static extern unsafe int git_blob_create_fromstream( + out IntPtr stream, + git_repository* repositoryPtr, + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictFilePathMarshaler))] FilePath hintpath); + + [DllImport(libgit2)] + internal static extern unsafe int git_blob_create_fromstream_commit( + ref GitOid oid, + IntPtr stream); + [DllImport(libgit2)] internal static extern unsafe int git_blob_create_fromchunks( ref GitOid oid, diff --git a/LibGit2Sharp/Core/Platform.cs b/LibGit2Sharp/Core/Platform.cs index d18613d29..1f43b6a24 100644 --- a/LibGit2Sharp/Core/Platform.cs +++ b/LibGit2Sharp/Core/Platform.cs @@ -13,7 +13,7 @@ internal static class Platform { public static string ProcessorArchitecture { - get { return Environment.Is64BitProcess ? "amd64" : "x86"; } + get { return Environment.Is64BitProcess ? "x64" : "x86"; } } public static OperatingSystemType OperatingSystem diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index 698dad7a4..b89e7d5ae 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -115,18 +115,18 @@ public static unsafe BlameHandle git_blame_file( #region git_blob_ - public static unsafe ObjectId git_blob_create_fromchunks(RepositoryHandle repo, FilePath hintpath, NativeMethods.source_callback fileCallback) + public static unsafe IntPtr git_blob_create_fromstream(RepositoryHandle repo, FilePath hintpath) { - var oid = new GitOid(); - int res = NativeMethods.git_blob_create_fromchunks(ref oid, repo, hintpath, fileCallback, IntPtr.Zero); - - if (res == (int)GitErrorCode.User) - { - throw new EndOfStreamException("The stream ended unexpectedly"); - } + IntPtr writestream_ptr; - Ensure.ZeroResult(res); + Ensure.ZeroResult(NativeMethods.git_blob_create_fromstream(out writestream_ptr, repo, hintpath)); + return writestream_ptr; + } + public static unsafe ObjectId git_blob_create_fromstream_commit(IntPtr writestream_ptr) + { + var oid = new GitOid(); + Ensure.ZeroResult(NativeMethods.git_blob_create_fromstream_commit(ref oid, writestream_ptr)); return oid; } diff --git a/LibGit2Sharp/Filter.cs b/LibGit2Sharp/Filter.cs index b66889a12..050d4a83c 100644 --- a/LibGit2Sharp/Filter.cs +++ b/LibGit2Sharp/Filter.cs @@ -261,8 +261,7 @@ int StreamCreateCallback(out IntPtr git_writestream_out, GitFilter self, IntPtr Marshal.StructureToPtr(state.thisStream, state.thisPtr, false); state.nextPtr = git_writestream_next; - state.nextStream = new GitWriteStream(); - Marshal.PtrToStructure(state.nextPtr, state.nextStream); + state.nextStream = (GitWriteStream)Marshal.PtrToStructure(state.nextPtr, typeof(GitWriteStream)); state.filterSource = FilterSource.FromNativePtr(filterSourcePtr); state.output = new WriteStream(state.nextStream, state.nextPtr); diff --git a/LibGit2Sharp/GlobalSettings.cs b/LibGit2Sharp/GlobalSettings.cs index 1a52089d7..a514caf04 100644 --- a/LibGit2Sharp/GlobalSettings.cs +++ b/LibGit2Sharp/GlobalSettings.cs @@ -24,7 +24,7 @@ static GlobalSettings() if (Platform.OperatingSystem == OperatingSystemType.Windows) { string managedPath = new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath; - nativeLibraryPath = Path.Combine(Path.GetDirectoryName(managedPath), "NativeBinaries"); + nativeLibraryPath = Path.Combine(Path.Combine(Path.GetDirectoryName(managedPath), "lib"), "win32"); } registeredFilters = new Dictionary(); @@ -129,10 +129,10 @@ public static LogConfiguration LogConfiguration /// /// Sets a hint path for searching for native binaries: when /// specified, native binaries will first be searched in a - /// subdirectory of the given path corresponding to the architecture - /// (eg, "x86" or "amd64") before falling back to the default - /// path ("NativeBinaries\x86" or "NativeBinaries\amd64" next - /// to the application). + /// subdirectory of the given path corresponding to the operating + /// system and architecture (eg, "x86" or "x64") before falling + /// back to the default path ("lib\win32\x86" or "lib\win32\x64" + /// next to the application). /// /// This must be set before any other calls to the library, /// and is not available on Unix platforms: see your dynamic diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index bd3ef3b15..067eaf844 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -1,6 +1,6 @@ - + - + Debug AnyCPU @@ -79,8 +79,8 @@ - + @@ -381,7 +381,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + - - - + diff --git a/LibGit2Sharp/ObjectDatabase.cs b/LibGit2Sharp/ObjectDatabase.cs index 3705ec5e5..aac0c7646 100644 --- a/LibGit2Sharp/ObjectDatabase.cs +++ b/LibGit2Sharp/ObjectDatabase.cs @@ -213,7 +213,7 @@ public virtual Blob CreateBlob(Stream stream, string hintpath, long numberOfByte return CreateBlob(stream, hintpath, (long?)numberOfBytesToConsume); } - private Blob CreateBlob(Stream stream, string hintpath, long? numberOfBytesToConsume) + private unsafe Blob CreateBlob(Stream stream, string hintpath, long? numberOfBytesToConsume) { Ensure.ArgumentNotNull(stream, "stream"); @@ -228,9 +228,51 @@ private Blob CreateBlob(Stream stream, string hintpath, long? numberOfBytesToCon throw new ArgumentException("The stream cannot be read from.", "stream"); } - var proc = new Processor(stream, numberOfBytesToConsume); - ObjectId id = Proxy.git_blob_create_fromchunks(repo.Handle, hintpath, proc.Provider); + IntPtr writestream_ptr = Proxy.git_blob_create_fromstream(repo.Handle, hintpath); + GitWriteStream writestream = (GitWriteStream)Marshal.PtrToStructure(writestream_ptr, typeof(GitWriteStream)); + try + { + var buffer = new byte[4 * 1024]; + long totalRead = 0; + int read = 0; + + while (true) + { + int toRead = numberOfBytesToConsume.HasValue ? + (int)Math.Min(numberOfBytesToConsume.Value - totalRead, (long)buffer.Length) : + buffer.Length; + + if (toRead > 0) + { + read = (toRead > 0) ? stream.Read(buffer, 0, toRead) : 0; + } + + if (read == 0) + { + break; + } + + fixed (byte* buffer_ptr = buffer) + { + writestream.write(writestream_ptr, (IntPtr)buffer_ptr, (UIntPtr)read); + } + + totalRead += read; + } + + if (numberOfBytesToConsume.HasValue && totalRead < numberOfBytesToConsume.Value) + { + throw new EndOfStreamException("The stream ended unexpectedly"); + } + } + catch(Exception e) + { + writestream.free(writestream_ptr); + throw e; + } + + ObjectId id = Proxy.git_blob_create_fromstream_commit(writestream_ptr); return repo.Lookup(id); } diff --git a/LibGit2Sharp/Version.cs b/LibGit2Sharp/Version.cs index 4a155dcba..b4cbd88f0 100644 --- a/LibGit2Sharp/Version.cs +++ b/LibGit2Sharp/Version.cs @@ -77,7 +77,7 @@ private string RetrieveAbbrevShaFrom(string name) /// /// /// The format of the version number is as follows: - /// Major.Minor.Patch-LibGit2Sharp_abbrev_hash-libgit2_abbrev_hash (x86|amd64 - features) + /// Major.Minor.Patch-LibGit2Sharp_abbrev_hash-libgit2_abbrev_hash (x86|x64 - features) /// /// public override string ToString() diff --git a/LibGit2Sharp/packages.config b/LibGit2Sharp/packages.config index ba1f583dc..669c5e8bf 100644 --- a/LibGit2Sharp/packages.config +++ b/LibGit2Sharp/packages.config @@ -1,4 +1,4 @@  - +