The display weirdness (e.g. the Z shell's percent character showing up) that you are seeing in your demo is because you are putting the terminal line discipline into raw mode, raw mode of course does not do CR-before-LF stuffing, and there's some confusion in the code as to when it does and when it does not explicitly emit CRs.
This is not intended to be an insult of any sort, but I am pretty sure the use of LLM to write this was not so moderate, but I have nothing against it, you have a working project. I have done the same with projects similar to this.
I use lazygit (also written in Go) and magit a lot, they are quite nice. For GUI, I use Git Cola.
I wish the demo GIF was something more complex, perhaps adding & removing a particular chunk and committing it or something like that.
Yep. Having made the switch, I now see git (as a user-facing VCS) as a dead end.
It’ll take awhile for people to switch, but I think it will happen eventually. Invisible git compatibility means we don’t have to get everyone to switch all at once, and the benefits of primitives more aligned with the mental model of what we’re trying to do are undeniable.
No, git is not going away. It's not radically rejected. To the contrary, Jiujutsu builds upon git, and remains backwards-compatible, within reason.
It's like using Zig instead of C. You get a much better, handier tool, but you can interact with C very easily, transparently. You can mix and match.
Things like Monotone and Darcs were exquisite research projects, they tested many important ideas, but could not hope to become the standard. Jiujutsu does have this chance.
Problem with GitHub is that the VCS is in the name, so they would have to re-brand themselves (which might end up in losing loads of users) before they start supporting an alternative VCS.
I agree anyways, replacing Git is or would be a very difficult task in many cases.
That said, let us say I have a team of 3 people and we are starting a new project. We can definitely choose something other than Git, like Darcs (or later Pijul). If we use a project management software that only supports git, however, then that would be a very limiting factor. We probably would just continue using git, or use another project management software or I have no idea. I have used Git most of the time ever since I started using VCSs.
Git as a backend (with some amendments) is lovely and brilliant. Git as a front end is legendarily difficult to use.
Jujutsu has all the advantages with none of the downsides and—unlike the alternatives—adoption doesn’t need to happen all at once. Every single person who I’ve convinced to give it a meaningful shot has fully converted. That speaks volumes.
any advice on learning jujutsu? i keep bouncing off tutorials and blog posts about it. i’ve had a difficult time trying to map the github-centric branch-based workflow to jj. i’m sure part of the problem is “don’t try to use it like git”, but i haven’t gotten to the aha moment where it clicks.
You can 100% use it with that workflow, and there is no problem in doing that. You could use other workflows but those are things you can pick up as you gain more familiarity.
What I would focus on is what it enables you to do that’s hard in git: editing and revising commits that you’re iterating on, extracting out a large block of work into smaller commits, or splitting unrelated work out into a separate branch without needing to do a bunch of stashing, jumping around between branches, rebasing, etc.
Hell, even just being able to switch branches without having to do a wip commit or mess around with the stash is worth the price of admission to me. And having all of my work tracked during a long rewrite even if I don’t think to make checkpoint commits along the way.
But yeah, I’d 100% focus on what new superpowers you can add to your existing workflow before trying to actually change your workflow.
Just dive in and force yourself to use it. Keep the branch based workflow until you are more comfortable with the tool. Then try more exotic workflows.
jj git fetch to pull upstream main.
jj rebase -d main to rebase your branch on main
As you add commits to your branch jj bookmark move to update the branch then jj git push -b branchname to push it to remote
Also I highly recommend a couple neovim plugins: hunk.nvim for splitting commits and jjdiffconflicts.nvim for resolving conflicts.
I yearned for something like jj before I knew of magit. I was very used to the hg way of doing things and so git is a downgrade. But with magit I'm satisfied enough that I haven't felt a need to switch. Going back to typing commands in a terminal felt backwards. And magit makes a lot of things easy, like splitting commits (u on the hunk and then c e c -a c), moving commits from one branch to a new branch (A s), and moving commits from one branch to another (r s). What makes jj better than magit?
jj’s first class conflicts and the way it handles rebase offers a UX that’s not possible with git.
Like with jj rebasing a stack of branches is just a single command. In git you would have to rebase the branch at the top and then hard reset each branch pointer one by one. jj’s rebase is just more powerful than git’s. Like it doesn’t just rebase a linear series of commits it rebases merge commits, other sibling branches, etc… it’s absolutely mind blowing.
I'm a long time magit user and jj is basically just how I just git! At least close enough. I owe most of my git proficiency to magit. I understand how people are confused by just using the CLI. So I'm all for higher level tools like jj. Don't think I could give up the magit interface, though, unless there's something similar for jj?
From the GIF in the repo I think it's somewhere between CLI and TUI -- it's interactive but does not try to draw windows/surfaces in the terminal. But the borderline is fuzzy, so yeah
Yeah, “terminal-based CLI” might’ve been a fuzzy phrase — I meant it’s an interactive command-line tool, not just a one-shot command like most git subcommands.
It’s somewhere between a minimal TUI and a CLI — no full-screen UI, but it does guide the user interactively.
Thanks for the discussion, made me realize I should clarify that better in the README.
Yeah, I kinda thought the same when I picked the name.
Didn’t expect it to trip people up this much though — might rethink it if it becomes a real issue. Thanks for the honest feedback!
I'm kind of relieved to see that it calls out to the native git binary. There is a popular pure-Go git implementation that is in my experience very slow.
I've used it - it's lacking a ton of features. Another commenter in this thread said it's very slow compared to the git CLI, which is not surprising given that git is written in C.
I’ve used it for a production service. I thought it was surprisingly robust/featureful. There was one issue I ran into, but IIRC it was a limitation in the library’s filesystem abstraction, not a missing feature.
I would have used libgit2 myself in any languages. If bindings do not exist, I would have made the bindings first. There is no way I would have called out to an external program.
Someone mentioned https://github.com/go-git/go-git. I would have definitely used it unless there are better alternatives. If - as someone who claimed - it turns out it is slow, I would have created my own bindings to libgit2 still, most likely.
Binding to C in Go is a bad idea typically. There’s performance overhead, but more importantly your library (and everything downstream) also loses the ability to do nice things like fast compile times or easy cross compilation. You also likely introduce a runtime dependency on libc if not libgit2, so you have some DLL hell to deal with.
How do you define significant? It is noticeable as compared to C. It is nothing compared to Python.
> Are there any benchmarks on this?
You will see an additional ~20ns per call (assuming the gc compiler; tinygo, for example, can call C functions as fast as C can). In other words, you're not ever going to notice unless you're making millions of calls in a hot loop. The bigger problem in a highly concurrent environment is that blocking C functions can start to mess with the scheduler if they are slow to return. You, again, would never notice in a program of this nature, though. The feature is there to be use. It being a "bad idea" is nonsense.
Some added pain in compilation is, fairly, a tradeoff to consider. But that's just because C compilers, for the most part, aren't very good. It is not like those problems go away if you use C instead.
Yeah, but for this project, why would you choose (as others stated they would or prefer) to call out to an external program instead of using https://github.com/libgit2/git2go (libgit2, FFI) for example? For what it is worth, there is also a pure Go implementation: https://github.com/go-git/go-git (pure Go).
Keep in mind the initial comment, which is "I would have used libgit2 myself in any languages.", and they claimed it is a bad idea due to performance, as opposed to calling out to an external program.
No, I want people to be informed well, and that requires me to hear their side so I can dispute them.
Many people has said they are thankful it calls out to "git" instead of using FFI, which I think is weird, but then there are others who go ahead and say that it is a worse thing to do, and I want people to know that no, it is not.
Yep, ggc is a wrapper around the git CLI — intentionally so.
I chose to shell out to git because it's fast, stable, and has great cross-platform support. Tools like go-git and libgit2 are interesting (and I’ve looked into them), but they come with their own tradeoffs like performance, features, and build complexity.
That said, I totally get the curiosity — thanks for the discussion!
* https://github.com/bmf-san/ggc/blob/9e93ef8a87973cab916e37a9...
* https://github.com/bmf-san/ggc/blob/9e93ef8a87973cab916e37a9...
In particular, C Shell (csh) and Tcsh uses "%" as the prompt character. Common in BSD systems.
Of course you can customize Zsh (or Bash) to show "%", too.
Edit: never mind, I noticed it when he quit "ggc". My bad. :)
I use lazygit (also written in Go) and magit a lot, they are quite nice. For GUI, I use Git Cola.
I wish the demo GIF was something more complex, perhaps adding & removing a particular chunk and committing it or something like that.
But these days, I’ve moved on to jujutsu, a git-compatible version control system with much better primitives than git.
If you haven’t tried jj, I highly recommend it. The first-class conflicts and powerful but simple primitives for editing the commit graph are amazing.
It makes stacking branches an absolute breeze compared to git. And since it is git compatible nobody on your team has to change how they work.
It’ll take awhile for people to switch, but I think it will happen eventually. Invisible git compatibility means we don’t have to get everyone to switch all at once, and the benefits of primitives more aligned with the mental model of what we’re trying to do are undeniable.
It's like using Zig instead of C. You get a much better, handier tool, but you can interact with C very easily, transparently. You can mix and match.
Things like Monotone and Darcs were exquisite research projects, they tested many important ideas, but could not hope to become the standard. Jiujutsu does have this chance.
I agree anyways, replacing Git is or would be a very difficult task in many cases.
That said, let us say I have a team of 3 people and we are starting a new project. We can definitely choose something other than Git, like Darcs (or later Pijul). If we use a project management software that only supports git, however, then that would be a very limiting factor. We probably would just continue using git, or use another project management software or I have no idea. I have used Git most of the time ever since I started using VCSs.
Jujutsu has all the advantages with none of the downsides and—unlike the alternatives—adoption doesn’t need to happen all at once. Every single person who I’ve convinced to give it a meaningful shot has fully converted. That speaks volumes.
What I would focus on is what it enables you to do that’s hard in git: editing and revising commits that you’re iterating on, extracting out a large block of work into smaller commits, or splitting unrelated work out into a separate branch without needing to do a bunch of stashing, jumping around between branches, rebasing, etc.
Hell, even just being able to switch branches without having to do a wip commit or mess around with the stash is worth the price of admission to me. And having all of my work tracked during a long rewrite even if I don’t think to make checkpoint commits along the way.
But yeah, I’d 100% focus on what new superpowers you can add to your existing workflow before trying to actually change your workflow.
jj git fetch to pull upstream main.
jj rebase -d main to rebase your branch on main
As you add commits to your branch jj bookmark move to update the branch then jj git push -b branchname to push it to remote
Also I highly recommend a couple neovim plugins: hunk.nvim for splitting commits and jjdiffconflicts.nvim for resolving conflicts.
jj’s first class conflicts and the way it handles rebase offers a UX that’s not possible with git.
Like with jj rebasing a stack of branches is just a single command. In git you would have to rebase the branch at the top and then hard reset each branch pointer one by one. jj’s rebase is just more powerful than git’s. Like it doesn’t just rebase a linear series of commits it rebases merge commits, other sibling branches, etc… it’s absolutely mind blowing.
https://ofcr.se/jujutsu-merge-workflow/
Also, good point about the demo GIF. I’ll try updating it with a more complex example. Appreciate the feedback!
I'm curious how other engineers manage their Git setup and workflows in practice. Specifically:
1. Primary Git client: Do you mostly use the CLI, a GUI tool, IDE integration, or custom scripts? And why?
2. Workflow shortcuts: Do you follow the classic `git add → commit → push` step-by-step, or do you bundle them into a single alias or script?
3. Interactive tasks: How do you handle more interactive tasks like staging hunks, resolving conflicts, or browsing history?
4. Alias and script maintenance: If you maintain custom aliases or functions, how do you keep them organized and shareable?
I’d love to hear what works for you (and what didn’t). Tools, habits, setups — anything goes!
2. I have two aliases: gs for "git status", and gap for "git add -p"
3. I use VSCode for resolving conflicts, and GitHub or gitk for browsing history
4. No maintenance. I add them by hand if they're missing
2- no aliases, I want to be aware of every step
3- for browsing history I'll go to Github (at my current job), I think it's a more pleasant experience
4- I don't apply
It’s somewhere between a minimal TUI and a CLI — no full-screen UI, but it does guide the user interactively.
Thanks for the discussion, made me realize I should clarify that better in the README.
holdup... is this just a wrapper around git?
oh my god. you have just wrapped standard git CLI. well, this is dissapointing.
> aims to be fully compatible with git, all the porcelain operations are implemented to work exactly as git does
written in pure go, therefore with a go native api.
I've never tried to use it, but it does look quite impressive to me.
[0] https://github.com/go-git/go-git
Someone mentioned https://github.com/go-git/go-git. I would have definitely used it unless there are better alternatives. If - as someone who claimed - it turns out it is slow, I would have created my own bindings to libgit2 still, most likely.
How do you define significant? It is noticeable as compared to C. It is nothing compared to Python.
> Are there any benchmarks on this?
You will see an additional ~20ns per call (assuming the gc compiler; tinygo, for example, can call C functions as fast as C can). In other words, you're not ever going to notice unless you're making millions of calls in a hot loop. The bigger problem in a highly concurrent environment is that blocking C functions can start to mess with the scheduler if they are slow to return. You, again, would never notice in a program of this nature, though. The feature is there to be use. It being a "bad idea" is nonsense.
Some added pain in compilation is, fairly, a tradeoff to consider. But that's just because C compilers, for the most part, aren't very good. It is not like those problems go away if you use C instead.
Keep in mind the initial comment, which is "I would have used libgit2 myself in any languages.", and they claimed it is a bad idea due to performance, as opposed to calling out to an external program.
Which, as before, is nonsense.
You want more nonsense...?
Many people has said they are thankful it calls out to "git" instead of using FFI, which I think is weird, but then there are others who go ahead and say that it is a worse thing to do, and I want people to know that no, it is not.
What's in it for them?
I chose to shell out to git because it's fast, stable, and has great cross-platform support. Tools like go-git and libgit2 are interesting (and I’ve looked into them), but they come with their own tradeoffs like performance, features, and build complexity.
That said, I totally get the curiosity — thanks for the discussion!