# Xit: a version control system

**URL:** <https://ziggit.dev/t/xit-a-version-control-system/8880>\
**Category:** Showcase\
**Created:** [March 5, 2025, 1:25am UTC](https://ziggit.dev/t/xit-a-version-control-system/8880 "2025-03-05T01:25:05Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![xeubie](https://ziggit.dev/user_avatar/ziggit.dev/xeubie/32/4715_2.png) [@xeubie](https://ziggit.dev/u/xeubie)\
**Post date:** [March 5, 2025, 1:25am UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/1 "2025-03-05T01:25:05Z")

</div>

Hi guys, I’m working on a version control system. Nothing big and professional like git :^)

> **[GitHub - xit-vcs/xit: a git alternative written in zig](https://github.com/xit-vcs/xit)**
>
> a git alternative written in zig

---

<div class="post-metadata">

**Author:** ![cryptocode](https://ziggit.dev/user_avatar/ziggit.dev/cryptocode/32/817_2.png) [@cryptocode](https://ziggit.dev/u/cryptocode)\
**Post date:** [March 5, 2025, 10:08am UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/2 "2025-03-05T10:08:50Z")

</div>

> [@xeubie](#):
>
> Nothing big and professional like git :^)

In case anyone missed the nice _big and professional_ reference: [Linux announcement](https://web.archive.org/web/20130509134305/http://groups.google.com/group/comp.os.minix/msg/b813d52cbc5a044b)

---

<div class="post-metadata">

**Author:** ![dbushell](https://ziggit.dev/user_avatar/ziggit.dev/dbushell/32/4741_2.png) [@dbushell](https://ziggit.dev/u/dbushell)\
**Post date:** [March 5, 2025, 10:24am UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/3 "2025-03-05T10:24:41Z")

</div>

Sounds like a fun but daunting challenge! The code looks very readable, thanks for sharing. How have you found Zig for network / HTTP stuff?

---

<div class="post-metadata">

**Author:** ![matklad](https://ziggit.dev/user_avatar/ziggit.dev/matklad/32/2462_2.png) [@matklad](https://ziggit.dev/u/matklad)\
**Post date:** [March 5, 2025, 1:06pm UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/4 "2025-03-05T13:06:38Z")

</div>

Your writing style is hilarious, I’ve learned a bunch from [xit/docs/patch.md at master · radarroark/xit · GitHub](https://github.com/radarroark/xit/blob/master/docs/patch.md), and had a good laugh, because CRDT, thanks!

---

<div class="post-metadata">

**Author:** ![xeubie](https://ziggit.dev/user_avatar/ziggit.dev/xeubie/32/4715_2.png) [@xeubie](https://ziggit.dev/u/xeubie)\
**Post date:** [March 5, 2025, 7:15pm UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/5 "2025-03-05T19:15:27Z")

</div>

> [@dbushell](#):
>
> Sounds like a fun but daunting challenge!

And possibly a fabulous waste of my time, but it’s been a fun ride anyway lol.

> [@dbushell](#):
>
> The code looks very readable, thanks for sharing. How have you found Zig for network / HTTP stuff?

Zig’s http client has worked pretty great for me so far. It supports everything I need, like chunked encoding. The only issue right now is that on linux, when you clone/fetch from github, you’ll see an ugly stack trace with `unexpected errno: 1` even though it actually succeeds (this happens on both 0.13 and 0.14). I’ve found similar issues already made so I’m not sure it’s worth reporting.

SSH is certainly the most important transport anyway, and it was actually the easiest to implement. Just spawn the process and send the right pktline format, letting ssh do the rest.

> [@matklad](#):
>
> Your writing style is hilarious

Thank you :^D Working on version control is often incredibly dull, so I need to do that just to maintain my sanity.

---

<div class="post-metadata">

**Author:** ![kracked](https://ziggit.dev/letter_avatar_proxy/v4/letter/k/e8c25b/32.png) [@kracked](https://ziggit.dev/u/kracked)\
**Post date:** [March 6, 2025, 1:32am UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/6 "2025-03-06T01:32:23Z")

</div>

> [@xeubie](#):
>
> version control is often incredibly dull

I’ve done my git from scratch thingy and I found it very rewarding. Not dull at all.

---

<div class="post-metadata">

**Author:** ![cian](https://ziggit.dev/user_avatar/ziggit.dev/cian/32/4359_2.png) [@cian](https://ziggit.dev/u/cian)\
**Post date:** [March 6, 2025, 1:08pm UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/7 "2025-03-06T13:08:04Z")

</div>

Yes, your notes on design are really fun to read. You should start a blog 🙂

On TUIs. I’ve used libvaxis, and I’m curious as to why you didn’t you use that. One UI style you might want to explore for short cuts is how wordstar/wordperfect used to do it, where there was a menu always visible. Or there’s the way that editors like doom emacs, helix, etc do it - where pressing a common key (space) opens up a menu that shows available short cuts. I’ve always found that a good compromise, as it makes it easy to discover learn shortcuts, while also giving the speed efficiencies once you’ve learned them.

Also, have you seen [GitHub - jj-vcs/jj: A Git-compatible VCS that is both simple and powerful](https://github.com/jj-vcs/jj) ?

---

<div class="post-metadata">

**Author:** ![cryptocode](https://ziggit.dev/user_avatar/ziggit.dev/cryptocode/32/817_2.png) [@cryptocode](https://ziggit.dev/u/cryptocode)\
**Post date:** [March 6, 2025, 1:15pm UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/8 "2025-03-06T13:15:19Z")

</div>

> [@cian](#):
>
> Also, have you seen [GitHub - jj-vcs/jj: A Git-compatible VCS that is both simple and powerful](https://github.com/jj-vcs/jj) ?

fyi jj is discussed [in xit’s compat document](https://github.com/radarroark/xit/blob/master/docs/compat.md)

As for libvaxis (which I also use and really like), the readme makes a point about avoiding 3rd party dependencies.

---

<div class="post-metadata">

**Author:** ![n0s4](https://ziggit.dev/user_avatar/ziggit.dev/n0s4/32/2227_2.png) [@n0s4](https://ziggit.dev/u/n0s4)\
**Post date:** [March 6, 2025, 2:12pm UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/9 "2025-03-06T14:12:14Z")

</div>

How does one pronounce ‘xit’?

---

<div class="post-metadata">

**Author:** ![GigaGrunch](https://ziggit.dev/user_avatar/ziggit.dev/gigagrunch/32/1823_2.png) [@GigaGrunch](https://ziggit.dev/u/GigaGrunch)\
**Post date:** [March 6, 2025, 2:15pm UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/10 "2025-03-06T14:15:42Z")

</div>

My guess: Like Xi in Jinping, but with a t at the end. Git is also not a “nice” word so that would fit 😁

---

<div class="post-metadata">

**Author:** ![cian](https://ziggit.dev/user_avatar/ziggit.dev/cian/32/4359_2.png) [@cian](https://ziggit.dev/u/cian)\
**Post date:** [March 6, 2025, 3:26pm UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/11 "2025-03-06T15:26:47Z")

</div>

Oh fair, I’d forgotten that you’re avoiding third party dependencies.

I didn’t think to read the compat document, but that does answer my question.  
I like your approach to this a lot. For my purposes at the moment obviously Jujitsu is more practical, but I’m definitely going to follow your progress. This feels right.

---

<div class="post-metadata">

**Author:** ![xeubie](https://ziggit.dev/user_avatar/ziggit.dev/xeubie/32/4715_2.png) [@xeubie](https://ziggit.dev/u/xeubie)\
**Post date:** [March 6, 2025, 4:25pm UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/12 "2025-03-06T16:25:11Z")

</div>

> [@cian](#):
>
> You should start a blog

[You’re in luck!](https://xit-vcs.github.io/xitlog/)

> [@cian](#):
>
> On TUIs. I’ve used libvaxis, and I’m curious as to why you didn’t you use that.

In addition to the no third party libraries thing, I also made [xitui](https://github.com/xit-vcs/xitui) due to actual design differences. I think libvaxis differs on these points, but correct me if I’m wrong:

1. I don’t like how these UI libraries always use dynamic dispatch. You already know the widget types in advance, so why not have a user-defined union type? [Here’s what it looks like](https://github.com/xeubie/radargit/blob/56572dc19a40ff2d4f701461eea3769f9a46cf42/src/main.zig#L22) in xitui. Union types avoid unnecessary indirection / pointer chasing, and are more readable IMO. Since it is user-defined, you can still add custom widgets.
2. In xitui, widgets always render to a buffer, rather than directly to the terminal. Their parent widget then can decide to use that buffer (or not). This is really important for complex layouts and responsive design.
3. There is a generic system for tracking focus _and_ selection. Every widget knows which (if any) of its child widgets are selected, and which widget in the entire graph currently has focus. Most TUIs just don’t provide a good indication of either focus or selection. Those that do often only use color to indicate it, which is bad for accessibility.

I’m not claiming xitui is perfect or production-ready though. It’s doing a lot of inefficient stuff right now. I still have a lot of work to do before I can claim it’s a good alternative to libraries like that.

> [@n0s4](#):
>
> How does one pronounce ‘xit’?

I pronounce it like “zit”. In fact that’s how it used to be spelled (for zig + git), but I changed the spelling to make it more searchable since zit is a common english word.

> [@GigaGrunch](#):
>
> My guess: Like Xi in Jinping, but with a t at the end.

Feel free to pronounce it this way if you run into any bugs :^D I’m looking forward to the day someone makes an `ohshitxit.com` actually.

---

<div class="post-metadata">

**Author:** ![IceGuye](https://ziggit.dev/letter_avatar_proxy/v4/letter/i/b782af/32.png) [@IceGuye](https://ziggit.dev/u/IceGuye)\
**Post date:** [March 6, 2025, 6:39pm UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/13 "2025-03-06T18:39:28Z")

</div>

If you made the announcement as a reply in other’s topic, just like what the git author did for his another fun project, that would be even more hilarious. 🤣

---

<div class="post-metadata">

**Author:** ![rockorager](https://ziggit.dev/user_avatar/ziggit.dev/rockorager/32/502_2.png) [@rockorager](https://ziggit.dev/u/rockorager)\
**Post date:** [March 6, 2025, 6:39pm UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/14 "2025-03-06T18:39:57Z")

</div>

> [@xeubie](#):
>
> - I don’t like how these UI libraries always use dynamic dispatch. You already know the widget types in advance, so why not have a user-defined union type? [Here’s what it looks like](https://github.com/radarroark/radargit/blob/56572dc19a40ff2d4f701461eea3769f9a46cf42/src/main.zig#L22) in xitui. Union types avoid unnecessary indirection / pointer chasing, and are more readable IMO. Since it is user-defined, you can still add custom widgets.

This is a design consideration I’m not particularly pleased with in the vxfw portion of libvaxis…Right now everything is an `*anyopaque` for the widgets, which has been working well but also is _very_ annoying when you need to allocate small widgets just to have them work in the framework. That said, this only exists in that portion of the library. The core doesn’t use any dynamic dispatch and (if you wanted a dep) you could build off the underlying library. One design consideration that is nice about the dynamic dispatch (and defining your own VTable) is that I can define separate widgets for the same pointer just by providing a different Vtable (IE an IRC channel can have a widget to draw the name of the channel, a widget to draw the members of the channel, a widget to draw the message view, a widget to draw the text field, etc…all with the same pointer, just a different VTable).

So far, the main reason I haven’t implemented Widgets as a tagged union is because of memory - I’ve been hesitant to have an individual widget take up the space of the largest - and they can get large. I have a `ghostty` widget in the works for an embedded terminal-in-a-terminal, and the memory of a single ghostty widget is at least an order of magnitude more than a Text widget.

> [@xeubie](#):
>
> - In xitui, widgets always render to a buffer, rather than directly to the terminal. Their parent widget then can decide to use that buffer (or not). This is really important for complex layouts and responsive design.

If you haven’t looked at the vxfw portion of libvaxis, it does essentially the same thing. Each widget returns a `Surface` which is a buffer of `Cell`s, a size, and a reference to the Widget that drew it. It’s all inspired by flutter so that I could get to a single pass layout. I’ve been pretty happy with how that layout style works (Parent gives Child size constraints, child draws within those constraints and tells parent it’s final size, parent sets location). The referenced widget is then used for directing events…since we have a tree of widgets we can accurately send events up and down the tree until someone consumes it. (This gets to your third point about focus and selection, which is also implemented in the framework).

Anyhow - there are a few ways you could use the library without getting into the widgets:

- `bork` uses the input parsing and tty stuff, but implements it’s own rendering
- `flow` uses the input parsing, tty stuff, and rendering, but implements it’s own event loop and widgets
- `ghostty +show-themes` uses input, tty, rendering, and event loop, but implements it’s own drawing / widget logic
- `comlink` uses the full out vxfw framework (input, tty, rendering, event loop, and widgets)

All of that said - terminal handling isn’t _that_ complicated and it looks like you’ve done a great job so far :). Excited to see where `xit` goes!

---

<div class="post-metadata">

**Author:** ![xeubie](https://ziggit.dev/user_avatar/ziggit.dev/xeubie/32/4715_2.png) [@xeubie](https://ziggit.dev/u/xeubie)\
**Post date:** [March 7, 2025, 12:25am UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/15 "2025-03-07T00:25:54Z")

</div>

> [@rockorager](#):
>
> So far, the main reason I haven’t implemented Widgets as a tagged union is because of memory - I’ve been hesitant to have an individual widget take up the space of the largest - and they can get large.

Fair enough. In that case I would just put that particular widget’s state behind a pointer though, rather than adding that indirection to all widgets.

> [@rockorager](#):
>
> If you haven’t looked at the vxfw portion of libvaxis, it does essentially the same thing.

> [@rockorager](#):
>
> (This gets to your third point about focus and selection, which is also implemented in the framework).

Ah gotcha, it sounds like my last two points are not actually differences then. That actually gives me comfort…I second guess myself a lot so if we’re doing something similar then that’s good :^D

---

<div class="post-metadata">

**Author:** ![tamadamas](https://ziggit.dev/user_avatar/ziggit.dev/tamadamas/32/4814_2.png) [@tamadamas](https://ziggit.dev/u/tamadamas)\
**Post date:** [March 12, 2025, 8:10pm UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/16 "2025-03-12T20:10:33Z")

</div>

Is that my dream project?  
I pretty sure I want to use it and help you developing it.

My story how I tried and failed with jj-vcs

> **[Why is so hard to simply push to Github? · jj-vcs/jj · Discussion #5976](https://github.com/jj-vcs/jj/discussions/5976)**
>
> I've read Steve books, readme, docs and seems I know how to work with jj but every time I need to push it fails with several reasons: Empty commits Missing description Missing anything else... What...

Long story first =\> they just have failed (as for my needs completely) with supporting one ever thing they must be supporting =\> git push (80/20 rule) so business will never care about inner if 20% just failed

And TUI! I really want working with all that (I remember creating my first website on Nokia small screen phone with php, html, css) and now I pretty sure the TUI must support Android and Iphone

So, what are in current priority to implement?

---

<div class="post-metadata">

**Author:** ![tamadamas](https://ziggit.dev/user_avatar/ziggit.dev/tamadamas/32/4814_2.png) [@tamadamas](https://ziggit.dev/u/tamadamas)\
**Post date:** [March 12, 2025, 8:47pm UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/17 "2025-03-12T20:47:59Z")

</div>

@xeubie By the way, could we move on organization? I pretty sure it helps on maintaining things right way more than forking several repositories.

I’m sure it’s pretty awesome you’re doing

---

<div class="post-metadata">

**Author:** ![xeubie](https://ziggit.dev/user_avatar/ziggit.dev/xeubie/32/4715_2.png) [@xeubie](https://ziggit.dev/u/xeubie)\
**Post date:** [March 13, 2025, 2:00am UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/18 "2025-03-13T02:00:54Z")

</div>

> [@tamadamas](#):
>
> So, what are in current priority to implement?

Things are moving fast. I added symlink support today and fixed a bunch of windows issues. Yesterday I made the TUI waaaay faster. The day before that I added force pushing. I’m all over the place.

As for my to-do list, it’s pretty long. A lot of it is just catching up with git: submodule support, rebase, revert, stash, etc. I also need to implement universal undo, a big feature enabled by [xitdb](https://github.com/xit-vcs/xitdb). It’s gonna kick ass.

> [@tamadamas](#):
>
> By the way, could we move on organization?

I’m not sure what you’re asking, can you rephrase it?

---

<div class="post-metadata">

**Author:** ![tamadamas](https://ziggit.dev/user_avatar/ziggit.dev/tamadamas/32/4814_2.png) [@tamadamas](https://ziggit.dev/u/tamadamas)\
**Post date:** [March 14, 2025, 7:43am UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/19 "2025-03-14T07:43:55Z")

</div>

Organization is about GitHub Organization with a name like “xit-vcs” and all related repositories in it.

> **[About organizations - GitHub Docs](https://docs.github.com/en/organizations/collaborating-with-groups-in-organizations/about-organizations)**
>
> Organizations are shared accounts where businesses and open-source projects can collaborate across many projects at once, with sophisticated security and administrative features.

---

<div class="post-metadata">

**Author:** ![JPL](https://ziggit.dev/letter_avatar_proxy/v4/letter/j/a9adbd/32.png) [@JPL](https://ziggit.dev/u/JPL)\
**Post date:** [March 14, 2025, 8:30am UTC](https://ziggit.dev/t/xit-a-version-control-system/8880/20 "2025-03-14T08:30:58Z")

</div>

hello,  
can we do that please.

```zig
git commit -m "maj_20250313-12:15"

```

[Next page](https://ziggit.dev/t/xit-a-version-control-system/8880.md?page=2)
