I’m Julien and I built an alternative CLI for Git : gut.
Even if I haven’t been coding for a long time (I’m in the first year studying computer science), I’ve always found git to be frustrating. The command naming is inconsistent and git lets you easily shoot yourself in the foot.
I made gut, another git porcelain, to solve these issues.
It provides a consistent naming of command. To do so, syntax is based on subcommands. For example, to delete a branch, run gut branch rm rather than git branch -d, same to delete a remote (gut remote rm) and so on.
Gut also prevents you from shooting yourself. It provides nice defaults and always prompt you before doing something destructive. Also, it won’t allow you to rewrite the history if it has been pushed to the remote. Creating commits in detached head is also prohibited.
Finally, git was made when GitHub and others didn’t existed yet. To diff commits, gut opens the compare view in the browser. And to merge a branch, gut opens a pull request.
I have been working on this project for the past few months and I am happy to be able to share it.
I hope you’ll like it. Any suggestions is welcome !
That got me thinking about the first time I really screwed something up and had to figure out how to use git rebase, and the first time I tried to create a git submodule (back when submodules were new and there wasn't much help to be found on StackOverflow). I must have let the Stockholm syndrome set in, because the "explain" feature is a wonderful idea for students.
The dead-simplicity of it is very desirable in certain spaces. Back when I was in college, I wrote code for some indie visual novel games, and I was always the only person with a software development background. If I had a tool like this, it would have been MUCH easier for my colleagues to cooperate with me in the development process.
However, a first year college student building something and putting it out in public is a great achievement and something to be condemned.
I assume you mean "not condemned" or "commended" possibly?
My standard work flow is that I have a branch for each change that I commit to without any form. I just use it to checkpoint myself. Yes I push those both as backup and to get CI to tell me things I broke while I keep working without having a full local build kill my machine from the load. At the end I squash, rebase and force push and then merge to master. In fact we only ever allow clean rebase "merges" to master, i.e. fast forwards.
Deleted Comment
Deleted Comment
Dead Comment
I’ve actually seen the opposite where people dive into the details and kind of get lost, give up and end up with a fragmented mental model that leaves them afraid to touch it.
The whole point of software engineering is to write software that makes our lives better. Why would "deal with it" be the right answer to the horrific mess that is the Git UI?
The frontend can be a ui or a cli like this with a good explain command.
It is important though that the final git commands are shown, such that you can learn, and find more details on the internet when needed.
So learn, yes, but whilst avoiding many initial pitfalls.
The best thing to learn about git is what the safety nets are, what commands do destructive edits, vs what commands do things you can undo. Once you know how to recover from all the non-destructive commands, you never have to stress about them again!
The reflog is weird and confusing at first, but once you know it’s here and a little about how to use it, all of a sudden you realize it’s pretty hard to lose things, as long as you commit them.
run "git log" to grab the commit hash
The really challenging parts of git IMO are around maintaining branches. Merge vs rebase, squash or no squash, when to back-merge, etc.
I'd love a command pallet where you could search for basic behavior in plain text like "reset my branch to GitHub's copy" or "only rebase two commits" and have it find the magic incantation.
[1]: https://blog.waleedkhan.name/git-undo/
Oh my god, I just realized this is ref-log (a log of references), and not re-flog (I'm not even sure what "to flog" is). No wonder I've never really understood why it's called that, I simply realized that I can look up older references to everything there by using it. Thank you!
It kinda needs separate command that shows you both reflog entries and commands that lead to it. Maybe merged with undo command so you could look at the history of operations, go back to that point, and get alert if you skip something already pushed upstream.
git rebase -i is essentially "undo" of sort but, uh, not a tool for faint hearts.
> git blame (git author)
I doubt people are confused by that
> I'd love a command pallet where you could search for basic behavior in plain text like "reset my branch to GitHub's copy" or "only rebase two commits" and have it find the magic incantation.
"git do" that just asks ChatGPT and pastes solution lmao.
Knowing the git enough to not need crutches is opposite of luddite.
But yeah, for devs sure, just read git book 2 or 3 times and if you're competent developer you'd probably get it just fine, once you get the concepts it's perfectly logical.
Just that not everyone is a developer wanting to use git for dev things and those UIs have place for that. I kinda wish there was more on the graphics side, like you can tell git how to diff binary files or even encrypted files but good luck explaining that to the non-coder trying to use it.
I still don't get developers complaining about it, it's your fucking main tool to work and about 10x easier than competence in any programming language, just learn it, you will use it longer than any piece of code you ever wrote most likely.
Suffice to say the complaints about git are alien to me. It seems that either devs need to know very little or everything to be safe. The middle ground falls under "knows enough to be dangerous"; you start getting over confident all fancy with your git moves and screw up. But nothing that can't be fixed.
Dead Comment
> Revert it without modifying history
Git revert modifying history is a feature!! It’s a safety net that allows you to, for example, revert the revert if the first revert was a mistake. Sometimes you don’t know the first revert is a mistake until later...
Likewise the undo command loses working tree progress just like git reset --hard, but I’m wondering is this the default behavior you want in an “easy” git wrapper?
What if a git wrapper designed to be easy also thought hard about how to make every single command safer than it is by default with git, for example, quietly making a backup of any work you want to undo or revert? Like maybe you could make branches with a special naming scheme so they’re normally hidden by the wrapper, and cleaned up later, but identifiable so you can bring them back. Or maybe the cli wrapper could provide a more intuitive & useable interface for the reflog.
One thing that would be useful with a git wrapper is a version of git stash that uses branches instead of the stash. This is because the stash is not in the reflog, and it doesn’t have the same level of safety that commits & branches do (the git stash manual mentions this). The biggest unintentional losses of code I’ve seen are git stash accidents, not counting people getting frustrated not knowing how to use git to fix a mess, and nuking their repo.
We're all professionals working in a professional environment. "Git jail" isn't a thing. The "Git courts" won't take away your ability to use Git.
If anything, this would be an opportunity for a senior engineer, you know the people that are supposed to mentor and role model juniors, to give guidance on how to revert in the future.
I've got more than a decade working with the tool and use rebase daily. Hasn't been a problem yet.
So if the author really means "git revert with a nicer user interface" then by all means have at it, although I don't see what anybody is disagreeing on.
My history with git and GitHub is indeed chaotic. It took multiple steps and being explained with different approaches for me to finally understand the basics of git. Today, I consider myself proficient because I'm autonomous for 99% of what I want to do with git or GitHub, and honestly what you cover largely corresponds to these 99%.
You could add a feature flag for users to actually display the commands that gut runs in the background. Users would use gut to actually learn git with time, that would be very powerful and I would instantly recommend your tool to my students.
Again, kudos to your approach and execution.
It's a great idea. For now, you can run "gut explain <command>" to get the git equivalent. But it would be better to really show what's going on.
I would suggest you go further and package all the branch related operations as subcommands of "gut branch". For instance, "gut branch ls" is more transparent and explicit than just "gut branch".
Also move the "switch" commands to "branch". Force branch creation to be explicit ("gut branch new") that does not change the current branch. That will prevent typos or memory lapses from leading to errant new branches. Then provide "gut branch switch branchname" that will only switch to an existing branch. You can include a "-f" flag to explicitly force branch creation, allowing a single command "create and switch" operation. You have in general avoided flags, but "-f" is extremely common and widely understood in the unix world.
Small changes like these can make significant improvements in the ergonomics of an interface that is already better than git's.
"gut branch ls" is an alias of "gut branch", and to prevent unwanted branch creation, a confirmation prompt appears when a new branch is specified in "gut switch".
I still agree with your point, though; it would be more consistent to have everything under the "branch" command. I will consider these changes.
In git you can switch to a tag or commit in addition to a branch. There are different flags you may want to use depending on which type of ref you have so in the case that gut should only support switching branches moving the command may make sense, but if it supports arbitrary refs then moving it would not make sense. Looking at the switch code for gut `CheckIfBranchExists` does expect only branches so tags and commits are not supported in the current version. Relatedly, it looks like gut does not make an attempt to reconcile a dirty working tree with switch: if it's dirty you either abort the switch or throw away your changes, but it could be helpful to tell the user they could also stash the changes and make the switch when aborting or offer to stash instead of just throwing away the changes.
I should move this switch command under the branch command.
Additionally, it is a good idea to advise to stash changes; I will likely add it in the next release.
1. If you want to do something advanced, it will be a lot easier to find help online using regular/original git commands
2. You still need to learn this new interface , so you will end up learning too different command line interfaces (one for the easy stuff and one for the advanced stuff)
3. You will surely, almost certainly mix the two interfaces
Use and learn git "original" commands to do advanced stuff Use a nice UI for the easy straightforward stuff
The only alt command line interface I might consider is magit, because it mixed the emacs commands with GUI elements, and still i think magit is not all that because its not GUI enough, if magit becomes faster and more graphical, only then it might make more sense (for now its really only for emacs hardcore users)
Couldn't you say the same for wrappers around an API ?
Git is very popular, there is ton of resources online on how to use it and learn it, and a lot of UI tools if you dont want to learn the cli at all
I would say if an API is as popular as Git, a wrapper would be a very hard sell
But if the API is considered old, legacy, or not very popular, then maybe a wrapper make sense, but then this would still be a niche case, if the API the is not used much, the wrapper would be used even less
The only solution is for Git itself to fix it, but that's very unlikely. We did get `git switch` but that's it. They'll never rename "the index" to something sensible (e.g. "draft") or make a sane way to delete remote branches.
I recommend just learning with a GUI (Git Extensions is good) so you don't have to deal with the abysmal CLI UX until you at least understand the DAG.
Lazygit is roughly similar to magit but it's written in go so it starts quicker if you don't already live in emacs.
I wonder if you could try to detect and warn about secrets, maybe via content inspection.
Secret detection seems hard. Maybe "gut save" should inform the user which file will be committed to prevent committing a credentials file, but it's probably not the right solution. I must look into that.
It takes a few minutes to install and then all your secrets and config will be in the environment, and will stay automatically up-to-date when there are changes.
Might be a way to cut out that particular failure mode when using Gut (which looks interesting btw--kinda like Git: the good parts).
1 - https://github.com/envkey/envkey
https://github.com/topics/secrets-detection
But the rule I preach everywhere is never to write credentials in your code. Even if it's your Hello World kind of a local small program to test out things.
Alternative: store the credentials in /tmp/my.password and load it in your program. Most programming languages make it easy.
Choosing a name is hard and all the gut ones are taken (haha...), but maybe at least choose one that isn't used multiple times for the same use case. You probably wrote kt for yourself and I name my programs however I like as well, but man you even registered a domain for it. Let's hope it finds more traction than all the other gut clients
Most of the clients I listed I knew from HN itself they were posted in the past and I first thought this was a repost :)
From a quick search in the pacman and ubuntu repository none of those packages (or for that matter any other package) has a binary called gut. So if your client will be a smash hit you could be the first ;) good luck with that