
Oh Shit, Git? - auraham
https://ohshitgit.com/
======
ThrowawayR2
Needs an entry for git submodules issues where the answer is to light the
computer on fire and find a new profession.

~~~
dreamcompiler
I learned a long time ago never to invade Russia in winter and never to use
git submodules.

Git doesn't compose.

~~~
anchpop
I think if git submodules were architectured differently, they could have been
a really interesting solution for package management. In fact my last place of
work uses a layer on top of submodules as part of their internal package
manager. I think they could be really special but unfortunately are now sort
of relegated to history.

~~~
slavik81
Is there anything wrong with the submodule architecture itself? My impression
is that the data model is fine, but the interface for manipulating them is
confusing even by git's standards.

~~~
Izkata
Your impression is correct: They are functionally identical to svn externals
that pin to a revision, but require an odd set of commands to update, instead
of just being batched in like how "svn up" includes externals.

I've never had a problem with them and don't understand why so many do.

~~~
mehrdadn
I won't suggest others are referring to the same issues necessarily, but try
switching between branches(/commits) when you have submodules. Let alone
rebasing etc... they simply don't "just work". You always get some odd vestige
of a submodule hanging somewhere that ends up causing problems, either in the
index or the .gitmodules or somewhere in .git/ or whatever. Hell, the fact
that there are so many places where git submodules are recorded itself has
caused me so many headaches.

~~~
rwmj
The most fun is had when a submodule was introduced to replace what was
previously an ordinary directory, then you try bisecting across that commit.
Qemu's git repo has at least one of these (the slirp/ submodule/directory)
which I curse every time I need to bisect something.

~~~
Izkata
Hm, this sounds like a good example of something I never encountered just by
chance. Be it svn externals or git submodules, I never string them around the
codebase - I put them in a subdirectory that's just for that purpose.

------
Waterluvian
Correct me if I’m wrong but these all seem to fix problems that exist in a
local clone only. And that’s where none of my “oh shit” moments happen.

All of my oh shit moments are two flavours: I have pushed to remote, or I have
pushed to remote and force pushes are disallowed.

I want a list of as graceful solutions as possible for those scenarios. And
certainly they can be real-world solutions like “this cannot be undone in a
desirable way so here’s an approach to handle the commit(s) necessary to fix
the problem.

This also brings up a question I didn’t realize I had: are people using git
without frequently pushing to remote? I feel like having a remote backup of my
work in progress is the killer feature. I can’t imagine doing any amount of
work and not backing it up.

~~~
the_pwner224
> are people using git without frequently pushing to remote? I feel like
> having a remote backup of my work in progress is the killer feature.

I use git without a remote pretty often. When doing personal projects or
exploratory work, the problem is either so trivial that I don't care about
backup, or already backed up using something like Nextcloud/Syncthing. But
having the commit history allows me to easily look at old code, revert
changes, and make big structural changes without having to back up the entire
project folder in case I end up disliking the new structure.

I guess you're just not working on many things at a scale where version
control is useful but setting up an online repo doesn't seem worth the time.

~~~
perryizgr8
> I guess you're just not working on many things at a scale where version
> control is useful but setting up an online repo doesn't seem worth the time.

It is literally a couple of clicks to set up a private repo on github. For me,
either the problem is too small to set up git, or it is big enough to spend
half a minute to create a github repo.

~~~
panpanna
Pro tip: you can set up a remote repo on any Unix machine with SSH access:

    
    
       ssh machine "mkdir x; git init x"
       git clone machine:x
    
    

If you have something sensetive or just want to avoid github/gitlab for some
other reason, an empty remote container with SSH access works just as well.

------
grayhatter
If y'all think git is hard, wait 'til you hear about computer algorithms!

Git isn't hard, it _might_ be complex, but how it works and how to use it is
simple as far as applications and/or processes go.

I find myself constantly trying to dispel the idea that git is too difficult
to understand in depth. The problem has always come down to the missing
attempt to understand the issue, over trying to ^c, ^v a solution.

Seriously, if you think git is hard: don't ask for it to be easier, ask
instead to be stronger. (Or in this case smarter, something you surprisingly
have control over)

~~~
smabie
It's not that it's hard or complex, it's that I really don't care about it and
am not at all interested in learning. It's a weak attitude, I know, but I just
can't help it.

So like most other developers, I go about my day totally not understanding git
at all and when something weird happens, I talk to that co-worker know
understands get (there's always at least one such psychopath on each dev team
in existence) and ask him to fix it. He invariably talks about how easy and
elegant git is and then finally gets around to giving me a couple commands
with non-sensical names and options that fix the problem.

I don't care, and I'm okay not caring. Not learning git might even give me
extra time to learn about these magical computer algorithms I've heard so much
about.

~~~
grayhatter
> there's always at least one such psychopath on each dev team in existence

I'm that psycopath :D

