private ReadOnlyMemory <GitPack> LoadPacks() { var packDirectory = Path.Combine(this.ObjectDirectory, "pack/"); if (!Directory.Exists(packDirectory)) { return(Array.Empty <GitPack>()); } var indexFiles = Directory.GetFiles(packDirectory, "*.idx"); var packs = new GitPack[indexFiles.Length]; int addCount = 0; for (int i = 0; i < indexFiles.Length; i++) { var name = Path.GetFileNameWithoutExtension(indexFiles[i]); var indexPath = Path.Combine(this.ObjectDirectory, "pack", $"{name}.idx"); var packPath = Path.Combine(this.ObjectDirectory, "pack", $"{name}.pack"); // Only proceed if both the packfile and index file exist. if (File.Exists(packPath)) { packs[addCount++] = new GitPack(this.GetObjectBySha, indexPath, packPath); } } return(packs.AsMemory(0, addCount)); }
private GitPack[] LoadPacks() { var packDirectory = Path.Combine(this.ObjectDirectory, "pack/"); if (!Directory.Exists(packDirectory)) { return(Array.Empty <GitPack>()); } var indexFiles = Directory.GetFiles(packDirectory, "*.idx"); GitPack[] packs = new GitPack[indexFiles.Length]; for (int i = 0; i < indexFiles.Length; i++) { var name = Path.GetFileNameWithoutExtension(indexFiles[i]); packs[i] = new GitPack(this, name); } return(packs); }
public static Stream GetObject(GitPack pack, Stream stream, long offset, string objectType, GitPackObjectType packObjectType) { if (pack is null) { throw new ArgumentNullException(nameof(pack)); } if (stream is null) { throw new ArgumentNullException(nameof(stream)); } // Read the signature #if DEBUG stream.Seek(0, SeekOrigin.Begin); Span <byte> buffer = stackalloc byte[12]; stream.ReadAll(buffer); Debug.Assert(buffer.Slice(0, 4).SequenceEqual(Signature)); var versionNumber = BinaryPrimitives.ReadInt32BigEndian(buffer.Slice(4, 4)); Debug.Assert(versionNumber == 2); var numberOfObjects = BinaryPrimitives.ReadInt32BigEndian(buffer.Slice(8, 4)); #endif stream.Seek(offset, SeekOrigin.Begin); var(type, decompressedSize) = ReadObjectHeader(stream); if (type == GitPackObjectType.OBJ_OFS_DELTA) { var baseObjectRelativeOffset = ReadVariableLengthInteger(stream); long baseObjectOffset = offset - baseObjectRelativeOffset; var deltaStream = new ZLibStream(stream, decompressedSize); var baseObjectStream = pack.GetObject(baseObjectOffset, objectType); return(new GitPackDeltafiedStream(baseObjectStream, deltaStream)); } else if (type == GitPackObjectType.OBJ_REF_DELTA) { Span <byte> baseObjectId = stackalloc byte[20]; stream.ReadAll(baseObjectId); Stream baseObject = pack.GetObjectFromRepository(GitObjectId.Parse(baseObjectId), objectType) !; var seekableBaseObject = new GitPackMemoryCacheStream(baseObject); var deltaStream = new ZLibStream(stream, decompressedSize); return(new GitPackDeltafiedStream(seekableBaseObject, deltaStream)); } // Tips for handling deltas: https://github.com/choffmeister/gitnet/blob/4d907623d5ce2d79a8875aee82e718c12a8aad0b/src/GitNet/GitPack.cs if (type != packObjectType) { throw new GitException($"An object of type {objectType} could not be located at offset {offset}.") { ErrorCode = GitException.ErrorCodes.ObjectNotFound }; } return(new ZLibStream(stream, decompressedSize)); }