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