← HOME - a blog about
xit RSS
██╗ ██╗██╗████████╗██╗ ██████╗ ██████╗
╚██╗██╔╝██║╚══██╔══╝██║ ██╔═══██╗██╔════╝
╚███╔╝ ██║ ██║ ██║ ██║ ██║██║ ███╗
██╔██╗ ██║ ██║ ██║ ██║ ██║██║ ██║
██╔╝ ██╗██║ ██║ ███████╗╚██████╔╝╚██████╔╝
╚═╝ ╚═╝╚═╝ ╚═╝ ╚══════╝ ╚═════╝ ╚═════╝
DEVLOG - FASTER DIFFING/CLONING, LAZY PATCHES, AND MORE -
March 21, 2025
Rejoice! xit is no longer quite as dog slow as it was
before. In particular, writing objects (at the end of a
clone or fetch) and generating patches are much faster now.
After some investigation, it became clear that the problem
was the same in both cases: xit was constantly reading small
pieces of files from the disk.
To solve this, I
first made it read text files fully
into memory for diffing. I
then updated the pack object
reader to load objects from pack files entirely into memory
(if they are below a certain file size). After these two
changes, generating patches and cloning/fetching are much
faster.
The UI got some love as well. I noticed that I neglected
to show conflicts in the status TUI, and that has been
fixed. A while later, I began
embedding TUIs into my
unit tests. Yes, I mean literally making assertions that
embed the TUI in a big string. It's glorious...let's see you
do that, GUI / web developers.
I also made some critical networking fixes recently. I
revamped and
fixed the http code, because it was quite
badly broken for more complex fetches. Hopefully it will now
be as reliable as the ssh code, which is inherently easier
to get right due to its simplicity (the ssh client does most
of the work, after all).
After the above-mentioned performance fixes, I felt
comfortable
re-enabling compression on text chunks.
Previously, I had disabled it because patch generation was
so slow, I didn't want to slow it down more with
compression. It is now enabled, though xit repos will
normally still take up much more space than git repos; there
are plenty more optimizations coming.
Lastly, I've received a slew of great PRs from my first
contributor, and
this one is worth noting. When you enable
patch-based merging with `xit patch on`, it now generates
the necessary patches at merge time rather than right away.
If you actually want to generate them all in advance, you
can do `xit patch all`. Generating them lazily is a great
idea because it allows you to delay the work until it's
needed, and only do the work for commits that are involved
in the merge.