Earlier quoted context omitted.
git gc runs automatically when some threshold is met in the number of "loose" objects (objects that were created by e.g. git add and that haven't been packed yet). I don't remember what the threshold is, though.
I believe loose objects are also packed when pushing to a remote or fetching from it. I wonder if the remote's .git folder is also about 3 MB in size.
Some Git internals
21–30 of 36 posts
Re: Some Git internals
#22Shameless plug: I recently picked up Golang and used it to implement a mini version of Git CLI using these internals [1].
Re: Some Git internals
#23This was really really educational. Git internals seem rather simple. Does anyone have a really good visual explanation of what's being done to the tree and such when commits and merges and rebases are done? I still don't quite grok it intimately enough.
The Git Internals section of the Pro Git book covers commits [1] and branches [2] well though it doesn’t go into details about merges and rebases. [1]: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects [2]: https://git-scm.com/book/en/v2/Git-Internals-Git-References
Re: Some Git internals
#24Re: Some Git internals
#25A dumb question: if I make a commit changing just a single line in a large file, does this create a completely new object/blob with the entire contents of the file? Or does it store it in a more space-efficient manner?
The former, until you run git gc, in which case the latter happens.
Re: Some Git internals
#26Re: Some Git internals
#27Earlier quoted context omitted.
Do you know if there's an easy way to do this without running git gc? Say by just supplying a diff or something? In particular I'm thinking of the case where there's an append-only file keeping a log, to commit the changes every so often without having to make a blob copy of the file first (which may be relatively large)?
This is sort of a worst-case scenario for git: there are patch-based DVCSes that would handle this scenario better (darcs and pijul), but those have their own set of trade offs (I think they end up being slower for large histories).
Applying a patch in Pijul is in O(p c log n), where p is the size of the patch and c the size of the largest "deletion-insertion conflict" p is involved in, where a "deletion-insertion conflict" is a situation where Alice deletes a block of text while Bob adds stuff in that same block.
Note that this is a rough bound, since all non-conflicting operations in a patch are in O(log n), except those involved in a "deletion-insertion conflict", which are in O(c log n).
So, Pijul is in fact faster than Git for merging (and rebasing). The only tradeoff at the moment is that going arbitrarily far back in history isn't as fast as it could be (this will be fixed very soon).
Re: Some Git internals
#28Re: Some Git internals
#29Re: Some Git internals
#30Earlier quoted context omitted.
It doesn't. It packs it.
Is git gc the only thing that can trigger packing?