Hacker News new | past | comments | ask | show | jobs | submit login

In my opinion github.com/go-git/go-git is a very high-quality project. Just because it doesn't solve some super-specific use-case that you have, doesn't mean the project isn't good. It's open source, have you tried opening a pull request to solve your own issue?



In truth it's a bit of a tire fire. You're better off shelling out to git in almost all cases.

I tried using it to automate some simple git workflows and found pitfalls everywhere.


Sorry to hear that, but go-git is good enough to be useful to Vault, Pulumi, kubernetes/test-infra, and many other projects which directly import it.

Some folks seem to expect it to be a feature-complete library-usable Go re-implementation of the entirety of Git, despite it being (afaik) largely unfunded / volunteer-driven in recent years. I don't think that's realistic. And yes in many use-cases it may indeed make more sense to shell out to `git`, there's nothing wrong with that.

In any case, in my direct experience, the go-git maintainers do happily accept helpful PRs.

It just seems really weird to me to see folks trash go-git, while simultaneously cheering this new gogit project which is just 400 lines and intentionally by design/scope contains only a tiny fraction of go-git's functionality.


> go-git aims to be fully compatible with git, all the porcelain operations are implemented to work exactly as git does.

It literally says this on the tin, yes. But it's not. I'm simply providing my own experience and a disclaimer.

Sure, they "happily accept helpful PRs" but the code is so very complex and many paths have horrible performance that it's an incredible uphill battle. To be clear I'm not simply shitting on this library, I'm saying it's not a reasonable choice over just using git directly, and is unlikely to ever be.

I haven't made any comment on TFA so while I'm not cheering it on, I do think the spirit is correct: just do the thing you need to do, don't try to be feature complete, just solve the task at hand.


I interpret "aims to be fully compatible" as meaning the operations it implements are intended to be compatible with how Git implements those operations. I do not interpret this statement as saying they implement all features of Git.

They offer a document which directly shows what is and isn't supported, and it specifically notes quite a few things that aren't supported yet: https://github.com/go-git/go-git/blob/master/COMPATIBILITY.m...

The godoc also says right upfront it "nowadays covers the majority of the plumbing read operations and some of the main write operations, but lacks the main porcelain operations such as merges." - https://pkg.go.dev/github.com/go-git/go-git/v5#pkg-overview

> I'm saying it's not a reasonable choice over just using git directly, and is unlikely to ever be.

OK, that's apparently true for your use-case. But again, what go-git implements is directly useful to a number of very popular projects, as well as literally two thousand less popular ones.

I find the exported functionality to be high quality, at least for my own use-case. I'm not commenting on the code quality. If I need a shed for bikes, and someone is giving out free but ugly bikesheds, I'm thankful. I don't complain about the color of the bikeshed.


It's useful for toy projects or narrow stateless use cases, like testing or fetching something one time, like in Terraform, but as soon as you have to deal with real world scenarios related to actual distributed version control, the wheels completely fall off.

Can you use it to implement a git remote? No. What about to write some commits? Also no. What about a read-only client? Nope.

It only works well if you have a narrow use case, and only works predictably if you are in full control of the repository being interacted with. Otherwise it is simply going to cause more pain than just using git directly. Look at the open issues, the open issues related to it in projects that depend on it.

You clearly have a horse in this race and that's fine, if it works for you, great. But I don't recommend it. And no amount of lobbying on your part is going to alter that reality. If you're doing serious things, use git directly, and if you're not, it's probably simpler to write it yourself.

And lastly, the exported functionality is not high quality. It performs poorly in many scenarios where shelling out to git does not, and it breaks with any sort of complicated set up.


not really. its littered with interfaces, in some cases many levels deep, which in Go is an anti pattern. original author clearly came from Java or some other deeply OOP language. also:

> super-specific use-case

uh, "git diff" is specific?


If I understand your issue correctly, it's `git diff --cached` that you're specifically looking for, not just `git diff` in general?

Your expectation seems to be that someone has already implemented this in Go for you, for free, but this is not the case. Why is this your expectation, and what does complaining about it accomplish?


> If I understand your issue correctly, it's `git diff --cached` that you're specifically looking for, not just `git diff` in general?

incorrect. I am simply looking for a normal "git diff", which compares the index with the working directory. shocking this is not available out of the box, hence my issue.