> I don't care, and I'm okay not caring. Not learning git might even give me
> extra time to learn about these magical computer algorithms I've heard so
> much about.

I'm fine with this actually. If you don't care, and don't want to. That's
actually totally fine. I _personally_ will look at you a bit strange. But when
it comes down to it. You should only care about what you want to. But please,
for my continued (admittedly borderline) sanity. Don't try to convince others
that it's too hard to learn, and/or that they shouldn't try. I want to work
with people who are curious, people who want to learn how cool things work.
But there's a trend in software engineering, that parts of it are too hard,
and that it's a waste of time to learn them. That's a scary thought to me;
imagine the next generation of software devs, all convinced that they can't
understand something, or that it would be a waste of their time to try?

~~~
smabie
I see it like learning a build system: ultimately a pointless piece of trivia
that isn't very interesting or worthwhile. This is in contrast to math or CS,
which is generalizable and timeless.

But you're right, we should all understand this stuff. And if it wasn't for
that one magic coworker (you're really taking one for the team), I probably
would.

~~~
roenxi
Git is a little bit different. It is a really good implementation of the
'history is immutable' philosophy of programming.

Learning the implementation details and reading the mystifying documentation
to learn what something is called can be a bit wasteful but understanding the
git model is very worthwhile. It is interesting to see how it handles the
pragmatic issues of fixing the situation up when the history becomes snarled.

Learning git will make some not insignificant number of people better at
concurrent programming. Most build systems don't do that..

~~~
recursive
It's not that good. For one, rebase mutates history. Also the ui is confusing
and inconsistent even if the data model is pure and beautiful.

~~~
mb7733
Rebase does not mutate. It creates new commits and updates the rebased branch
to point at them. The original commits still exist (even if no other branch
points at them).

Git commits are never mutated. They are referred to by a hash of their content
after all.

~~~
dreamcompiler
Rebase sure _seems_ like it mutates.

What's the UI for getting at those old commits? Is it possible to get a _true_
chronological log from them? Do they stay around forever or do they get
garbage collected eventually?

~~~
RichardCA
Good:

    
    
      git log --all --graph --oneline --reflog
    

Better:

    
    
      git config --global alias.lg "log --date=format-local:'%Y-%m-%d %H:%M:%S' --pretty=format:'%cd %<(20,trunc)%an %C(auto)%h%Creset%C(auto)%d%Creset %s'"
    
      git lg --all --graph --reflog
    

> Is it possible to get a true chronological log from them?

The output of git log with --graph is not chronological, because it does a
topological traversal of the commit graph.

> Do they stay around forever or do they get garbage collected eventually?

They get garbage collected eventually. As a rule you should not assume
dangling commits are safe. If you need to keep one, assign a trivial branch
name to it.

------
dang
If curious see also

2019
[https://news.ycombinator.com/item?id=19906972](https://news.ycombinator.com/item?id=19906972)

2017
[https://news.ycombinator.com/item?id=15951825](https://news.ycombinator.com/item?id=15951825)

2016
[https://news.ycombinator.com/item?id=12459755](https://news.ycombinator.com/item?id=12459755)

------
catchmeifyoucan
I’ve almost been exclusively using the GitHub Desktop client as my primary Git
Tool and I’m much more comfortable with git now and helping people out. Merge
conflicts were super scary, but with VS code markers, it’s a breeze. The
desktop tool also makes sure to fetch origin first. If my commit is incorrect,
I just use the “revert” button and it lets me fix things. There are a few
things like renames and branch deletes that I use the shell for, but I’m happy
and more confident in using git since the desktop tool is effective. One thing
I hate is the pesky .DS_Store on Mac. No matter how many times I ignore it, it
just wants to be a part of my commit.

~~~
SebastianKra
Sounds like you already committed it before adding it to the gitignore. Here's
a fix:

[https://stackoverflow.com/questions/13541615/how-to-
remove-f...](https://stackoverflow.com/questions/13541615/how-to-remove-files-
that-are-listed-in-the-gitignore-but-still-on-the-repositor#13541721)

...but this shouldn't be a problem with a good git client such as Fork (git-
fork.com) or SourceTree. They show you the changed files and let you select
which ones to commit.

I would never commit anything without at least skimming the changes first.

~~~
catchmeifyoucan
In the GitHub client - if you point it to a folder and say “add repo from
existing folder” it automatically makes an “init commit”. So you don’t get a
chance.

I’ll keep an eye on it next time.

------
kuharich
Prior comments:
[https://news.ycombinator.com/item?id=12459755](https://news.ycombinator.com/item?id=12459755),
[https://news.ycombinator.com/item?id=15951825](https://news.ycombinator.com/item?id=15951825)

------
aloknnikhil
> Git documentation has this chicken and egg problem where you can't search
> for how to get yourself out of a mess, unless you already know the name of
> the thing you need to know about in order to fix your problem.

This is exactly why I have been running "git diff HEAD" instead of "git diff
--staging" to diff my changes that have already been added to staging. I
didn't even know that flag was a thing. I really wish there was some sort of
an auto complete that could go from me describing the problem to the thing
suggesting commands. Oh well, until then thanks for this!

~~~
everybodyknows
Note that the two commands are not in general equivalent. Try `git add some-
modified-file`, then change some line of the working file just "added". `git
diff HEAD` will show the new change, whereas `git diff --staging` will not.

------
O_H_E
I LOVE how they have a non-swearing version at dangitgit.com :D

------
tracer4201
Thanks, that last entry gave me a good chuckle. I wasn’t aware of the -—no-
edit flag when performing an amend. Learned something new.

~~~
michaelmior
Huh. Neither was I. I've been using -C HEAD which has the same affect (reusing
the commit from the branch head) but --no-edit makes it more obvious what's
going on...sort of. It's still not clear _what_ isn't being edited.

~~~
grayhatter
What are the options for what could be the target? Or I guess in this case,
what isn't the target.

~~~
michaelmior
Do you mean the target of the editing? It could also be the commit author or
committee perhaps. Maybe the message is the only logical choice, but for long
flags, I think more explicit is still better.

------
ARandomerDude
Good tips, not a page I would use at work on account of the title.

I get that SV is probably profanity-friendly, but a lot of us work in more
reserved environments.

~~~
snazz
That's what [https://dangitgit.com/en](https://dangitgit.com/en) is for :)

~~~
atum47
really clever

------
woggy
A little bit off topic, but I hear a Pijul release is coming some time within
the next week (its been a year since the last one). I've never really
understood Git and always hoped for something else to come along, at least as
an alternative.

~~~
kyriakos
Looks interesting but the name may be blocking it from becoming more popular

------
dskrvk
I prefer [https://github.com/k88hudson/git-flight-
rules](https://github.com/k88hudson/git-flight-rules) which is more complete
and doesn’t use unnecessary swearing.

------
harrispj
Imho, just start using one of the desktop clients. I really like GitKraken but
I've heard good things about tower too. Cannot emphasize how easy GitKraken
has made my life when I eventually get into these scenarios.

------
jancsika
> git revert [saved hash]

I see a future article forming:

"The Power of Unix Pipes Except for The Zillions of Times Per Day Developers
Awkwardly Drag a Mouse Over a Human Unreadable String Just to Make Trivial Git
Commands Work"

~~~
O_H_E
laughing in zsh completions. Not defending the git interface, but it is
seriously bliss.

See
[https://asciinema.org/a/LcarSXE90npusIczkIRdrzJLx](https://asciinema.org/a/LcarSXE90npusIczkIRdrzJLx)

~~~
lma21
wow!

how do I do this for custom cli apps?

~~~
O_H_E
If you mean generate completion entries for you own tool, my answer will be 'I
am not that kind of a guru ;D'. Go lookup creating zsh completions

If you mean the interface with tabs, I am just using zsh-grml config (config
file you download for those who don't care for a zsh plugin manger) (I believe
very similar behavior is available in bash)

Then, I just look up zsh completion for $TOOL.

------
acidburnNSA
I think there's an comic book version of this for sale from the same people.

[https://gumroad.com/l/oh-shit-git](https://gumroad.com/l/oh-shit-git)

------
runawaybottle
Love this, definitely needs part 2 and 3 for rebasing and so forth.

~~~
O_H_E
Not a rescue guide, but a very nice and animated hands-on tutorial:
[https://learngitbranching.js.org/](https://learngitbranching.js.org/)

------
jeppesen-io
Just me, but git rebase -i is my go-to tool when I make a mistake

------
winrid
I'm almost done reading Pro Git. I thought there was a good chance it'd be
useless, but it was actually useful even after using Git for six years.

------
wffurr
A+ my go-to git reference. I don't work with git in my day job mostly, but
when I do I end up here at least once a month.

------
JakeStone
I was today days old when I learned about 'git reflog'. I may have to play
with that sometime soon.

------
margaretdouglas
Oh shit I accidentally force pushed my local master branch to origin.

~~~
Arnavion
Well, if you're already force-pushed it once, you might as well force-push the
right commit (from reflog, if necessary) back to it again.

~~~
margaretdouglas
Only works if you've recently fetched origin, otherwise it'll be a challenge
sorting out what the previous HEAD was.

~~~
sio8ohPi
\--force-with-lease is almost always the flag you ought to use instead.

"\--force-with-lease alone, without specifying the details, will protect all
remote refs that are going to be updated by requiring their current value to
be the same as the remote-tracking branch we have for them."

------
ldiracdelta
Bitkeeper was better. Larry McVoy is a hero.

------
atum47
that is some really useful shit right there. thanks for sharing

