top | item 15951825

Oh shit, git: Getting myself out of bad situations

1209 points| adishaporwal | 8 years ago |ohshitgit.com

508 comments

order
[+] lwansbrough|8 years ago|reply
Adopted a git GUI years ago and haven't looked back. I get looks sometimes, but I can't help but gloat when I can stage and unstage individual lines in less than a second.

I think anyone who uses the CLI is either trying too hard or hasn't realized the beauty of a git GUI.

Takeaways:

- My commit time is usually much faster than coworkers, with higher accuracy (less frequent accidental commits, etc.)

- I don't remember the last time I made an irreversible change to the repo, or had an "oh shit" moment. And that's despite using some interesting git features.

- Staging individual files, folders, lines of code, or hunks is easy. Makes maintaining multiple trains of though / addressing bugs while working on other code a non-issue.

- It's easy to keep files uncommitted for long periods of time intentionally, without slowing down my workflow.

- It's much easier to get an overview of the changes I'm making.

[+] swalsh|8 years ago|reply
I use the git CLI. I do it for one reason. I know exactly what i'm doing on it. I have nothing to prove to anyone, I'm not trying to impress anyone with my "hacker" skillz.

When I've tried GUI's, I'm not 100% sure what's going on under the covers. Sometimes they try to obfuscate things. While I'm probably not the worlds most advanced user, I know enough to know what I want to do, and how to do it. The CLI let's me do it. The GUI get's in my way.

[+] dasil003|8 years ago|reply
You're entitled to your own opinion of course, but you underestimate the efficiency of the command line, especially when you already have one open for other development tasks.

I use one or more GUIs for visualizing branches, and old branch cleanup, and yes, committing single lines from hunks that can't be split.

However for everything else CLI is fairly close to optimal, including interactive adding/rebasing, and don't want to use whatever shitty editor your tool has in it, I want to use vim with syntax highlighting so I can properly format my commit messages. Even something as simple as viewing a full commit is faster in the CLI because you can just pipe it to less or send it to an editor versus whatever tradeoffs a GUI has to make to stay performant, make use of screen space, etc.

One last tool is Fugitive. This blows away anything else I've ever seen for interactively traversing history at the line level.

[+] nlawalker|8 years ago|reply
I've become a big fan of Git Extensions. I like that it doesn't try to layer its own agenda over the Git workflow, shows all the console input/output it uses, and warns me when I'm about to do something stupid, but overall I like it for the same 3 reasons that I like most GUIs:

- It's a live dashboard. A GUI gives me live, persistent information organized well on the screen. I appreciate the power of the CLI for accomplishing tasks, but I've never understood how people prefer it when it comes to simply viewing and understanding the state of something. I don't see why I'd want to run a bunch of commands to see stuff scroll by in my format-constrained terminal when I can have a live, all-up view of multiple aspects of a repo all at once, with relevant, context-sensitive commands on whatever I click on.

- It's discoverable. Most of what I've learned about git has been through clicking around in Git Extensions.

- The structure and organization of the UI helps me to understand how git operates. When I open the "Pull" dialog, for example, the way the controls in the UI are grouped and the kinds of controls that are used help me logically understand what "Pull" can do.

[+] emeraldd|8 years ago|reply
What GUI do you recommend? My experience has been that GUIs are the easiest and fastest way to make a mess that can't be corrected without dropping to CLI or re-cloning. (I'm looking at you SourceTree). I've long recommended that everyone who uses git know how to use the CLI even if they don't use it regularly.
[+] aschampion|8 years ago|reply
> I think anyone who uses the CLI is either trying too hard or hasn't realized the beauty of a git GUI.

Or, you know, understands and thinks in the semantics of the underlying tool and is already working in other text-based tools.

[+] minitech|8 years ago|reply
> I think anyone who uses the CLI is either trying too hard or hasn't realized the beauty of a git GUI.

Nah, it’s just a lot easier than you make it out to be. GUIs are fine too, but if you read the documentation and don’t just memorize a fixed set of commands there’s nothing dangerous, slow, or inconvenient in going about a standard workflow using the CLI.

And yes, lots of people don’t have time for this. Totally okay. Don’t generalize to “anyone who uses the CLI is trying too hard”.