object.Tree has a Diff() method. You can get an object.Tree of any commit hash from a Repository with its TreeObject() method. I don't recall offhand how to get an object.Tree of the working directory or index (perhaps from the Repository.Storer?) but worst-case you could just create a new commit in order to get a hash and then run the diff.

The package is more read-oriented than write-oriented; the docs specifically say it "covers the majority of the plumbing read operations and some of the main write operations". If you're trying to diff working directory modifications, that's a write-path use-case since it implies files are being changed / you're not trying to diff two pre-existing commits.

(edit: removed some text based on an initial misreading of your statement.)


> You can get an object.Tree of any commit hash from a Repository with its TreeObject() method.

OK, but I am not dealing with a commit, as mentioned in the issue and my previous comment, I am dealing with THE INDEX and working directory, not a commit.

> I don't recall offhand how to get an object.Tree of the working directory or index (perhaps from the Repository.Storer?)

right, so you can see how its not as easy to hand wave away the problem as you initially thought.

> worst-case you could just create a new commit in order to get a hash and then run the diff.

no, I am not making a commit just to diff the working directory. would you tell someone to do that with the command line tool as well?

> The package is more read-oriented than write-oriented; the docs specifically say it "covers the majority of the plumbing read operations and some of the main write operations".

cool, we are talking about a read operation, no writing is being done.

> If you're trying to diff working directory modifications, that's a write-path use-case since it implies files are being changed / you're not trying to diff two pre-existing commits.

no its not. I am not writing to anything, only reading.


> no, I am not making a commit just to diff the working directory.

OK, you do you. I say it depends on the situation: if this is a throwaway clone (especially an in-memory one), creating a commit is harmless. I mean it's certainly not an ideal solution, but at the end of the day it solves the problem at hand.

> would you tell someone to do that with the command line tool as well?

It's not my library, I didn't design it, I'm just trying to provide a solution to the problem you posed. If you don't like that solution then, well, OK? Shell out to `git` and call it a day, or write your own `git` implementation for scratch, or send go-git a PR. Any of these would be more productive than complaining about how a free open source library doesn't provide a solution to your use-case.

> I am not writing to anything

Clearly you've written to the files in the working directory, otherwise your diff would be blank.

Again, it's a read-path oriented library. If you're writing to working directory files, your use-case may not be aligned with that of the package authors.


> creating a commit is harmless. I mean it's certainly not an ideal solution, but at the end of the day it solves the problem at hand.

youre making my arguments for me here. youre essentially saying the library is so poorly designed that the "easiest" solution is to create a commit, rather than actually just diffing the worktree directly.

> Shell out to `git` and call it a day, or write your own `git` implementation for scratch

again, making my arguments for me. youre essentially saying the library is so poor, that is cant support simple use cases and it would be easier to shell out to Git than to write a program that diffs the worktree.

> a solution to your use-case.

I would say its a solution to essentially every command line user. how many people DONT use git diff?

> Clearly you've written to the files in the working directory, otherwise your diff would be blank.

the diff it not writing anything. the issue is not "how do I write to a file", that can already be done with the standard library.

> If you're writing to working directory files

writing to files it done outside the scope of the Git package. the Git package is only needed to handle diffs that were done with some other tool.

> your use-case may not be aligned with that of the package authors.

git diff?


I didn't say that was the "easiest" solution, or ever imply it. Don't put quotes around words I didn't say. That's really not cool.

The library is designed for use-cases like getting git metadata or contents from git repos. IIRC, the previous main sponsor (creator?) was a product that let you run SQL SELECT queries against git repos. There's no need to interact with the working tree at all in that type of use-case, so why would they spend a bunch of time implementing diffs for it?

If you're trying to use this library for an IDE, or something else like that where arbitrary modifications are made to working dir files, you're going to have a bad time. The library simply wasn't created to do what you want it to do. That doesn't mean it's bad or useless. It's directly imported by Vault, Pulumi, k8s test-infra, etc because its use-case is aligned with what these projects need.

Personally I think it's cool that I can use go-git to clone a git repo to memory and then perform programmatic read operations on the repo's contents. That's useful to me. It's not useful to you, and that's fine, but clearly we have different opinions and expectations around community-driven FOSS software projects.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: