Example #1
0
        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);
        }
Example #3
0
        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));
        }