[+] lillesvin|8 years ago|reply
My biggest issue with a GUI is that most that I've seen introduce new terms for various stuff, e.g. "sync" in VS Code, or "revert commit" (in Source Tree maybe?) — there's no Git command called "sync" or "revert", so I'm not immediately sure what they do.

In a CLI I know exactly what's happening.

That's just my opinion though. If people feel comfortable working in a GUI all the more power to them.

[+] Cthulhu_|8 years ago|reply
I don't trust GUI clients; it's easy to not be able to discern the current status, easy to just commit all changes, some of the clients don't respect the pre-push hook, and I've seen other colleagues who have no clue what they're actually doing end up mixing pull and pull --rebase, somehow managing to make duplicate commits with slightly different contents and not having a clue what's going on.

Don't use clients if you don't even understand the basic git workflows. And those usually don't support the advanced oh shit situations this article is about.

[+] rcxdude|8 years ago|reply
I've felt a good GUI would make using git far more intuitive, but I've yet to find a good one. They all seem to fail on one front or another (too hard to use, don't expose enough functionality, attempt to enforce one workflow, aren't available on platforms I want, are slow/resource hogs).

Usually I use the included gitk to view the repo, and the CLI to manipulate it.

[+] rhodysurf|8 years ago|reply
For the most part using git is like five commands and it is definitely fast to use them from the command line if you have some sort of git understanding
[+] emodendroket|8 years ago|reply
Which do you use? I'm generally pro-GUI (I love Postman, for instance, and don't use curl much) but my experience with git GUIs has been that they were kind of half-baked and will not do what I expected, leaving me with a difficult-to-understand mess to clean up.
[+] MaulingMonkey|8 years ago|reply
> I think anyone who uses the CLI is either trying too hard or hasn't realized the beauty of a git GUI.

I've suffered a lot of git GUI bugs. The admittedly large repositories I sometimes deal with cause things to hang and stall, breaking my flow. I keep filing bug reports - truncated diffs because new files were "too large" (presumably someone trying to fix the hang and stall issue), a client that only renders the top half of the window consistently when on a portrait 4K monitor, etc.

The git CLI is simply second nature enough to me at this point that waiting for a GUI to load, refresh, etc. is rarely faster. It does happen, but it's not the common case. Getting a good summary of a set of changes is sometimes one of them. Picking individual hunks/lines is sometimes another - although I prefer to commit with such frequency when using git, that it's extremely rare I have changes that belong in different commits.

Then, looking at perforce, I'm finding more and more cases where I'm dropping out of P4V and into command line tools. Any kind of mass move/edit seems easier to do through the command line. Command line diffs were way easier to review than P4V's file based diff interface when I had changes involving 1 or 2 line tweaks spread across dozens to hundreds of files (such as verifying function rename changelists didn't accidentally pick up other changes.)

I think anyone who's swayed by the beauty of a git GUI has much more patience than me.

"Sourcetree (Not Responding)" - I typed this out while waiting for my Visual Rust tab to focus. Euhg.

I could've made a commit from the command line in that amount of time.

[+] madeofpalk|8 years ago|reply
I've found my sweet spot is using both a GUI (Github app, to be specific) and a CLI.

GUI for partial commits and reviewing my change, and then command line for basically everything else (merge, checkout, branch, etc).

[+] rectangletangle|8 years ago|reply
I've tried out a few different GIT GUIs, and never really took to any of them. Settled for using the CLI + many BASH aliases. Anything I do frequently gets a concise alias to minimize typing. I have relatively short fingers, and I'm admittedly a pretty poor typist, so I really emphasize the concise part. Pretty much all the aliases are write only code. I do this for pretty much every other complex CLI application too, e.g., Docker, Heroku, AWS. A little abstraction really speeds up using the CLI. Aliases are my favorite feature of BASH, I think they've saved me literally months of typing at this point in my life.

Here's a few handy ones:

  alias currentbranch='git rev-parse --abbrev-ref HEAD'
  alias gpush='git push origin $(currentbranch)'
  alias gsync='git pull origin $(currentbranch)'

  alias ga='git add -A'
  alias gc='git checkout'
  alias gcm='git commit -m'
  alias gca='git commit --amend'

  # and my personal favorite (list recent branches)
  alias gb='git for-each-ref --sort=-committerdate refs/heads/ --format="%(HEAD) %(color:yellow)%(refname:short)%(color:reset)" | head -n 20'
