{"thread":{"id":"5142","subject":"Git files data formats documentation","startedAt":"2006-08-05T05:39:25Z","lastAt":"2006-08-16T16:55:23Z","messageCount":13,"participants":["A Large Angry SCM","Jon Smirl","Junio C Hamano","Shawn Pearce","Jakub Narebski","Nicolas Pitre"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"24797","messageId":"44D42F0D.3040707@gmail.com","threadId":"5142","inReplyTo":null,"subject":"Git files data formats documentation","fromName":"A Large Angry SCM","fromEmail":"gitzilla@gmail.com","sentAt":"2006-08-05T05:39:25Z","receivedAt":"2006-08-05T05:39:25Z","isPatch":false,"sender":{"key":"gitzilla@gmail.com","avatar":"https://gravatar.com/avatar/354625c442439908ff3dd99757dee330e29e9df7847472384faf7a00add247fb?d=mp&s=160"},"body":"This information may be useful for reading and writing the various Git \nfiles.\n\n\nGit files data formats\n======================\n\nOBJECTS\n-------\n# The object ID, or \"name\", of an object is\n#\t_sha-1_digest_( <OBJECT_HEADER> <object_CONTENTS> ).\n\n<BLOB>\n\t:\t_deflate_( <OBJECT_HEADER> <BLOB_CONTENTS> )\n\t|\t<COMPACT_OBJECT_HEADER> _deflate_( <BLOB_CONTENTS> )\n\t;\n\n<BLOB_CONTENTS>\n\t:\t<DATA>\n\t;\n\n<TREE>\n\t:\t_deflate_( <OBJECT_HEADER> <TREE_CONTENTS> )\n\t|\t<COMPACT_OBJECT_HEADER> _deflate_( <TREE_CONTENTS> )\n\t;\n\n<TREE_CONTENTS>\n\t:\t<TREE_ENTRIES>\n\t;\n\n<TREE_ENTRIES>\n\t# Tree entries are sorted by the byte sequence that comprises\n\t# the entry name.\n\t:\t( <TREE_ENTRY> )*\n\t;\n\n<TREE_ENTRY>\n\t# The type of the object referenced MUST be appropriate for\n\t# the mode. Regular files and symbolic links reference a BLOB\n\t# and directories reference a TREE.\n\t:\t<OCTAL_MODE> <SP> <NAME> <NUL> <BINARY_OBJ_ID>\n\t;\n\n<COMMIT>\n\t:\t_deflate_( <OBJECT_HEADER> <COMMIT_CONTENTS> )\n\t|\t<COMPACT_OBJECT_HEADER> _deflate_( <COMMIT_CONTENTS> )\n\t;\n\n<COMMIT_CONTENTS>\n\t:\t\"tree\" <SP> <HEX_OBJ_ID> <LF>\n\t\t( \"parent\" <SP> <HEX_OBJ_ID> <LF> )*\n\t\t\"author\" <SP>\n\t\t\t<SAFE_NAME> <SP>\n\t\t\t<LT> <SAFE_EMAIL> <GT> <SP>\n\t\t\t<GIT_DATE> <LF>\n\t\t\"committer\" <SP>\n\t\t\t<SAFE_NAME> <SP>\n\t\t\t<LT> <SAFE_EMAIL> <GT> <SP>\n\t\t\t<GIT_DATE> <LF>\n\t\t<LF>\n\t\t<DATA>\n\t;\n\n<TAG>\n\t:\t_deflate_( <OBJECT_HEADER> <TAG_CONTENTS> )\n\t|\t<COMPACT_OBJECT_HEADER> _deflate_( <TAG_CONTENTS> )\n\t;\n\n<TAG_CONTENTS>\n\t:\t\"object\" <SP> <HEX_OBJ_ID> <LF>\n\t\t\"type\" <SP> <NONTAG_OBJ_TYPE> <LF>\n\t\t\"tag\" <SP> <TAG_NAME> <LF>\n\t\t<LF>\n\t\t<DATA>\n\t;\n\n<OBJECT_HEADER>\n\t:\t<OBJ_TYPE> <SP> <DECIMAL_LENGTH> <NUL>\n\t;\n\n<COMPACT_OBJECT_HEADER>\n\t# The object type DELTA_ENCODED is not valid in a\n\t# <COMPACT_OBJECT_HEADER>.\n\t:\t<TYPE_AND_BASE128_SIZE>\n\t;\n\n<DATA>\n\t# Uninterpreted sequence of bytes.\n\t;\n\n<OCTAL_MODE>\n\t# Octal encoding, without prefix, of the file system object\n\t# type and permission bits. The bit layout is according to the\n\t# POSIX standard, with only regular files, directories, and\n\t# symbolic links permitted. The actual permission bits are\n\t# all zero except for regular files. The only permission bit\n\t# of any consequence to Git is the owner executable bit. By\n\t# default, the permission bits for files will be either 0644\n\t# or 0755, depending on the owner executable bit.\n\t;\n\n<NAME>\n\t# Sequence of bytes not containing the ASCII character byte\n\t# value NUL (0x00).\n\t;\n\n<BINARY_OBJ_ID>\n\t# The object ID of the referenced object.\n\t;\n\n<HEX_OBJ_ID>\n\t# Hexidecimal encoding (lower case) of the <BINARY_OBJ_ID>.\n\t;\n\n<SAFE_NAME>\n\t:\t<SAFE_STRING> \n\t;\n\n<SAFE_EMAIL>\n\t:\t<SAFE_STRING>\n\t;\n\n<SAFE_STRING>\n\t# A sequence of bytes not containing the ASCII character byte\n\t# values NUL (0x00), LF (0x0a), '<' (0c3c), or '>' (0x3e).\n\t#\n\t# The sequence may not begin or end with any bytes with the\n\t# following ASCII character byte values: SPACE (0x20),\n\t# '.' (0x2e), ',' (0x2c), ':' (0x3a), ';' (0x3b), '<' (0x3c),\n\t# '>' (0x3e), '\"' (0x22), \"'\" (0x27).\n\t;\n\n<GIT_DATE>\n\t:\t<SECONDS> <SP> <TZ_OFFSET>\n\t;\n\n<SECONDS>\n\t# Base 10, ASCII encoding of the number of seconds since 12:00\n\t# midnight January 1, 1970, UTC without accounting for leap\n\t# seconds, and without leading zeros.\n\t;\n\n<TZ_OFFSET>\n\t# Signed offset of time zone from UTC.\n\t:\t<TZ_OFFSET_SIGN> <TZ_OFFSET_HOURS> <TZ_OFFSET_MIN>\n\t;\n\n<TZ_OFFSET_SIGN>\n\t:\t\"+\"\n\t|\t\"-\"\n\t;\n\n<TZ_OFFSET_HOURS>\n\t:\t<DIGIT> <DIGIT>\n\t;\n\n<TZ_OFFSET_MIN>\n\t# Valid values are \"00\" to \"59\" inclusive.\n\t:\t<DIGIT> <DIGIT>\n\t;\n\n<DIGIT>\n\t# ASCII decimal digit.\n\t;\n\n<NONTAG_OBJ_TYPE>\n\t:\t\"BLOB\"\n\t|\t\"TREE\"\n\t|\t\"COMMIT\"\n\t;\n\n<OBJ_TYPE>\n\t:\t<NONTAG_OBJ_TYPE>\n\t|\t\"TAG\"\n\t;\n\n<DECIMAL_LENGTH>\n\t# Base 10, ASCII encoding of the byte length of the object\n\t# contents, without leading zeros. The length value does not\n\t# include the length of the <OBJECT_HEADER>.\n\t:\t( <DIGIT> )+\n\t;\n\n<SP>\n\t# ASCII SPACE (0x20) character.\n\t;\n\n<NUL>\n\t# ASCII NUL (0x00) character.\n\t;\n\n<LF>\n\t# ASCII LF (0x0a) \"line feed\" character.\n\t;\n\n\nPACK FILE\n---------\n# The name of a pack file is \"pack-${PACK_ID}.pack\", where ${PACK_ID}\n# is the hexidecimal encoding (lower case) of the SHA-1 digest of the\n# sorted list of binary object IDs in the pack file without a separator\n# between the object IDs. Initially, the ${PACK_ID} for a pack was not\n# defined, making the value effectively random.\n\n<PACK_FILE>\n\t:\t<PACK_FILE_CONTENTS> <PACK_FILE_CHECKSUM>\n\t;\n\n<PACK_FILE_CONTENTS>\n\t:\t\"PACK\" <PACK_VERSION> <PACK_OBJECT_COUNT>\n\t\t( <PACKED_OBJECT_HEADER> <PACKED_OBJECT_DATA> )*\n\t\t<PACK_FILE_CHECKSUM>\n\t;\n\n<PACK_VERSION>\n\t# 32 bit, network byte order, binary integer indicating which\n\t# version of the pack file format was used to create the pack\n\t# file.\n\t;\n\n<PACK_OBJECT_COUNT>\n\t# 32 bit, network byte order, binary integer containg the\n\t# number of objects encoded in the pack file.\n\t;\n\n<PACK_FILE_CHECKSUM>\n\t:\t_sha-1_digest_( <PACK_FILE_CONTENTS> )\n\t;\n\n\n<PACKED_OBJECT_HEADER>\n\t# If the object type is not a DELTA_ENCODED object, the packed\n\t# object data that follows is the deflated byte sequence of the\n\t# object without the Git object header. The length value is the\n\t# byte count of the inflated byte sequence of the object.\n\t#\n\t# If the object type is a DELTA_ENCODED object, what follows is\n\t# the ID of the base object and the deflated delta data to\n\t# transform the base object into the target object. The type of\n\t# the target object is the same as that of the base object and\n\t# the length value is the byte count of the inflated delta\n\t# data. The base object may also be DELTA_ENCODED but cyclic\n\t# base object chains are not permitted and the pack file MUST\n\t# contain all base objects.\n\t:\t<TYPE_AND_BASE128_SIZE>\n\t;\n\n<TYPE_AND_BASE128_SIZE>\n\t# A compact, variable length, encoding of the packed object\n\t# length and type. The first byte is comprised of 3 fields\n\t# (where bit 0 is the least significant bit in a byte):\n\t#\tbit 7:\t\tmore flag\n\t#\tbits 6-4:\tobject type\n\t#\tbits 3-0:\tleast significant bits of the object\n\t#\t\t\tlength.\n\t# If the more flag is set, the next byte contains more object\n\t# length bits.\n\t# The object types corresponding to the object type bits are:\n\t#\t6 5 4\n\t#\t- - -\n\t#\t0 0 0\tinvalid: Reserved\n\t#\t0 0 1\tCOMMIT object\n\t#\t0 1 0\tTREE object\n\t#\t0 1 1\tBLOB object\n\t#\t1 0 0\tTAG object\n\t#\t1 0 1\tinvalid: Reserved\n\t#\t1 1 0\tinvalid: Reserved\n\t#\t1 1 1\tDELTA_ENCODED object\n\t#\n\t# If the more flag was set, the next byte will have more length\n\t# bits and will be comprised to 2 fields:\n\t#\tbit 7:\t\tmore flag\n\t#\tbits 6-0:\t7 additional, more significant, bits of\n\t#\t\t\tthe object length\n\t# If the more flag is set, the next byte contains more object\n\t# length bits using the same encoding.\n\t;\n\n<PACKED_OBJECT_DATA>\n\t:\t_deflate_( <DATA> )\n\t|\t<BINARY_OBJ_ID> _deflate_( <DELTA_DATA> )\n\t;\n\n<DELTA_DATA>\n\t# Size of the base object encoded as a base 128 number, least\n\t# significant bits first, using bit 7 (the most significant\n\t# bit) of each byte to indicate that more bits follow.\n\t#\n\t# Size of the result object encoded as a base 128 number, using\n\t# the same method as used for the base object size.\n\t#\n\t# There will then be a sequence of delta hunks.\n\t# Zero as the value of the first byte of a hunk in reserved.\n\t#\n\t# If bit 7 of the first byte of a delta hunk is not set, the\n\t# hunk is an \"insert\" hunk and bits 0-6 specify the number of\n\t# bytes to append to the output buffer from the hunk.\n\t#\n\t# If bit 7 of the first byte of a delta hunk is set, the hunk\n\t# is a \"copy\" hunk and bits 0-6 specify how the remaining\n\t# bytes in the hunk make up the base offset and length for the\n\t# copy. The following C code demonstrate how to determine the\n\t# base offset and length for the copy:\n\t#\n\t#\t/* -  -  -  -  -  -  -  -  -  -  -  - *\\\n\t#\t | This reflects version 3 pack files |\n\t#\t\\* -  -  -  -  -  -  -  -  -  -  -  - */\n\t#\n\t#\tbyte *data = delta_hunk_start\n\t#\topcode = *data++\n\t#\toff_t copy_offset= 0;\n\t#\tsize_t copy_length = 0;\n\t#\n\t#\tfor (shift=i=0; i<4; i++) {\n\t#\t\tif (opcode & 0x01) {\n\t#\t\t\tcopy_offset |= (*data++)<<shift;\n\t#\t\t\t}\n\t#\t\topcode >>= 1;\n\t#\t\tshift += 8;\n\t#\t\t}\n\t#\n\t#\tfor (shift=i=0; i<3; i++) {\n\t#\t\tif (opcode & 0x01) {\n\t#\t\t\tcopy_length |= (*data++)<<shift;\n\t#\t\t\t}\n\t#\t\topcode >>= 1;\n\t#\t\tshift += 8;\n\t#\t\t}\n\t#\n\t#\tif (!copy_length) {\n\t#\t\tcopy_length = 1<<16;\n\t#\t\t}\n\t#\n\t# For version 2 pack files, the size of a copy is limited to\n\t# 64K bytes or less and bit 6 of the opcode byte is set if the\n\t# source of the copy is from the buffer of the result object\n\t# instead of the the base object.\n\t#\n\t# It's unknown if any version 2 pack files were created with\n\t# bit 6 set in the opcode byte; however, the change that added\n\t# support for version 3 pack files removed the code that would\n\t# change the copy source to the result buffer.\n\t#\n\t#\t/* -  -  -  -  -  -  -  -  -  -  -  - *\\\n\t#\t | This reflects version 2 pack files |\n\t#\t\\* -  -  -  -  -  -  -  -  -  -  -  - */\n\t#\n\t#\tbyte *data = delta_hunk_start\n\t#\topcode = *data++\n\t#\toff_t copy_offset= 0;\n\t#\tsize_t copy_length = 0;\n\t#\n\t#\tfor (shift=i=0; i<4; i++) {\n\t#\t\tif (opcode & 0x01) {\n\t#\t\t\tcopy_offset |= (*data++)<<shift;\n\t#\t\t\t}\n\t#\t\topcode >>= 1;\n\t#\t\tshift += 8;\n\t#\t\t}\n\t#\n\t#\tfor (shift=i=0; i<2; i++) {\n\t#\t\tif (opcode & 0x01) {\n\t#\t\t\tcopy_length |= (*data++)<<shift;\n\t#\t\t\t}\n\t#\t\topcode >>= 1;\n\t#\t\tshift += 8;\n\t#\t\t}\n\t#\n\t#\tif (!copy_length) {\n\t#\t\tcopy_length = 1<<16;\n\t#\t\t}\n\t#\n\t#\tcopy_from_result = opcode & 0x01\n\t#\n\t;\n\n\nPACK INDEX\n----------\n# The name of a pack file index is \"pack-${PACK_ID}.idx\", where\n# ${PACK_ID} is the hexidecimal encoding (lower case) of the SHA-1\n# digest of the sorted list of binary object IDs in the pack file\n# without a separator between the object IDs. Initially, the ${PACK_ID}\n# for a pack was not defined, making the value effectively random.\n\n<PACK_INDEX>\n\t:\t<PACK_INDEX_CONTENTS> <PACK_INDEX_CHECKSUM>\n\t;\n\n<PACK_INDEX_CONTENTS>\n\t:\t( <INDEX_PARTIAL_COUNT> ){256}\n\t\t( <PACK_OBJECT_OFFSET> <BINARY_OBJ_ID> )*\n\t\t<PACK_FILE_CHECKSUM>\n\t;\n\n<INDEX_PARTIAL_COUNT>\n\t# 32 bit, network byte order, binary integer of the count of\n\t# objects in the pack file with the first byte of the object\n\t# ID less than or equal to the index of the count, starting\n\t# from zero.\n\t;\n\n<PACK_OBJECT_OFFSET>\n\t# 32 bit, network byte order, binary integer giving the offset,\n\t# in bytes from the begining of the pack file, where the\n\t# encoding of the object starts.\n\t;\n\n<PACK_INDEX_CHECKSUM>\n\t:\t_sha-1_digest_( <PACK_INDEX_CONTENTS> )\n\t;\n\n\nINDEX FILE (CACHE)\n------------------\n\n<INDEX_FILE>\n\t:\t<INDEX_FILE_FORMAT_V1>\n\t|\t<INDEX_FILE_FORMAT_V2>\n\t;\n\n<INDEX_FILE_FORMAT_V1>\n\t# This format is no longer supported.\n\t:\t<INDEX_HEADER> <INDEX_CHECKSUM> <INDEX_CONTENTS>\n\t;\n\n<INDEX_FILE_FORMAT_V2>\n\t:\t<INDEX_HEADER> <EXTENDED_INDEX_CONTENTS> <EXTENED_CHECKSUM>\n\t;\n\n<INDEX_HEADER>\n\t:\t\"DIRC\" <INDEX_FILE_VERSION> <INDEX_ENTRY_COUNT>\n\t;\n\n<INDEX_FILE_VERSION>\n\t# 32 bit, network byte order, binary integer indicating which\n\t# version of the index file format was used to create the\n\t# index file.\n\t;\n\n<INDEX_ENTRY_COUNT>\n\t# 32 bit, network byte order, binary integer containg the\n\t# number of index entries in the index file.\n\t;\n\n<EXTENDED_CHECKSUM>\n\t:\t_sha-1_digest_( <EXTENDED_INDEX_CONTENTS> )\n\t;\n\n<INDEX_CHECKSUM>\n\t:\t_sha-1_digest_( <INDEX_CONTENTS> )\n\t;\n\n<INDEX_CONTENTS>\n\t:\t( <INDEX_ENTRY> )*\n\t;\n\n<EXTENDED_INDEX_CONTENTS>\n\t:\t<INDEX_CONTENTS> <INDEX_CONTENTS_EXTENSIONS>\n\t;\n\n<INDEX_ENTRY>\n\t:\t<INDEX_ENTRY_STAT_INFO>\n\t\t<ENTRY_ID>\n\t\t<ENTRY_FLAGS>\n\t\t<ENTRY_NAME>\n\t;\n\n<INDEX_ENTRY_STAT_INFO>\n\t# These fields are used as a part of a heuristic to determine\n\t# if the file system entity associated with this entry has\n\t# changed. The names are very *nix centric but the exact\n\t# contents of each field have no meaning to Git, besides exact\n\t# match, except for the <ENTRY_MODE> and <ENTRY_SIZE> fields.\n\t:\t<ENTRY_CTIME>\n\t\t<ENTRY_MTIME>\n\t\t<ENTRY_DEV>\n\t\t<ENTRY_INODE>\n\t\t<ENTRY_MODE>\n\t\t<ENTRY_UID>\n\t\t<ENTRY_GID>\n\t\t<ENTRY_SIZE>\n\t;\n\n<ENTRY_CTIME>\n\t# The timestamp of the last status change of the associated\n\t# file system entity.\n\t:\t<ENTRY_TIME>\n\t;\n\n<ENTRY_MTIME>\n\t# The timestamp of the last modification of the associated\n\t# file system entity.\n\t:\t<ENTRY_TIME>\n\t;\n\n<ENTRY_TIME>\n\t:\t<TIME_LSB32> <TIME_NSEC>\n\t;\n\n<TIME_LSB32>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) timestamp.\n\t;\n\n<TIME_NSEC>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) more precise\n\t# timestamp, if available.\n\t;\n\n<ENTRY_DEV>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) file system\n\t# device identifier. Use of this field is a compile time\n\t# option.\n\t;\n\n<ENTRY_INODE>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) inode number, or\n\t# equivalent.\n\t;\n\n<ENTRY_MODE>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) file system\n\t# entity type and permissions.\n\t;\n\n<ENTRY_UID>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) file system\n\t# entity owner identifier.\n\t;\n\n<ENTRY_GID>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) file system\n\t# entity group identifier, or equivalent.\n\t;\n\n<ENTRY_SIZE>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) size.\n\t;\n\n<ENTRY_ID>\n\t# Object ID of the of the file system entity contents.\n\t;\n\n<ENTRY_FLAGS>\n\t# 16 bit, network byte order, binary integer.\n\t#\tbits 15-14\tReserved\n\t#\tbits 13-12\tEntry stage\n\t#\tbits 11-0\tName byte length\n\t#\n\t# See git-read-tree(1) for a description of how the stage\n\t# field is used.\n\t;\n\n<ENTRY_NAME>\n\t# File system entity name. Path is normalized and relative to\n\t# the working directory.\n\t;\n\n<INDEX_CONTENTS_EXTENSIONS>\n\t:\t( <INDEX_EXTENSION> )*\n\t;\n\n<INDEX_EXTENSION>\n\t:\t<INDEX_EXTENSION_HEADER>\n\t\t<INDEX_EXTENSION_DATA>\n\t;\n\n<INDEX_EXTENSION_HEADER>\n\t:\t<INDEX_EXTENSION_NAME> <INDEX_EXTENSION_DATA_SIZE>\n\t;\n\n<INDEX_EXTENSION_NAME>\n\t# 4 byte sequence identifying how the <INDEX_EXTENSION_DATA>\n\t# should be interpreted. The first byte having a value greater\n\t# than or equal to the ASCII character 'A' (0x41) and less than\n\t# or equal to the ASCII character 'Z' (0x5a).\n\t;\n\n<INDEX_EXTENSION_DATA_SIZE>\n\t# 32 bit, network byte order, binary integer containg the\n\t# length of the <INDEX_EXTENSION_DATA> byte sequence.\n\t;\n\n<INDEX_EXTENSION_DATA>\n\t# Sequence of bytes.\n\t;\n\n\n"},{"id":"24800","messageId":"9e4733910608042248s18443277j436298229ed5ec05@mail.gmail.com","threadId":"5142","inReplyTo":"44D42F0D.3040707@gmail.com","subject":"Re: Git files data formats documentation","fromName":"Jon Smirl","fromEmail":"jonsmirl@gmail.com","sentAt":"2006-08-05T05:48:23Z","receivedAt":"2006-08-05T05:48:23Z","isPatch":false,"sender":{"key":"jonsmirl@gmail.com","avatar":"https://gravatar.com/avatar/cff3bf5bfdfa6708b905712ff91f0f9b8aaca161659f38c02b787920d5d28b7e?d=mp&s=160"},"body":"You might make some notes about old format headers and new format ones\nand the use_legacy_headers flag.\n\nI started off looking at packs so I knew about TYPE_AND_BASE128_SIZE.\nNext I wanted to write objects so I looked at sha1_file.c. If you\ndon't look at the code closely write_binary_header() will lead you to\nbelieve that object files use TYPE_AND_BASE128_SIZE. It took me a\ncouple of hours to notice use_legacy_headers and discover that it\ndefaults to on.\n\nJon Smirl\njonsmirl@gmail.com\n"},{"id":"24802","messageId":"7vac6jfzem.fsf@assigned-by-dhcp.cox.net","threadId":"5142","inReplyTo":"44D42F0D.3040707@gmail.com","subject":"Re: Git files data formats documentation","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-05T06:51:45Z","receivedAt":"2006-08-05T06:51:45Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Good documentation, but some nitpicks are needed before it hits\nDocumentation/technical/ part of the source tree.\n\n> <TREE_ENTRIES>\n> \t# Tree entries are sorted by the byte sequence that comprises\n> \t# the entry name.\n> \t:\t( <TREE_ENTRY> )*\n> \t;\n\nNot quite.  An entry for a subtree is sorted as if a '/' is\nsuffixed to its name.\n\n        $ git ls-tree $T\n        100644 blob 2398e9f8892812607f5eee6ed0d5712c2e3de197\ta-\n        100644 blob 7f07527a80bd8c2b1c5087d7ccfe61073b068374\ta-b\n        040000 tree 23fddf6a57ff3ba98aa93fb71431276c3f1a3c40\ta\n        100644 blob 2afe6dcc5466068b8dcc7263cece05d2adf044fe\ta=\n        100644 blob efc73add7dd868242a66faf2a59b145f2a60b834\ta=b\n\nThis is, by the way, consistent with the order of cache entries\nin the index file.\n\n        $ git ls-files -s\n        100644 2398e9f8892812607f5eee6ed0d5712c2e3de197 0\ta-\n        100644 7f07527a80bd8c2b1c5087d7ccfe61073b068374 0\ta-b\n        100644 0ee729686ab2a0074639c5f64930648571e7c4b2 0\ta/b\n        100644 2afe6dcc5466068b8dcc7263cece05d2adf044fe 0\ta=\n        100644 efc73add7dd868242a66faf2a59b145f2a60b834 0\ta=b\n\n> <TREE_ENTRY>\n> \t# The type of the object referenced MUST be appropriate for\n> \t# the mode. Regular files and symbolic links reference a BLOB\n> \t# and directories reference a TREE.\n> \t:\t<OCTAL_MODE> <SP> <NAME> <NUL> <BINARY_OBJ_ID>\n> \t;\n\nAs you correctly explain later, OCTAL_MODE must be minimal; \"git\nls-tree\" output says 040000 in the above example, but the actual\nobject records it as 40000.\n\n> <TAG_CONTENTS>\n> \t:\t\"object\" <SP> <HEX_OBJ_ID> <LF>\n> \t\t\"type\" <SP> <NONTAG_OBJ_TYPE> <LF>\n> \t\t\"tag\" <SP> <TAG_NAME> <LF>\n> \t\t<LF>\n> \t\t<DATA>\n> \t;\n\nA tag can tag another tag (think of chain of trust), so what\nfollows \"type\" does not have to be NONTAG_OBJ_TYPE.\n\n> <OCTAL_MODE>\n> \t# Octal encoding, without prefix, of the file system object\n> \t# type and permission bits. The bit layout is according to the\n> \t# POSIX standard, with only regular files, directories, and\n> \t# symbolic links permitted. The actual permission bits are\n> \t# all zero except for regular files. The only permission bit\n> \t# of any consequence to Git is the owner executable bit. By\n> \t# default, the permission bits for files will be either 0644\n> \t# or 0755, depending on the owner executable bit.\n> \t;\n\nIt's not really \"by default\" -- more like \"by definition\", since\nthere is no way for the program to use something different.  We\nused to record non-canonical modes in ancient versions of git,\nbut I think fsck-objects would warn on objects created that way.\n\n> <NONTAG_OBJ_TYPE>\n> \t:\t\"BLOB\"\n> \t|\t\"TREE\"\n> \t|\t\"COMMIT\"\n> \t;\n\nDrop this definition, and make the literals part of <OBJ_TYPE>,\nafter lowercasing them ;-).\n\n> <OBJ_TYPE>\n> \t:\t<NONTAG_OBJ_TYPE>\n> \t|\t\"TAG\"\n> \t;\n\n> PACK FILE\n> ---------\n> # The name of a pack file is \"pack-${PACK_ID}.pack\", where ${PACK_ID}\n> # is the hexidecimal encoding (lower case) of the SHA-1 digest of the\n> # sorted list of binary object IDs in the pack file without a separator\n> # between the object IDs. Initially, the ${PACK_ID} for a pack was not\n> # defined, making the value effectively random.\n\nAlthough the really core level does not care, a PACK_ID is\nrequired to be unique (within a object store and its alternates)\n40-byte hexadecimal for http commit walker to work properly.\n\nBTW, I still have a patch to tighten the check to enforce this\nas part of the consistency check.\n\n> <PACKED_OBJECT_DATA>\n> \t:\t_deflate_( <DATA> )\n> \t|\t<BINARY_OBJ_ID> _deflate_( <DELTA_DATA> )\n> \t;\n\nIt might be cleaner to separate this definition into two.  That\nis, one packed object is either non-delta-type base128 type-length\nfollowed by deflated data, or delta-type base128 type-length\nfollowed by base object id followed by deflated delta.\n\n> PACK INDEX\n> ----------\n> # The name of a pack file index is \"pack-${PACK_ID}.idx\", where\n> # ${PACK_ID} is the hexidecimal encoding (lower case) of the SHA-1\n> # digest of the sorted list of binary object IDs in the pack file\n> # without a separator between the object IDs. Initially, the ${PACK_ID}\n> # for a pack was not defined, making the value effectively random.\n\nI would not repeat \", where ${PACK_ID} is...\" part, which was\ndone in the description of the pack file.  Rather, \", where\n${PACK_ID} is same as the .pack file the .idx file corresponds\nto\", would be more appropriate.\n\n> <INDEX_PARTIAL_COUNT>\n> \t# 32 bit, network byte order, binary integer of the count of\n> \t# objects in the pack file with the first byte of the object\n> \t# ID less than or equal to the index of the count, starting\n> \t# from zero.\n> \t;\n\nLinus and I call this part \"fan-out\".\n\n> <ENTRY_NAME>\n> \t# File system entity name. Path is normalized and relative to\n> \t# the working directory.\n> \t;\n\nDid you mention that the index entries are sorted by name?\n\n> <INDEX_EXTENSION_NAME>\n> \t# 4 byte sequence identifying how the <INDEX_EXTENSION_DATA>\n> \t# should be interpreted. The first byte having a value greater\n> \t# than or equal to the ASCII character 'A' (0x41) and less than\n> \t# or equal to the ASCII character 'Z' (0x5a).\n> \t;\n\nThis is not true, but the code needs better comments.  The\nintention is that an extended section whose name starts with a\ncapital letter (such as \"cache-tree extension\" whose name is\n\"TREE\") is purely optional, and if a software of different\nversion does not understand it, it can still safely keep using\nthe rest of the index.  If somebody introduces a new extended\nsection that _must_ be interpreted in order to fully understand\nwhat the index file records, such an extended section can signal\nthat by having a name that do not start with a capital.  A\nversion of the software that does understand such extended\nsections would have a case arm that covers such a name in the\nswitch statement you took this 'A' .. 'Z' from.\n"},{"id":"24832","messageId":"20060805162233.GA19909@spearce.org","threadId":"5142","inReplyTo":"44D42F0D.3040707@gmail.com","subject":"Re: Git files data formats documentation","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-08-05T16:22:33Z","receivedAt":"2006-08-05T16:22:33Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"A Large Angry SCM <gitzilla@gmail.com> wrote:\n> This information may be useful for reading and writing the various Git \n> files.\n[snip]\n> \t#\t/* -  -  -  -  -  -  -  -  -  -  -  - *\\\n> \t#\t | This reflects version 3 pack files |\n> \t#\t\\* -  -  -  -  -  -  -  -  -  -  -  - */\n[snip]\n> \t#\t/* -  -  -  -  -  -  -  -  -  -  -  - *\\\n> \t#\t | This reflects version 2 pack files |\n> \t#\t\\* -  -  -  -  -  -  -  -  -  -  -  - */\n\nThanks for taking the time to write these out.  The pack delta\nformats were particularly helpful as it caused me to go back\nand look at the unpacking code in jgit.\n\nApparently I wasn't handling the version 2 pack file correctly as I\ndidn't support copy-from-result; I had an infinite loop if the base\ndidn't decompress in one read (never happen right now, but could\nin the future); and apparently my insert opcode implementation was\ncausing an infinite loop.  Nasty bugs.  I need to get more unit\ntests written apparently.  :-)\n\n\n-- \nShawn.\n"},{"id":"24834","messageId":"44D4D5DD.8070908@gmail.com","threadId":"5142","inReplyTo":"20060805162233.GA19909@spearce.org","subject":"Re: Git files data formats documentation","fromName":"A Large Angry SCM","fromEmail":"gitzilla@gmail.com","sentAt":"2006-08-05T17:31:09Z","receivedAt":"2006-08-05T17:31:09Z","isPatch":false,"sender":{"key":"gitzilla@gmail.com","avatar":"https://gravatar.com/avatar/354625c442439908ff3dd99757dee330e29e9df7847472384faf7a00add247fb?d=mp&s=160"},"body":"Shawn Pearce wrote:\n> A Large Angry SCM <gitzilla@gmail.com> wrote:\n>> This information may be useful for reading and writing the various Git \n>> files.\n> [snip]\n>> \t#\t/* -  -  -  -  -  -  -  -  -  -  -  - *\\\n>> \t#\t | This reflects version 3 pack files |\n>> \t#\t\\* -  -  -  -  -  -  -  -  -  -  -  - */\n> [snip]\n>> \t#\t/* -  -  -  -  -  -  -  -  -  -  -  - *\\\n>> \t#\t | This reflects version 2 pack files |\n>> \t#\t\\* -  -  -  -  -  -  -  -  -  -  -  - */\n> \n> Thanks for taking the time to write these out.  The pack delta\n> formats were particularly helpful as it caused me to go back\n> and look at the unpacking code in jgit.\n> \n> Apparently I wasn't handling the version 2 pack file correctly as I\n> didn't support copy-from-result; I had an infinite loop if the base\n> didn't decompress in one read (never happen right now, but could\n> in the future); and apparently my insert opcode implementation was\n> causing an infinite loop.  Nasty bugs.  I need to get more unit\n> tests written apparently.  :-)\n\nKeep in mind that the git-core code for reading version 2 or version 3 \npack files does _not_ handle copy-from-result correctly.\n"},{"id":"24836","messageId":"eb2onf$7up$1@sea.gmane.org","threadId":"5142","inReplyTo":"44D42F0D.3040707@gmail.com","subject":"Re: Git files data formats documentation","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-05T18:41:32Z","receivedAt":"2006-08-05T18:41:32Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"A Large Angry SCM wrote:\n\n> <TREE_ENTRY>\n>         # The type of the object referenced MUST be appropriate for\n>         # the mode. Regular files and symbolic links reference a BLOB\n>         # and directories reference a TREE.\n>         :       <OCTAL_MODE> <SP> <NAME> <NUL> <BINARY_OBJ_ID>\n>         ;\n[...]\n> <OCTAL_MODE>\n>         # Octal encoding, without prefix, of the file system object\n>         # type and permission bits. The bit layout is according to the\n>         # POSIX standard, with only regular files, directories, and\n>         # symbolic links permitted. The actual permission bits are\n>         # all zero except for regular files. The only permission bit\n>         # of any consequence to Git is the owner executable bit. By\n>         # default, the permission bits for files will be either 0644\n>         # or 0755, depending on the owner executable bit.\n>         ;\n\nI do wonder why there is <OCTAL_MODE> (and not <BINARY_OCTAL_MODE>) \nbut <BINARY_OBJ_ID> (and not <HEX_OBJ_ID>).\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"24838","messageId":"20060805193046.GA20565@spearce.org","threadId":"5142","inReplyTo":"7vac6jfzem.fsf@assigned-by-dhcp.cox.net","subject":"Re: Git files data formats documentation","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-08-05T19:30:46Z","receivedAt":"2006-08-05T19:30:46Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> Not quite.  An entry for a subtree is sorted as if a '/' is\n> suffixed to its name.\n> \n>         $ git ls-tree $T\n>         100644 blob 2398e9f8892812607f5eee6ed0d5712c2e3de197\ta-\n>         100644 blob 7f07527a80bd8c2b1c5087d7ccfe61073b068374\ta-b\n>         040000 tree 23fddf6a57ff3ba98aa93fb71431276c3f1a3c40\ta\n>         100644 blob 2afe6dcc5466068b8dcc7263cece05d2adf044fe\ta=\n>         100644 blob efc73add7dd868242a66faf2a59b145f2a60b834\ta=b\n> \n> This is, by the way, consistent with the order of cache entries\n> in the index file.\n\nArrrrgh.  I didn't realize that '/' was needed on the end of a tree\nname when sorting its parent for output.  jgit was/is definately\ndoing this wrong.  And it all comes back to how the index operates,\ndoesn't it?  :-)\n\nI've got to go back now and do some surgery on how jgit sorts\nentries in a tree.  Clearly it would be incorrect with the example\nyou just gave.  It also would have thought that core GIT generated\na corrupt tree if it tried to read in your example.  Thank you for\ntaking the time to clarify it!\n\n-- \nShawn.\n"},{"id":"24842","messageId":"44D4FC52.6030807@gmail.com","threadId":"5142","inReplyTo":"eb2onf$7up$1@sea.gmane.org","subject":"Re: Git files data formats documentation","fromName":"A Large Angry SCM","fromEmail":"gitzilla@gmail.com","sentAt":"2006-08-05T20:15:14Z","receivedAt":"2006-08-05T20:15:14Z","isPatch":false,"sender":{"key":"gitzilla@gmail.com","avatar":"https://gravatar.com/avatar/354625c442439908ff3dd99757dee330e29e9df7847472384faf7a00add247fb?d=mp&s=160"},"body":"Jakub Narebski wrote:\n> A Large Angry SCM wrote:\n> \n>> <TREE_ENTRY>\n>>         # The type of the object referenced MUST be appropriate for\n>>         # the mode. Regular files and symbolic links reference a BLOB\n>>         # and directories reference a TREE.\n>>         :       <OCTAL_MODE> <SP> <NAME> <NUL> <BINARY_OBJ_ID>\n>>         ;\n> [...]\n>> <OCTAL_MODE>\n>>         # Octal encoding, without prefix, of the file system object\n>>         # type and permission bits. The bit layout is according to the\n>>         # POSIX standard, with only regular files, directories, and\n>>         # symbolic links permitted. The actual permission bits are\n>>         # all zero except for regular files. The only permission bit\n>>         # of any consequence to Git is the owner executable bit. By\n>>         # default, the permission bits for files will be either 0644\n>>         # or 0755, depending on the owner executable bit.\n>>         ;\n> \n> I do wonder why there is <OCTAL_MODE> (and not <BINARY_OCTAL_MODE>) \n> but <BINARY_OBJ_ID> (and not <HEX_OBJ_ID>).\n> \n\n<OCTAL_MODE> because it's an ASCII string. <BINARY_OBJ_ID> because it's \nthe 20 byte digest.\n"},{"id":"24849","messageId":"44D5141A.2070004@gmail.com","threadId":"5142","inReplyTo":"7vac6jfzem.fsf@assigned-by-dhcp.cox.net","subject":"Re: Git files data formats documentation","fromName":"A Large Angry SCM","fromEmail":"gitzilla@gmail.com","sentAt":"2006-08-05T21:56:42Z","receivedAt":"2006-08-05T21:56:42Z","isPatch":false,"sender":{"key":"gitzilla@gmail.com","avatar":"https://gravatar.com/avatar/354625c442439908ff3dd99757dee330e29e9df7847472384faf7a00add247fb?d=mp&s=160"},"body":"Junio C Hamano wrote:\n...\n>> <OCTAL_MODE>\n>> \t# Octal encoding, without prefix, of the file system object\n>> \t# type and permission bits. The bit layout is according to the\n>> \t# POSIX standard, with only regular files, directories, and\n>> \t# symbolic links permitted. The actual permission bits are\n>> \t# all zero except for regular files. The only permission bit\n>> \t# of any consequence to Git is the owner executable bit. By\n>> \t# default, the permission bits for files will be either 0644\n>> \t# or 0755, depending on the owner executable bit.\n>> \t;\n> \n> It's not really \"by default\" -- more like \"by definition\", since\n> there is no way for the program to use something different.  We\n> used to record non-canonical modes in ancient versions of git,\n> but I think fsck-objects would warn on objects created that way.\n> \n\nSee git-mktree.\n"},{"id":"24850","messageId":"44D51D47.9090700@gmail.com","threadId":"5142","inReplyTo":"44D42F0D.3040707@gmail.com","subject":"Re: Git files data formats documentation","fromName":"A Large Angry SCM","fromEmail":"gitzilla@gmail.com","sentAt":"2006-08-05T22:35:51Z","receivedAt":"2006-08-05T22:35:51Z","isPatch":false,"sender":{"key":"gitzilla@gmail.com","avatar":"https://gravatar.com/avatar/354625c442439908ff3dd99757dee330e29e9df7847472384faf7a00add247fb?d=mp&s=160"},"body":"A Large Angry SCM wrote:\n> This information may be useful for reading and writing the various Git \n> files.\n\nRevised.\n\n\n\nGit files data formats\n======================\n\nOBJECTS\n-------\n# The object ID, or \"name\", of an object is\n#\t_sha-1_digest_( <OBJECT_HEADER> <object_CONTENTS> ).\n\n<BLOB>\n\t:\t_deflate_( <OBJECT_HEADER> <BLOB_CONTENTS> )\n\t|\t<COMPACT_OBJECT_HEADER> _deflate_( <BLOB_CONTENTS> )\n\t;\n\n<BLOB_CONTENTS>\n\t:\t<DATA>\n\t;\n\n<TREE>\n\t:\t_deflate_( <OBJECT_HEADER> <TREE_CONTENTS> )\n\t|\t<COMPACT_OBJECT_HEADER> _deflate_( <TREE_CONTENTS> )\n\t;\n\n<TREE_CONTENTS>\n\t:\t<TREE_ENTRIES>\n\t;\n\n<TREE_ENTRIES>\n\t# Tree entries are sorted by the byte sequence that comprises\n\t# the entry name. However, for the purposes of the sort\n\t# comparison, entries for tree objects are compared as if the\n\t# entry name byte sequence has a trailing ASCII '/' (0x2f).\n\t:\t( <TREE_ENTRY> )*\n\t;\n\n<TREE_ENTRY>\n\t# The type of the object referenced MUST be appropriate for\n\t# the mode. Regular files and symbolic links reference a BLOB\n\t# and directories reference a TREE.\n\t:\t<OCTAL_MODE> <SP> <NAME> <NUL> <BINARY_OBJ_ID>\n\t;\n\n<COMMIT>\n\t:\t_deflate_( <OBJECT_HEADER> <COMMIT_CONTENTS> )\n\t|\t<COMPACT_OBJECT_HEADER> _deflate_( <COMMIT_CONTENTS> )\n\t;\n\n<COMMIT_CONTENTS>\n\t:\t\"tree\" <SP> <HEX_OBJ_ID> <LF>\n\t\t( \"parent\" <SP> <HEX_OBJ_ID> <LF> )*\n\t\t\"author\" <SP>\n\t\t\t<SAFE_NAME> <SP>\n\t\t\t<LT> <SAFE_EMAIL> <GT> <SP>\n\t\t\t<GIT_DATE> <LF>\n\t\t\"committer\" <SP>\n\t\t\t<SAFE_NAME> <SP>\n\t\t\t<LT> <SAFE_EMAIL> <GT> <SP>\n\t\t\t<GIT_DATE> <LF>\n\t\t<LF>\n\t\t<DATA>\n\t;\n\n<TAG>\n\t:\t_deflate_( <OBJECT_HEADER> <TAG_CONTENTS> )\n\t|\t<COMPACT_OBJECT_HEADER> _deflate_( <TAG_CONTENTS> )\n\t;\n\n<TAG_CONTENTS>\n\t:\t\"object\" <SP> <HEX_OBJ_ID> <LF>\n\t\t\"type\" <SP> <OBJ_TYPE> <LF>\n\t\t\"tag\" <SP> <TAG_NAME> <LF>\n\t\t<LF>\n\t\t<DATA>\n\t;\n\n<OBJECT_HEADER>\n\t:\t<OBJ_TYPE> <SP> <DECIMAL_LENGTH> <NUL>\n\t;\n\n<COMPACT_OBJECT_HEADER>\n\t# The object type DELTA_ENCODED is not valid in a\n\t# <COMPACT_OBJECT_HEADER>.\n\t:\t<TYPE_AND_BASE128_SIZE>\n\t;\n\n<DATA>\n\t# Uninterpreted sequence of bytes.\n\t;\n\n<OCTAL_MODE>\n\t# ASCII encoding of the octal encoding, without prefix or\n\t# leading zeros, of the file system object type and permission\n\t# bits. The bit layout is according to the POSIX standard, with\n\t# only regular files, directories, and symbolic links\n\t# permitted. The actual permission bits are all zero except for\n\t# regular files. The only permission bit of any consequence to\n\t# Git is the owner executable bit. By default, the permission\n\t# bits for files will be either 0644 or 0755, depending on the\n\t# owner executable bit.\n\t;\n\n<NAME>\n\t# Sequence of bytes not containing the ASCII character byte\n\t# values NUL (0x00) or \"/\" (0x2f).\n\t;\n\n<BINARY_OBJ_ID>\n\t# The object ID of the referenced object.\n\t;\n\n<HEX_OBJ_ID>\n\t# Hexidecimal encoding (lower case) of the <BINARY_OBJ_ID>.\n\t;\n\n<SAFE_NAME>\n\t:\t<SAFE_STRING> \n\t;\n\n<SAFE_EMAIL>\n\t:\t<SAFE_STRING>\n\t;\n\n<SAFE_STRING>\n\t# A sequence of bytes not containing the ASCII character byte\n\t# values NUL (0x00), LF (0x0a), '<' (0c3c), or '>' (0x3e).\n\t#\n\t# The sequence may not begin or end with any bytes with the\n\t# following ASCII character byte values: SPACE (0x20),\n\t# '.' (0x2e), ',' (0x2c), ':' (0x3a), ';' (0x3b), '<' (0x3c),\n\t# '>' (0x3e), '\"' (0x22), \"'\" (0x27).\n\t;\n\n<GIT_DATE>\n\t:\t<SECONDS> <SP> <TZ_OFFSET>\n\t;\n\n<SECONDS>\n\t# Base 10, ASCII encoding of the number of seconds since 12:00\n\t# midnight January 1, 1970, UTC without accounting for leap\n\t# seconds, and without leading zeros.\n\t;\n\n<TZ_OFFSET>\n\t# Signed offset of time zone from UTC.\n\t:\t<TZ_OFFSET_SIGN> <TZ_OFFSET_HOURS> <TZ_OFFSET_MIN>\n\t;\n\n<TZ_OFFSET_SIGN>\n\t:\t\"+\"\n\t|\t\"-\"\n\t;\n\n<TZ_OFFSET_HOURS>\n\t:\t<DIGIT> <DIGIT>\n\t;\n\n<TZ_OFFSET_MIN>\n\t# Valid values are \"00\" to \"59\" inclusive.\n\t:\t<DIGIT> <DIGIT>\n\t;\n\n<DIGIT>\n\t# ASCII decimal digit.\n\t;\n\n<OBJ_TYPE>\n\t:\t\"blob\"\n\t|\t\"tree\"\n\t|\t\"commit\"\n\t|\t\"tag\"\n\t;\n\n<DECIMAL_LENGTH>\n\t# Base 10, ASCII encoding of the byte length of the object\n\t# contents, without leading zeros. The length value does not\n\t# include the length of the <OBJECT_HEADER>.\n\t:\t( <DIGIT> )+\n\t;\n\n<SP>\n\t# ASCII SPACE (0x20) character.\n\t;\n\n<NUL>\n\t# ASCII NUL (0x00) character.\n\t;\n\n<LF>\n\t# ASCII LF (0x0a) \"line feed\" character.\n\t;\n\n\nPACK FILE\n---------\n# The name of a pack file is \"pack-${PACK_ID}.pack\", where ${PACK_ID}\n# is the hexidecimal encoding (lower case) of the SHA-1 digest of the\n# sorted list of binary object IDs in the pack file without a separator\n# between the object IDs. Initially, the ${PACK_ID} for a pack was not\n# well defined, effectively making the value 40 random hexidecimal\n# (lower case) characters. Recent, non git-core, code depends on the\n# uniqueness of ${PACK_ID} across all of the object databases used by\n# a repository.\n\n<PACK_FILE>\n\t:\t<PACK_FILE_CONTENTS> <PACK_FILE_CHECKSUM>\n\t;\n\n<PACK_FILE_CONTENTS>\n\t:\t\"PACK\" <PACK_VERSION> <PACK_OBJECT_COUNT>\n\t\t( <PACKED_OBJECT_HEADER> <PACKED_OBJECT_DATA> )*\n\t\t<PACK_FILE_CHECKSUM>\n\t;\n\n<PACK_VERSION>\n\t# 32 bit, network byte order, binary integer indicating which\n\t# version of the pack file format was used to create the pack\n\t# file.\n\t;\n\n<PACK_OBJECT_COUNT>\n\t# 32 bit, network byte order, binary integer containg the\n\t# number of objects encoded in the pack file.\n\t;\n\n<PACK_FILE_CHECKSUM>\n\t:\t_sha-1_digest_( <PACK_FILE_CONTENTS> )\n\t;\n\n\n<PACKED_OBJECT_HEADER>\n\t# If the object type is not a DELTA_ENCODED object, the packed\n\t# object data that follows is the deflated byte sequence of the\n\t# object without the Git object header. The length value is the\n\t# byte count of the inflated byte sequence of the object.\n\t#\n\t# If the object type is a DELTA_ENCODED object, what follows is\n\t# the ID of the base object and the deflated delta data to\n\t# transform the base object into the target object. The type of\n\t# the target object is the same as that of the base object and\n\t# the length value is the byte count of the inflated delta\n\t# data. The base object may also be DELTA_ENCODED but cyclic\n\t# base object chains are not permitted and the pack file MUST\n\t# contain all base objects.\n\t:\t<TYPE_AND_BASE128_SIZE>\n\t;\n\n<TYPE_AND_BASE128_SIZE>\n\t# A compact, variable length, encoding of the packed object\n\t# length and type. The first byte is comprised of 3 fields\n\t# (where bit 0 is the least significant bit in a byte):\n\t#\tbit 7:\t\tmore flag\n\t#\tbits 6-4:\tobject type\n\t#\tbits 3-0:\tleast significant bits of the object\n\t#\t\t\tlength.\n\t# If the more flag is set, the next byte contains more object\n\t# length bits.\n\t# The object types corresponding to the object type bits are:\n\t#\t6 5 4\n\t#\t- - -\n\t#\t0 0 0\tinvalid: Reserved\n\t#\t0 0 1\tCOMMIT object\n\t#\t0 1 0\tTREE object\n\t#\t0 1 1\tBLOB object\n\t#\t1 0 0\tTAG object\n\t#\t1 0 1\tinvalid: Reserved\n\t#\t1 1 0\tinvalid: Reserved\n\t#\t1 1 1\tDELTA_ENCODED object\n\t#\n\t# If the more flag was set, the next byte will have more length\n\t# bits and will be comprised to 2 fields:\n\t#\tbit 7:\t\tmore flag\n\t#\tbits 6-0:\t7 additional, more significant, bits of\n\t#\t\t\tthe object length\n\t# If the more flag is set, the next byte contains more object\n\t# length bits using the same encoding.\n\t;\n\n<PACKED_OBJECT_DATA>\n\t:\t_deflate_( <DATA> )\n\t|\t<BINARY_OBJ_ID> _deflate_( <DELTA_DATA> )\n\t;\n\n<DELTA_DATA>\n\t# Size of the base object encoded as a base 128 number, least\n\t# significant bits first, using bit 7 (the most significant\n\t# bit) of each byte to indicate that more bits follow.\n\t#\n\t# Size of the result object encoded as a base 128 number, using\n\t# the same method as used for the base object size.\n\t#\n\t# There will then be a sequence of delta hunks.\n\t# Zero as the value of the first byte of a hunk in reserved.\n\t#\n\t# If bit 7 of the first byte of a delta hunk is not set, the\n\t# hunk is an \"insert\" hunk and bits 0-6 specify the number of\n\t# bytes to append to the output buffer from the hunk.\n\t#\n\t# If bit 7 of the first byte of a delta hunk is set, the hunk\n\t# is a \"copy\" hunk and bits 0-6 specify how the remaining\n\t# bytes in the hunk make up the base offset and length for the\n\t# copy. The following C code demonstrate how to determine the\n\t# base offset and length for the copy:\n\t#\n\t#\t/* -  -  -  -  -  -  -  -  -  -  -  - *\\\n\t#\t | This reflects version 3 pack files |\n\t#\t\\* -  -  -  -  -  -  -  -  -  -  -  - */\n\t#\n\t#\tbyte *data = delta_hunk_start\n\t#\topcode = *data++\n\t#\toff_t copy_offset= 0;\n\t#\tsize_t copy_length = 0;\n\t#\n\t#\tfor (shift=i=0; i<4; i++) {\n\t#\t\tif (opcode & 0x01) {\n\t#\t\t\tcopy_offset |= (*data++)<<shift;\n\t#\t\t\t}\n\t#\t\topcode >>= 1;\n\t#\t\tshift += 8;\n\t#\t\t}\n\t#\n\t#\tfor (shift=i=0; i<3; i++) {\n\t#\t\tif (opcode & 0x01) {\n\t#\t\t\tcopy_length |= (*data++)<<shift;\n\t#\t\t\t}\n\t#\t\topcode >>= 1;\n\t#\t\tshift += 8;\n\t#\t\t}\n\t#\n\t#\tif (!copy_length) {\n\t#\t\tcopy_length = 1<<16;\n\t#\t\t}\n\t#\n\t# For version 2 pack files, the size of a copy is limited to\n\t# 64K bytes or less and bit 6 of the opcode byte is set if the\n\t# source of the copy is from the buffer of the result object\n\t# instead of the the base object.\n\t#\n\t# It's unknown if any version 2 pack files were created with\n\t# bit 6 set in the opcode byte; however, the change that added\n\t# support for version 3 pack files removed the code that would\n\t# change the copy source to the result buffer.\n\t#\n\t#\t/* -  -  -  -  -  -  -  -  -  -  -  - *\\\n\t#\t | This reflects version 2 pack files |\n\t#\t\\* -  -  -  -  -  -  -  -  -  -  -  - */\n\t#\n\t#\tbyte *data = delta_hunk_start\n\t#\topcode = *data++\n\t#\toff_t copy_offset= 0;\n\t#\tsize_t copy_length = 0;\n\t#\n\t#\tfor (shift=i=0; i<4; i++) {\n\t#\t\tif (opcode & 0x01) {\n\t#\t\t\tcopy_offset |= (*data++)<<shift;\n\t#\t\t\t}\n\t#\t\topcode >>= 1;\n\t#\t\tshift += 8;\n\t#\t\t}\n\t#\n\t#\tfor (shift=i=0; i<2; i++) {\n\t#\t\tif (opcode & 0x01) {\n\t#\t\t\tcopy_length |= (*data++)<<shift;\n\t#\t\t\t}\n\t#\t\topcode >>= 1;\n\t#\t\tshift += 8;\n\t#\t\t}\n\t#\n\t#\tif (!copy_length) {\n\t#\t\tcopy_length = 1<<16;\n\t#\t\t}\n\t#\n\t#\tcopy_from_result = opcode & 0x01\n\t#\n\t;\n\n\nPACK INDEX\n----------\n# The name of a pack file index is \"pack-${PACK_ID}.idx\", where\n# ${PACK_ID} is the same as that of the pack file that the pack index\n# corresponds to.\n\n<PACK_INDEX>\n\t:\t<PACK_INDEX_CONTENTS> <PACK_INDEX_CHECKSUM>\n\t;\n\n<PACK_INDEX_CONTENTS>\n\t:\t( <INDEX_PARTIAL_COUNT> ){256}\n\t\t( <PACK_OBJECT_OFFSET> <BINARY_OBJ_ID> )*\n\t\t<PACK_FILE_CHECKSUM>\n\t;\n\n<INDEX_PARTIAL_COUNT>\n\t# 32 bit, network byte order, binary integer of the count of\n\t# objects in the pack file with the first byte of the object\n\t# ID less than or equal to the index of the count, starting\n\t# from zero.\n\t;\n\n<PACK_OBJECT_OFFSET>\n\t# 32 bit, network byte order, binary integer giving the offset,\n\t# in bytes from the begining of the pack file, where the\n\t# encoding of the object starts.\n\t;\n\n<PACK_INDEX_CHECKSUM>\n\t:\t_sha-1_digest_( <PACK_INDEX_CONTENTS> )\n\t;\n\n\nINDEX FILE (CACHE)\n------------------\n\n<INDEX_FILE>\n\t:\t<INDEX_FILE_FORMAT_V1>\n\t|\t<INDEX_FILE_FORMAT_V2>\n\t;\n\n<INDEX_FILE_FORMAT_V1>\n\t# This format is no longer supported.\n\t:\t<INDEX_HEADER> <INDEX_CHECKSUM> <INDEX_CONTENTS>\n\t;\n\n<INDEX_FILE_FORMAT_V2>\n\t:\t<INDEX_HEADER> <EXTENDED_INDEX_CONTENTS> <EXTENED_CHECKSUM>\n\t;\n\n<INDEX_HEADER>\n\t:\t\"DIRC\" <INDEX_FILE_VERSION> <INDEX_ENTRY_COUNT>\n\t;\n\n<INDEX_FILE_VERSION>\n\t# 32 bit, network byte order, binary integer indicating which\n\t# version of the index file format was used to create the\n\t# index file.\n\t;\n\n<INDEX_ENTRY_COUNT>\n\t# 32 bit, network byte order, binary integer containg the\n\t# number of index entries in the index file.\n\t;\n\n<EXTENDED_CHECKSUM>\n\t:\t_sha-1_digest_( <EXTENDED_INDEX_CONTENTS> )\n\t;\n\n<INDEX_CHECKSUM>\n\t:\t_sha-1_digest_( <INDEX_CONTENTS> )\n\t;\n\n<INDEX_CONTENTS>\n\t# Index entries are sorted by the byte sequence that comprises\n\t# the entry name; with a secondary comparison of the stage bits\n\t# from the <ENTRY_FLAGS> if the entry name byte sequences are\n\t# identical.\n\t:\t( <INDEX_ENTRY> )*\n\t;\n\n<EXTENDED_INDEX_CONTENTS>\n\t:\t<INDEX_CONTENTS> <INDEX_CONTENTS_EXTENSIONS>\n\t;\n\n<INDEX_ENTRY>\n\t:\t<INDEX_ENTRY_STAT_INFO>\n\t\t<ENTRY_ID>\n\t\t<ENTRY_FLAGS>\n\t\t<ENTRY_NAME>\n\t\t<NUL>\n\t\t<ENTRY_ZERO_PADDING>\n\t;\n\n<ENTRY_ZERO_PADDING>\n\t# The minimum length 0x00 byte sequence necessary to make the\n\t# written of digested byte length of the <INDEX_ENTRY> a\n\t# multiple of 8.\n\t;\n\n<INDEX_ENTRY_STAT_INFO>\n\t# These fields are used as a part of a heuristic to determine\n\t# if the file system entity associated with this entry has\n\t# changed. The names are very *nix centric but the exact\n\t# contents of each field have no meaning to Git, besides exact\n\t# match, except for the <ENTRY_MODE> and <ENTRY_SIZE> fields.\n\t:\t<ENTRY_CTIME>\n\t\t<ENTRY_MTIME>\n\t\t<ENTRY_DEV>\n\t\t<ENTRY_INODE>\n\t\t<ENTRY_MODE>\n\t\t<ENTRY_UID>\n\t\t<ENTRY_GID>\n\t\t<ENTRY_SIZE>\n\t;\n\n<ENTRY_CTIME>\n\t# The timestamp of the last status change of the associated\n\t# file system entity.\n\t:\t<ENTRY_TIME>\n\t;\n\n<ENTRY_MTIME>\n\t# The timestamp of the last modification of the associated\n\t# file system entity.\n\t:\t<ENTRY_TIME>\n\t;\n\n<ENTRY_TIME>\n\t:\t<TIME_LSB32> <TIME_NSEC>\n\t;\n\n<TIME_LSB32>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) timestamp.\n\t;\n\n<TIME_NSEC>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) more precise\n\t# timestamp, if available.\n\t;\n\n<ENTRY_DEV>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) file system\n\t# device identifier. Use of this field is a compile time\n\t# option.\n\t;\n\n<ENTRY_INODE>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) inode number, or\n\t# equivalent.\n\t;\n\n<ENTRY_MODE>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) file system\n\t# entity type and permissions.\n\t;\n\n<ENTRY_UID>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) file system\n\t# entity owner identifier.\n\t;\n\n<ENTRY_GID>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) file system\n\t# entity group identifier, or equivalent.\n\t;\n\n<ENTRY_SIZE>\n\t# 32 bit, network byte order, binary integer containg the lower\n\t# 32 bits of the entry (file or symbolic link) size.\n\t;\n\n<ENTRY_ID>\n\t# Object ID of the of the file system entity contents.\n\t;\n\n<ENTRY_FLAGS>\n\t# 16 bit, network byte order, binary integer.\n\t#\tbits 15-14\tReserved\n\t#\tbits 13-12\tEntry stage\n\t#\tbits 11-0\tName byte length\n\t#\n\t# See git-read-tree(1) for a description of how the stage\n\t# field is used.\n\t;\n\n<ENTRY_NAME>\n\t# File system entity name. Path is normalized and relative to\n\t# the working directory.\n\t;\n\n<INDEX_CONTENTS_EXTENSIONS>\n\t:\t( <INDEX_EXTENSION> )*\n\t;\n\n<INDEX_EXTENSION>\n\t:\t<INDEX_EXTENSION_HEADER>\n\t\t<INDEX_EXTENSION_DATA>\n\t;\n\n<INDEX_EXTENSION_HEADER>\n\t:\t<INDEX_EXTENSION_NAME> <INDEX_EXTENSION_DATA_SIZE>\n\t;\n\n<INDEX_EXTENSION_NAME>\n\t# 4 byte sequence identifying how the <INDEX_EXTENSION_DATA>\n\t# should be interpreted. If the first byte has a value greater\n\t# than or equal to the ASCII character 'A' (0x41) and less than\n\t# or equal to the ASCII character 'Z' (0x5a), the extension is\n\t# optional and does not affect the interpretation of the other\n\t# contents in the index file. Any non-optional extensions must\n\t# be understood by the reading application to correctly\n\t# interpret the index file contents.\n\t;\n\n<INDEX_EXTENSION_DATA_SIZE>\n\t# 32 bit, network byte order, binary integer containg the\n\t# length of the <INDEX_EXTENSION_DATA> byte sequence.\n\t;\n\n<INDEX_EXTENSION_DATA>\n\t# Sequence of bytes.\n\t;\n\n\n"},{"id":"24852","messageId":"eb3ad8$fq6$1@sea.gmane.org","threadId":"5142","inReplyTo":"44D4FC52.6030807@gmail.com","subject":"Re: Git files data formats documentation","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-05T23:43:19Z","receivedAt":"2006-08-05T23:43:19Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"A Large Angry SCM wrote:\n\n> Jakub Narebski wrote:\n\n>> I do wonder why there is <OCTAL_MODE> (and not <BINARY_OCTAL_MODE>) \n>> but <BINARY_OBJ_ID> (and not <HEX_OBJ_ID>).\n>> \n> \n> <OCTAL_MODE> because it's an ASCII string. <BINARY_OBJ_ID> because it's \n> the 20 byte digest.\n\nI meant why git use ASCII string for octal mode, while using 20 byte digest\nfor object-id in tree format. More consistent would be use binary and\nbinary, or ASCII and ASCII (i.e. <HEX_OBJ_ID>).\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"24862","messageId":"7vejvud7ib.fsf@assigned-by-dhcp.cox.net","threadId":"5142","inReplyTo":"44D5141A.2070004@gmail.com","subject":"Re: Git files data formats documentation","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-06T00:37:16Z","receivedAt":"2006-08-06T00:37:16Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"A Large Angry SCM <gitzilla@gmail.com> writes:\n\n> Junio C Hamano wrote:\n> ...\n>>> <OCTAL_MODE>\n>>> \t# Octal encoding, without prefix, of the file system object\n>>> \t# type and permission bits. The bit layout is according to the\n>>> \t# POSIX standard, with only regular files, directories, and\n>>> \t# symbolic links permitted. The actual permission bits are\n>>> \t# all zero except for regular files. The only permission bit\n>>> \t# of any consequence to Git is the owner executable bit. By\n>>> \t# default, the permission bits for files will be either 0644\n>>> \t# or 0755, depending on the owner executable bit.\n>>> \t;\n>>\n>> It's not really \"by default\" -- more like \"by definition\", since\n>> there is no way for the program to use something different.  We\n>> used to record non-canonical modes in ancient versions of git,\n>> but I think fsck-objects would warn on objects created that way.\n>>\n>\n> See git-mktree.\n\nThat's a bad example -- the tool being too loose.\n"},{"id":"25417","messageId":"Pine.LNX.4.64.0608161243080.3494@localhost.localdomain","threadId":"5142","inReplyTo":"44D51D47.9090700@gmail.com","subject":"Re: Git files data formats documentation","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2006-08-16T16:55:23Z","receivedAt":"2006-08-16T16:55:23Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"A Large Angry SCM wrote:\n> This information may be useful for reading and writing the various Git\n> files.\n\n[...]\n\n        # For version 2 pack files, the size of a copy is limited to\n        # 64K bytes or less and bit 6 of the opcode byte is set if the\n        # source of the copy is from the buffer of the result object\n        # instead of the the base object.\n        #\n        # It's unknown if any version 2 pack files were created with\n        # bit 6 set in the opcode byte; however, the change that added\n        # support for version 3 pack files removed the code that would\n        # change the copy source to the result buffer.\n\nThere were no version 2 pack files with bit 6 set in the opcode byte \never produced (except on my own hard disk when I was experimenting with \nthat feature).  The (negative) compression gain turned up to be not \nworth the needed computational cost to make use of it, hence that bit is \nnow dedicated to specifying an extra size byte.\n\nSee commit d60fc1c8649f80c006b9f493c542461e81608d4b log message for \nmore.\n\n\nNicolas\n"}]}