here are some things I learned while writing this:
1. Commits can have "extra fields", for example a GPG signature
2. I always thought entries in a tree had 4 fields, but there are actually only 3 (file name, file type, and object ID)
3. Git sometimes prints out file types as a bit set (100644), but it's really more like an enum, since there are only 5 file types (regular file, executable file, symlink, directory, and gitlink)
(2/?)
4. In Git's index (aka staging area), every file has a "stage number". This is usually 0, but when there's a merge conflict then there can be 4 versions of the same file in the "staging area"
5. Branches are not necessarily always stored as "every branch is a file in .git", there's also a reftable backend https://about.gitlab.com/blog/a-beginners-guide-to-the-git-reftable-format/ which fixes some problems with "branches are files", like how if you're on a case-insensitive filesystem it means your branches are also case-insensitive
(3/?)
@enhancedscurry i just looked into this and as far as I can tell from my experimentation, it's theoretically possible in Git to create a commit with an empty directory in it (like there's nothing in the data model that prevents it).
BUT if you check out that commit, the checkout won't include the empty directory, so the effect is that (as we all know) you can't have empty directories in Git.
@b0rk The way Git displays octal file modes to the user is so unfortunate :( It gives you the false impression that files in a repo *could* have unusual permissions/types, or that perhaps the umask on a commiter's machine might affect the permissions of newly committed files, whereas in reality Git enforces "standard" file modes.
(To be clear, I think it's good that Git can't store any fancy permissions/types - I just wish it would communicate that to the user...)
@b0rk Hmm, are those extra fields stored in the commit itself or can arbitrary metadata be stored in Git?
For some context (and it might have been experimented on already), Mercurial has an extension called evolve that is providing "obsolescence markers", which are pushed (and pulled) in the remote repository. Those obsolescence markers let you know when a commit was rewritten in history, e.g. after a rebase or after modifying it, and this is used to automatically "evolve" a branch modified by your peers (and also for the server to forbid pushing outdated changes, like with force-with-lease).
I'm wondering if evolve could be ported to Git.
@Exagone313 they're in the commit so they're immutable
it looks like someone's tried to build "git evolve" before https://lwn.net/Articles/914041/
6.88K Posts, 342 Following, 49.9K Followers · programming and exclamation marks I have DMs muted from people I don’t follow.
@b0rk That's amazing!
I just read through it, and I think I found a formatting bug: The text "the old commit will usually not be reachable, ..." at the end of REFERENCES looks like it should be part of the note, but at least in the GitHub preview it's rendered outside of the note box.
This is great and also necessary.