[+] kendallpark|8 years ago|reply
I use a git GUI for staging commits, but the CLI + text editor for everything else (and no aliases). The CLI is universal--I can go to another dev's computer and get them out of rebase hell without learning their particular git GUI interface. Knowing the CLI by heart is also useful if you ever have to use git server side through SSH. I have found that the CLI fits into my workflow better than the GUI for everything except staging.
[+] sigi45|8 years ago|reply
I work very well on a cli. I can do partial adds faster than you and don't had any 'oh shit' moments for a few years.

I do not care if someone is using a gui.

My takeaway: - If i can use git on an cli, i can use git on any server with an cli. I do need this for when i use git on my ansible maschine or on my home media server or when doing something with build infrastructure (jenkins -> git -> cli)

[+] marssaxman|8 years ago|reply
Past experience with GUI frontends and other sorts of simplifying interfaces for version control tools has left me extremely reluctant to use anything more than git's out-of-the-box command line, despite its execrably wretched, unlearnable inconsistency. When things don't make sense with git, I can at least compare notes with coworkers, or search the web and find many discussions where other people have been similarly confused, and received useful advice. If I'm using some custom frontend interface, on the other hand, there are inevitably going to be situations it doesn't handle where I have to fall back to the command line, which I won't remember anything about because I will not have been using it, nobody else on my team is likely to be familiar with the tools I'm using, and discussions on the web are likely to be scarce. Better to just absorb the ongoing pain of git's terrible interface for day-to-day tasks so that I'm not completely hosed when things inevitably go wrong.
[+] Balero|8 years ago|reply
Additionally you can always use the command line if you need to. I use a GUI for 99% of what I do, then use the CLI for what I need it for.
[+] dlwdlw|8 years ago|reply
I wouldn't say "anyone" is trying to hard but I have seen a lot of people who immediately disregard guis as soon as they internalize that the cli is more difficult. Reasons include wanting to be "badass" or "smart". Yet many also do not care about how got differs and basically ask "how do I save" and proceed to revolve their entire workflow on a few copy pasted or memorized commands.other they hear how "rebase" is only for "smart" people...

On the opposite side gui users can often be unaware of the actual model and instead be working with imperfect internal models with be GUI being a crutch.

In both cases there is lack of desire to learn but I'm often more sympathetic to the latter where people want just enough information to do their work well as oppossed to the former who often make things harder than they have to be in all areas and have lost touch with true expertise in favor of appearance of expertise.

[+] chiefalchemist|8 years ago|reply
Which Git GUI are you using?

The GUI is said to be a major leap forward in human conputer usage, in the context the CLI just strikes me as either (elitist?) jargon, or brogrammer bravado. In either case, not really a step forward but certain macho. I still don't get it.

[+] repsak|8 years ago|reply
I use https://github.com/jonas/tig for interactive staging and git CLI for everything else. Best of both worlds and I don't have to leave the terminal.
[+] dozzie|8 years ago|reply
> I think anyone who uses the CLI is either trying too hard or hasn't realized the beauty of a git GUI.

Or just couldn't be bothered with leaving terminal. I refuse to reach for mouse for any repository operation when everything else I do from console.

[+] Pxtl|8 years ago|reply
I use both - to me the big advantage of getting used to GIT CLI is that you learn the tools to handle uncommon operations and automate tasks, which the GUI doesn't give you. When you need to start piping stuff through grep, for example.
[+] pkamb|8 years ago|reply
In addition to better staging and committing, I love my git GUI for allowing me to easily see and work with every past commit.

Right click on any commit and I can create a new branch there, copy the SHA, do a mixed reset to that location, rebase on it, etc. SO much easier to visualize the actual tree of commits you're working with.

I'm sure some people do do all that from the command line. But every CLI coworker of mine has really only known the basics of branching and committing. The GUI unlocks the repo and all of its branches and commits as something you can play with and explore.

[+] ashelmire|8 years ago|reply
Git is, imo, way too simple to require a gui. How long is it taking you and your coworkers to make commits? git commit -am "message" (or add the files you want with git add, then commit); git push; git pr -m "message". The longest part of that is coming up with a good commit message. A gui isn't going to stop people from making mistakes because the mistakes aren't from complexity of the command line, they are from committing things you shouldn't, which will happen regardless of whether or not you use a gui.
[+] B_612|8 years ago|reply
The Git UI that comes with intelij can do all the essentials git statements and has a console that logs everything it is doing.

