Subject: Re: confused about preserved permissions

From: Junio C Hamano <[email-masked]>
Date: Mon, 20 Aug 2007 19:06:27 -0700

"Shawn O. Pearce" <[email-masked]> writes:

> Mike Hommey <[email-masked]> wrote:
>> > >> > sprintf "%06o %s\0%s", $mode, $file, pack("H[40]", $sha1)
>> 
>> The question here was why the permissions are encoded with "%06o" while
>> the hash is packed. Anyways, it's just a boring detail.
>
> Because text format is simple and pretty much everyone understands
> it, especially when you are talking about UNIX mode/permission
> bits in octal, the name is "text", and then oh, wait, those 40
> bytes of hex is a lot of data - we'll just make that 20 bytes of
> binary instead.  :-)

That is almost true, but there is one factual error I need to
correct.

In-tree representation of the mode is not actually "%06o" but
just "%o".  In very early days of git, we used to have extra
leading "0" in trees (e.g. "040000"), but that is something
modern fsck even warns about.  IOW, it is not the norm.

It is represented as text because we _can_ add any number of
bits to the data later if we wanted to.  Basic tree objects that
contain only the kind of data we traditionally used will
continue to work, while trees that contain (yet to be invented)
new types that are represented with longer mode bits may of
course not be read by older tools.

On the other hand, by definition, SHA-1 is 20-bytes.  If we
wanted to be able to replace hash function, we _could_ have done
hashtype + length + data format (and length is represented with
either text or "7-bit-per-byte plus stop bit" format as in the
pack format), but there was no reason to.

The same logic applies to the loose object header -- length is
not "network byte order 4-byte integer" (or 8-byte), but just a
textual representation of an unsigned integer of unspecified
length.  The current code happen to use "%lu" with ulong only
because that is the largest integral type that can be used
portably and is not cumbersome to use.  On future architectures
with larger word size, we do not have to update the data
structure definition nor even the code to read and write loose
objects.  Using a blob that is longer than 2^64 bytes may or may
not be possible depending on how long your ulong is, of course.