In California, it's capped at a knowable amount when you buy the home and pegged at the sale price. You know what it is and what it always will be when the transaction happens. The people whom have owned a house now worth a million for 30 years probably pay a few grand a year and always have. Dry taxing the technical value of their assets today would destroy millions of families. The point is that dry taxation is generally pretty stupid.
HN user
schacon
works at GitButler. loves kittens, ruby and git.
Love it.
In fact, we should have expanded it to be a "millionaire tax" where everyone who has a home worth more than $1M needs to pay a one time $50k+ tax to the highly efficient state government. I'm sure they can easily figure out how to sell a small fraction of their home to cover it.
If there is one thing that history has proven, I think it's how valuable dry taxation is for everyone in the long term.
Relicensing under any other license, including the LGPL, is exactly the same thing. Either the reimplementation copies protected expression, in which case it would be required to be GPL-2.0-only, or it does not, in which case we can choose the most fitting license.
If you believe that using an MIT license is not correct, then you defacto also believe that using an LGPL license is not correct.
Would you be happy for someone to do the same with the GitButler source code?
Honestly, that would be pretty awesome. We would be flattered.
Nice, I haven't dug into this yet. If we can get this usable, it would be pretty cool to have a small lib or a series of much smaller, directed libs that can be used by simpler interfaces and you can just compose the parts you need.
Not yet. I have a PR with a WASM experiment based on an earlier build, but it's not integrated. It's on my list of things to try. I _did_ get it working for some things, so it's clearly possible, but I need to put some more effort into it.
Well, there's lots of really interesting opinions here from a lot of armchair lawyers.
To clarify, my stance on this is that the reimplementation did not copy protected expressions (Jplag reports less than 1.8% max similarity between the codebases), it's done in good faith, and it's what's best for the broader Git ecosystem (assuming Grit even becomes usable, which it's currently not purported to be).
From a copyright standpoint, however, only the first argument there is relevant. Grit is an independently authored implementation of Git-compatible behavior, with negligible similarity to Git source code.
I think antirez summarized the situation quite well and I broadly agree with his position: https://antirez.com/news/162
I think that those in the community who know me and have worked with me in the Git and open source communities for the last 20 years know that my intentions are to contribute, share and foster innovation and learning. Many of the main authors of the Git source code are friends of mine and I have no intention to steal anything from anyone, only to make their great ideas more broadly useful.
GitButler's source code is available, so we're not asking you to trust us much at all.
A feature complete, reentrant, linkable library. Reading the article often helps with questions like this.
As mentioned, we also work on the Gitoxide project and Byron is a member of our team. We are well aware of all large community efforts and we're also cohosting the Git Merge conference this year.
There is a recent effort to vibe-loop more Git into Gitoxide, which is interesting:
https://github.com/GitoxideLabs/gitoxide/pull/2538
I still think that this is a project that can have value with a little more work. This announcement is merely a milestone, not the end product. I wasn't sure it was really possible to do, even halfway through the project. There has been a lot learned and there is a lot to learn, but I think there are useful applications for both a high quality, hand crafted, opinionated partial Git library (Gix) as well as a vibed, fully implemented, partially sloppy LLM Git library (Grit). We think it's worth exploring and investing in both options for now.
Also, I am the exec involved and I've done quite a lot for the Git community over the years. I would never try to have my "own copy" of it, that's ridiculous. I wrote and open sourced the Pro Git book (https://git-scm.com/book/en/v2) and Git community book before it (https://schacon.github.io/gitbook/index.html), I created the official Git website (https://git-scm.com), I cofounded GitHub which hosts nearly all open source in the world, I have evangelized and supported the Git ecosystem for almost 20 years now. I restarted and funded development of libgit2 15 years ago, which you could similarly argue was an exec trying to have our "own copy" of Git under a more permissive license and would have been a similarly ridiculous argument.
I think Byron (Gix author/maintainer) is one of the most excited people about the Grit project.
Gitoxide is great and we will continue to push it forward. Grit is an orthogonal project. Perhaps we can use one in the other or maybe Grit goes nowhere. But we thought that a small investment in a different approach is worth the effort.
I see it differently. I look at it as if I had written this code myself, using this same approach. Look at the docs, look at the tests, look at the source, implement something that is interactively compatible but a very different approach.
For example, this is exactly what I did when I tried to get SSH commit signing working properly in GitButler:
https://blog.gitbutler.com/signing-commits-in-git-explained
You can see in the post that I dug through the C source to figure out how it was canonically done and then implemented something that accomplished the same thing in Rust but without copying source code.
There are some similarities between the Grit Rust source and the Git source, but it's mostly around time/formatting type things or byte offset type things needed to make packfile parsing and whatnot work, but as far as I can tell, there is no straightforward copying of code. The approach needed to make this a reentrant, memory safe, library driven codebase is so different that copying is generally not useful. But nobody can _guess_ how packfiles or reftable binary formats are specified, since they're not really documented. I'm aware of this because I'm pretty sure I _personally_ am one of the only ones who has ever attempted to document the packfile binary format: https://schacon.github.io/gitbook/7_the_packfile.html
You have to read the source. Which means that libgit2 and Gitoxide and every other Git reimplementation is also "license-washing" per this definition because they also had to reference the Git source to see what the technical specification is.
If you find any code in Grit that is clearly line-for-line copied, please point it out and I will replace it. But the Git source is the Git specification and every reimplementation, LLM or not, is forced to use this approach to build anything compatible.
To be clear, I 100% did not make libgit. I did help the libgit2 project get off the ground.
I'm assuming you didn't read the article, since I'm pretty sure I covered all of this, but I'm happy to respond.
Don't bother.
It's probably not for you. It's slower, more obtuse, more bloated, less capable, exponentially less scalable at any size. Canonical Git is better in every way, except being a linkable library.
Even in the arena of being linkable libraries that can do Git stuff, both Gitoxide (Rust) and libgit2 (C which has git2 crate Rust bindings) are both better, they're just not feature complete. That is the only point of this project.
We're choosing a license that is usable by the entire community. Our goal is a linkable library, which makes GPL impossible. If we had chosen to go with LGPL or GPL with linking exception (like libgit2), it would have the same issue of changing the license, so we went with whatever was the most permissive so everyone could use it for anything if they wish. This has nothing to do with business - I hope I can get the project to the point where Jujutsu or whomever can use whatever is valuable here for whatever they want.
We clearly learned from how Git does operations and emulated it in order to function interoperably, the same way that Gitoxide and libgit2 have, and released it under a license that would be the most valuable for people wanting to use a linkable library, the same way that Gitoxide and libgit2 have.
Gitoxide is also developed primarily by Byron, who also is part of the GitButler team. We're pushing both projects forward.
I'm happy to take contributions if you want to throw some tokens at it. Bug reports would be amazing, since I haven't tested it for real very much (enough to know you can do basics).
I want to get it to the point where we can replace fork/exec'ing to an unknown Git binary or having said binary be an external dependency for GitButler. The networking stuff (push/fetch) is currently an external dep for both GitButler and Jujutsu (and pretty much every other Git-based tool in the world). I'm pretty sure I can get the project good enough at these networking ops (including all the hairy credential stuff) to be able to not need those fork/exec calls.
I started the project as Gust, but felt like Grit was such a better name. I asked Tom if I could boot the name back up again because I always liked it and he said it was fine.
Also, I worked on the Ruby Grit pretty extensively during the early days of GitHub, so hopefully I earned the right to carry on the mantle. :)
I would not use this except to help us test it if interested. I'm announcing it because it's interesting and a milestone in the breadth of test coverage it can pass. It almost certainly cheated on a bunch of those tests and is not feature complete yet.
The author of gitoxide is also working on GitButler (who worked on this project) and we're pushing both projects forward and actively using and developing Gitoxide as well. This is simply a different and hopefully complimentary approach to the same problem.
libgit.a isn't reentrant. It will call `die()` on many errors. If you link to it in a long running binary, it will kill your process on error.
Libgit2 is meant to address this and I was heavily involved in the development of that project 15 years ago. It's great but it's not feature complete and it's development is also completely separate from git development, so it's out of sync and constantly struggling to keep up.
My intent with this project is not to replace Git in any way. I don't care about the CLI part of this project.
The point is to provide a feature-complete reentrant linkable library. Even if it's an ugly and slow one, this is still the only one thing that exists that covers those points - Gitoxide and libgit2 are both awesome but they are not feature complete.
I would also be interested.
I haven't dug into this at all yet, nor have I tried to optimize the size (or really, anything else).
However, the library part will be less than half of this - a lot of code is spent on the CLI specific stuff and would not be part of the library, which is mostly what I care about for the purposes of this project. The CLI part is just to try to prove the point that it actually does what Git does. The library part is what might be useful in that nothing else exists that does all of the things that it does (provide a reentrant linkable library that is feature complete with Git).
It's not for Rust, it's for Library.
Well, it's sort of for Rust. GitButler is written in Rust and Jujutsu is written in Rust and we're both depending on fork/exec'ing to an unknown Git binary with no linkable library and no control over the subprocess to do a range of networking stuff. Neither Gitoxide or libgit2 are capable of this either, as much as I love and support those projects.
This project is entirely about providing a feature complete (even if sloppy) library implementation of Git, which does not otherwise exist.
I addressed this in the post, but Git has no linkable library and never has. If you want to do even something small, you need to fork/exec a process and communicate with it via stdin/out. Or completely reimplement it and all of the edge cases - for example, reading even one object can be either loose (easy) or in a packfile (much more difficult). Reading a reference (what SHA does a branch point to) can be in a loose file, a packfile, or a reftable. etc.
There is no way anyone would ever use this for it's CLI - it will almost certainly always be slower and worse in every way, even if I get it stable (which it's currently not). You can use libgit2 (a project I also helped kickstart), or Gitoxide (a project GitButler also currently helps drive) - they are faster and better in nearly every way, but they are not feature complete.
This isn't for the person using Git. This is for someone trying to build a tool that wants to use parts of Git, which is different.
Git is awesome in lots of ways. As a data storage layer and as a transport protocol, it's pretty great. The porcelain was built for a different era and is slow to adapt. Originally, Git was meant to just be these primitives and everyone was supposed to write their own "porcelain" or SCM on top. We're doing that and then some - creating new standards for more metadata, real time communications, built in review, etc. If anything, we're going back to the original point of git and doing what Linus wanted other people to do in the first place - write a good SCM for their workflows on top of the foundation he started.
Ah, I see. You missed the part where that was funny.
I would like to take this opportunity to kindly inform you that I wrote that post, as I write all of the blog posts on our blog (and everywhere else I write). You will never see something with my name on it that was written by AI. Thanks.
Actually, it is. We're currently leading a conversation among several players in this space to agree on a metadata standard that helps make attaching, collaborating on and transmitting information like this simple, extensible and scalable.
Keep an eye on our blog to see how we're doing this, and how we're doing it in a way that hopefully the entire community joins us in a way where we're not all reinventing the same wheels.
I'm trying not to comment on too many of these, but this one is interestingly wrong to me, so why not indeed?
GitButler came about many years ago because I have been using Git for almost the full 20 years of it being around and I thought there could be a better way to do the things it's trying to solve for us. I want version control to do more for us, easier, faster and smarter. Git is still pretty dumb. Plus, now, everything in the dev workflow is changing - it's an interesting problem to think about what a _great_ toolset for how we'll all soon be developing software will be.
As a _single_ example - agents can't use interactive editors, yet _so many_ of the powerful parts of Git absolutely _require_ it. Agents can't interactively rebase, meaning they can't very effectively squash, amend, reword, reorder, absorb. They can't very easily interactively add. They are middling at best when it comes to stacking branches. Git is designed to send patches over email and agents are not concerned with that.
I would love to debate all of the lessons learned about the history of Git, but I was around for all of that. I know why Git was started, I know what it was meant to do, I understand how it's evolved. I still think there are a lot of interesting things that we could have in our change control tooling and Git is not the perfect solution.
Nearly everyone in this thread suffers from the same basic local maxima blindness that you do. Git is great, GitHub made it more valuable. But maybe the answer to the papercuts we've constantly been dealing with for decades isn't faster horses. (To, you know, mix metaphors)
Just to clarify (and we do say this when you run `but setup`), the `pre-commit` hook is needed because of the way that we manage commits - we allow for multiple parallel applied branches, which Git cannot do. The way we accomplish this is to maintain a hidden 'megamerge' commit (as JJ would say). All Git commands work fine the way we're doing it except 'git commit', which is not aware of our operating model and will commit on top of our megamerge, which is problematic. So we install pre-commit to protect against getting yourself in a poor situation by using both Git and GitButler interchangeably.
It's not difficult to "escape" - using `git checkout` will tear everything down properly - that's the only task of the `post-checkout` - to determine that you want to go back to using vanilla git commit tooling and remove our shims.
We also don't have a prepare-commit-msg hook - our commit tooling will inject an extra Change-Id header (of the same format and interchangeable with Jujutsu) but that affects nothing that vanilla git cares about.