And you can also learn useful things by reading the console sometimes. There is no magic.

[+] outworlder|8 years ago|reply
"- It's easy to keep files uncommitted for long periods of time intentionally, without slowing down my workflow." "- My commit time is usually much faster than coworkers, with higher accuracy (less frequent accidental commits, etc.)"

Do you mean that as "not committed", or "not pushed"?

If you mean not committed, then why is it a good thing? You should be committing often. Then you push after you are satisfied. It is much easier to revert mistakes that way.

[+] inferiorhuman|8 years ago|reply
Once upon a time I found a git GUI that I liked (SourceTree). Then Atlassian bought it and pushed their cloud nonsense on me so hard that I just gave up and reverted back to the command line. Eventually I bought the O'Reilly book and figured out how to do the neat things that SourceTree would let me do. Only this time the GUI wouldn't get borked while trying to stage individual lines.

I haven't looked back because I haven't found the need.

[+] lambda|8 years ago|reply
I'd consider myself an expert on Git, and I use a GUI of sorts for the vast majority of my Git work: Magit in Emacs.

It has many of the advantages that you describe; makes it easier to get an overview of what's going on, makes it easier to stage individual files, folder, lines of code, hunks, etc.

There are a couple of cases in which I need to fall back to the Git command line, but it's not very often, and I do find it substantially improves my life.

[+] falcolas|8 years ago|reply
A git off my lawn moment: Every time I see someone complaining because they have to dive into the reflog to fix their own mistake, all I can hear is "I was operating my table saw without using a push stick and can't understand why I lost a thumb".

Friends don't let friends (especially those who don't learn how to use their tools) rewrite shared git history. If you don't understand rebase, amends, etc can do to your (and everyone else's) repo, DON'T DO IT.

[+] herogreen|8 years ago|reply
In three years of using git I believe there is a single bad command that I could not undo: `git checkout -- somefile` The second worst thing I did is losing a commit in a `git rebase -i` but I was able to find it back with `git reflog`. Which makes me think that git is really well designed.
[+] sfink|8 years ago|reply
You could also use an alternative CLI for git. My preferred one is hg-git.

I'm sort of kidding, but not really. By using it, I can operate on a git repo using the mercurial CLI, which I am more comfortable with and have built tooling around.

Once you have the extension installed, it's a matter of prepending 'git+' to the beginning of eg a github url to clone it, and then you can use native mercurial commands.

