<- 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.