Obviously, this is an extra layer with all of the problems that involves (eg you're going to be managing git branches through an hg interface. Which works surprisingly well most of the time.) So this makes NO SENSE WHATSOEVER unless (1) you are comfortable with the hg interface, (2) you aren't that comfortable with the git interface, and (3) you don't need to do complex operations that would require thinking through the layers of what is happening.

Honestly, though, if I want to contribute to a github repo, this gives me everything I need 95% of the time. So far, the only time I ran into trouble was when the active branch was renamed in the github repo. Things got very tangled up, and I had to re-clone and import my patch stack. Judging by the number of people talking about making "backups" of git repos in this comment section, it doesn't sound like that's an unexpected operation in git-land. With mercurial's immutable and append-only nature, I very very rarely need to do this, so it felt kind of awful.

(Admittedly, my main hg repo that I work on is 6GB and I'm normally near the limit of my disk space, so my habits don't really match your typical megabyte-sized github repo in some noncompiled language.)

[+] mFixman|8 years ago|reply
Honestly, a lot of what's wrong in git is that people seem to mostly memorize or copy-paste a finite amount of commands, and when something goes wrong they are completely lost unless they can find a way to copy-paste a solution.

Instead of saving a 6 command list for some use cases, why not just get used to the simple but kinda unintuitive way of how revisions and branches work? If you know that, you can solve any problem with `commit`, `checkout`, `reset`, `reflog`, and occasionally `cherry-pick`.

[+] compiler-guy|8 years ago|reply
The fact web pages like this exist, and are popular, and make it to the top of Hacker News is all you need to know about git's ease-of-use and mental model.

That Perforce and SVN don't get such things should also tell you something.

(Which isn't to hate on git--it's a great tool.)

[+] tnolet|8 years ago|reply
Good thing HN doesn’t have memes, otherwise I would post one of those bears confessing “I’m a software engineer with 19 years of experience and I still don’t really understand git”.

Silliness aside, I guess Git suffers from the trait that it is very hard for many people to internalize and visualize how it works in their heads. Totally different but related: the Azure CLI is for some reason 10x easier to work with than the AWS CLI, while I’m 10x more experienced with AWS. I guess CLI design is also design.

[+] hitekker|8 years ago|reply
I like using IDEA, PyCharm's and Webstorm's "local history" feature to compensate for gaps in my git knowledge.

A constant, instant backup of all files, independent of the repo, has been my saving grace for small projects.

[+] anotherevan|8 years ago|reply
“Git gets easier once you get the basic idea that branches are homeomorphic endofunctors mapping submanifolds of a Hilbert space.”

— Isaac Wolkerstorfer (@agnoster)

[+] grawprog|8 years ago|reply
My last git mistake was pretty terrifying. I decided to try and go back to an old commit on a project on my local machine after about a days work. Somehow I ended up making the commit I wanted to revert to a new branch, then somehow tagged that branch with the name of the commit making git get angry and decide that branch wasn't valid. Then continuing in my ignorance I reset to that branch and tried to checkout only to watch my source and resource files vanish one by one. Deciding the commandline had caused enough trouble I returned to a qgit window I had open, all the source files were still there and I could at least save them one by one. Better refresh the qgit window. Oh shit now qgit's mad at me too. Well there goes thousands of lines of code and about 3 months worth of work. Eventually,after reading gits cryptic error messages and a few google searches I figured out how to remove a tag from a branch and properly checkout an old commit. I was really happy when all those source files reappeared.
[+] dkns|8 years ago|reply
> Oh shit, I accidentally committed to the wrong branch!

I find cherry-picking to be easier in this case. Just checkout the branch and cherry pick commits from 'wrong' branch.

https://git-scm.com/docs/git-cherry-pick

[+] Waterluvian|8 years ago|reply
I gave up on rebasing or any form of history rewrite after going through the screw up phase, then watching every dev that came after me do the same at least once.

I realised that treating a git repo like an immutable collection, where existing commits are NEVER mutated makes it far easier to reason about history and nearly impossible to do serious damage.

Devs can do whatever they please with their own local pulls (such as squashing 50 rambling commits during dev), but once a commit is on remote, it never changes.

[+] gerbilly|8 years ago|reply
On barrier to learning git is that people are understandably reluctant to try things out because they are working in real repositories.

This site makes a game out of learning git: https://learngitbranching.js.org/

It's a great way to learn without putting your real repository at risk.

[+] teilo|8 years ago|reply
I stubbornly stuck with Mercurial for a long time because of the complexity of git's UI. But when one moves beyond a few developers, the available tooling and extensive ecosystem for git makes it inevitable.
[+] nikanj|8 years ago|reply
We pushed large binaries into our git in the past. This was fine-ish as long as Git was hosted inhouse, but now that it's SAASed out, they are a huge pain in the rear.

I've browsed through a few git guides, but can't seem to find anything that would let me:

1) Do something like "du -s *|sort -n" for the entire Git history

2) Let me "rm -rf --from-history-too", that would cause the remote repo to actually shrink in size.

[+] erikb|8 years ago|reply
I always fight for people really learning git, because that's when it finally starts to get good. And I always tell people that git is not the tool that everybody should use. Most people just need a simple data storage with diff management, like Dropbox or SVN.

But even after nearly 10 years, the pressure from the aint-nobody-got-time-for-that crowd is still there. I really, really hope that the git devs don't feel pushed to simplify and therefore depower git. Thinking turning VIM into the Windows text editor.

[+] trevor-e|8 years ago|reply
I think Git would be way more approachable if things were named better. A key part of Git is whether a file is untracked/unstaged/staged, yet the terminology around this is very confusing. Why aren't commands simply `git stage`, `git unstage`, `git add` (to track files), `git remove` (to untrack), `git undo`, etc? Not to mention the overloaded command names like `git checkout`, how is `git checkout -- someFile` intuitive at all?
[+] jimmaswell|8 years ago|reply
5+ years later and I still sometimes have to do the classic "repull the entire repo into a new folder and manually copy the wanted changes over"