
Common Git Problems and How to Fix Them - mzehrer
https://citizen428.net/10-common-git-problems-and-how-to-fix-them-e8d809299f08
======
alangpierce
I think the most powerful tool for fixing mistakes is "git reflog". It doesn't
fix everything, but it works very well as long as you view git with the right
mental model: a git repo is an ever-growing tree of immutable commits, with
branches and tags pointing to the most interesting ones. As long as code has
ever made it into that tree (by being in any commit at any time), it's
recoverable, and reflog lets you trace your steps back to any point in the
past on that tree. Supposedly-destructive operations like amend and rebase
actually just build the tree at a different point and move branches to other
places in the tree, but (pretty much) nothing in the tree is ever destroyed.

For the actually-destructive git commands like checkout and reset, another
tool that I'd highly recommend is a "local history" feature in your editor.
JetBrains IDEs do this by default, and other editors have plugins for it. It
automatically records changes as you make them so you can go back to previous
versions of any file. Usually git is enough to save me, but I've also had
plenty of times where I make some mistake outside of git commit history and am
saved by digging through local history.

~~~
Boulth
> As long as code has ever made it into that tree (by being in any commit at
> any time), it's recoverable, and reflog lets you trace your steps back to
> any point in the past on that tree.

Actually it's enough for the file to hit index (staging area) to be
recoverable.

~~~
jolmg
Do you mean it as recovering it while it's still in the index, or is it
possible to add a file to the index, remove it from the index, let days of
commits pass and still recover it?

If the latter, how do you do that?

~~~
Boulth
Once you add it to index it's in .git/objects. You can find it using `find`
with modification date parameter. The name will be a hash but you can look at
the contents. (there will also be a tree object with file names).

------
michaelmrose
Can the main article link to [https://www.codementor.io/citizen428/git-
tutorial-10-common-...](https://www.codementor.io/citizen428/git-
tutorial-10-common-git-problems-and-how-to-fix-them-aajv0katd) which is vastly
more readable.

~~~
dewiz
Oh thanks, those snippet links make it really hard to read the post otherwise

------
ecthiender
Why aren't code snippets part of the article? Why are they hosted somewhere
else? Especially when they are 2-3 line snippets.

~~~
sus_007
> _Originally published at gist.github.com_

Maybe because the article was originally a gist[0] itself.

[0]
[https://gist.github.com/citizen428/16fb925fcca59ddfb652c7cb2...](https://gist.github.com/citizen428/16fb925fcca59ddfb652c7cb22809018)

~~~
alangpierce
That gist links back to the actual original article, which shows code inline:

[https://www.codementor.io/citizen428/git-
tutorial-10-common-...](https://www.codementor.io/citizen428/git-
tutorial-10-common-git-problems-and-how-to-fix-them-aajv0katd)

~~~
extralego
This should be the posted article.

A lot of useful stuff here but not readable until I found this.

~~~
rurban
Better, but still too many typos or wrong syntax to be useful enough.

------
nerdponx
I'm sorry, I hate "recipe style" Git articles.

Understanding reset and checkout is not hard if you understand the underlying
data model. If you don't understand te data model, it's all black magic.

Interestingly, I feel the same way about actual recipe books for cooking. It's
one thing to keep around as a reference. But if you don't know what a bay leaf
tastes like and what it does to a dish, you won't learn anything from someone
telling you to use it in a particular recipe.

~~~
ollysb
I would love to read a cooking book which talked about the effect of
ingredients and process. Anybody know if one exists?

edit: well this one looks interesting [https://www.amazon.com/Ingredient-
Unveiling-Essential-Elemen...](https://www.amazon.com/Ingredient-Unveiling-
Essential-Elements-Food/dp/0062385356)

~~~
wool_gather
I'll strongly second the Cook's Illustrated recommendation. If you want to
know the reasons behind the recipes, there's no better place to start. I've
used things I've learned from their articles many, many times to help with
_other_ recipes.

And here's some books that spend at least as much time talking about how to
cook as they do giving lists of ingredients.

_The Zuni Cafe Cookbook_ by Judy Rodgers

_Cooking by Hand_ by Paul Bertolli

The French Laundry book by Thomas Keller is worth a read.

If you're into charcuterie, someone else mentioned Michael Ruhlman; his book
_Charcuterie_ with chef Bryan Polcyn is excellent. _The River Cottage Meat
Cookbook_ is also good.

If you want to go deep into ingredients, _The Elements of Taste_ by Gray Kunz
and Peter Kaminsky (and _The Flavor Bible_ by Karen Page and Andrew Dornenberg
(I haven't personally read that one all the way through, though)).

And you can always just pick up a culinary school textbook.

~~~
nerdponx
The Flavor Bible is more of an ingredient reference. It's also very Western-
and Northern- (as in the hemisphere) centric.

------
levi_n
I found the list helpful, with just about everything I would expect in a list
such as this.

If I could make one suggestion: I found it to be quite annoying to have to
click through to a two-line gist for every single one command. Having those
commands be in the article itself would be considerably easier to read.

~~~
doodhwala
Linking to this comment instead of the actual link you want so that the right
person gets credit :)

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

~~~
extralego
Can’t tell if joking.

------
0x0
Don't use push --force, use push --force-with-lease. Then you avoid
accidentally undoing unexpected new commits on the remote.

~~~
fcarraldo
Better yet, don’t use push —force at all unless you specifically intend to
undo commits on the remote. Resolve conflicts locally and never force push to
a shared branch.

~~~
jeremyjh
This forces you to merge master into your shared topic branches instead of
rebasing them on master, which makes the history harder to follow.

~~~
u801e
You can always run something like:

    
    
        git diff origin/your-branch..your-branch
    

to check whether you have made any unintentional changes to the code. For the
commits themselves, you can do something like:

    
    
        git log origin/master..origin/your-branch
    

and

    
    
        git log origin/master..your-branch
    

to see if the commits differ. You can use the -p switch on the git log
commands to see if the diffs have changed. If you do this before pushing up to
the remote, then it's much easier to see what you're going to change before
you run git push -f.

------
cdubzzz
Another reference site that has come in handy for me for quick reminders, and
has a very memorable name -- [http://ohshitgit.com/](http://ohshitgit.com/)

~~~
hyperpape
More comprehensive (enough so that I haven't read every entry):
[https://github.com/k88hudson/git-flight-
rules](https://github.com/k88hudson/git-flight-rules)

------
magoon
I advocate:

git add -p

for interactive staging. It’ll present each hunk of code with a y/n prompt.
This is a good habit to prevent committing any debug code or stray marks.

~~~
acemarke
That's one of the reasons why I've always preferred a GUI for most of my day-
to-day operations. It's a lot easier to click "Add Hunk", or CTRL-click a
couple lines and click "Unstage Lines", then it is to go through the CLI
options for dozens of hunks. Similarly, SourceTree's interactive rebase UI is
great, and when I briefly played with Tower's latest beta, they made it as
simple as drag-and-drop for individual commits.

On the flip side, it's a lot easier to do "git add -u" or "git add
src/some/folder" for those use cases.

~~~
crtasm
'tig' is a TUI for git, once you learn the shortcuts it's easy to stage
specific lines/hunks.

------
Hello71
In addition to what nerdponx said about recipe style articles being poor,
there are some moderate issues with this article:

1\. it doesn't clearly say that git checkout with a path is irreversible.

2\. it says that git reset --hard is irreversible, which is not correct. (see
3.)

3\. it doesn't mention one of the most powerful git features for fixing
mistakes, the reflog.

4\. git remove is not a git command.

5\. gitingore is not a git file.

6\. git-amend is not a git command.

7\. It doesn't adequately explain why force-pushing causes problems.

It looks like clicking through to the gists was such a pain that even the
author didn't proofread them.

~~~
nerdponx
Oh god, I missed this one:

 _git checkout with a path is irreversible_

Not only is it a reversible, but it is destructive. It will overwrite
untracked changes and even untracked files, without so much as a warning. I
personally consider this a critical bug in Git, but apparently the mailing
list denizens do not agree with me.

~~~
mikro2nd
And this is _exactly_ the sort of behaviour that led me to call git "The Swiss
Army Chainsaw of Version Control". It can do _anything_ , but if you wield it
wrong it'll cut your leg off without hesitation.

I consider this a UX failure. Give me hg anytime.

~~~
Hello71
That is, broadly speaking, not correct. The reflog makes it very difficult to
permanently lose committed changes, and for the most part, commands that
change the working directory are generally self-evident. git checkout is
really the only common command that has this non-obvious behavior, and even
then, only when checking out a path; checking out a commit will warn before
overwriting working directory changes. In fact, from what I read, git is far
better than mercurial in this respect, as reflog is always on, whereas the
journal extension must be manually enabled.

~~~
krupan
What you heard about mercurial being worse is wrong. There is no need for a
journal extension to prevent mercurial from permanently deleting commits.
Operations that might delete commits such as strip, rebase, etc. either saves
the removed commits as a backup bundle or marks the commits as obsolete and
does not ever automatically garbage collect them.

------
davidgerard
Mods - please link the original, which has the code fragments inline:

[https://www.codementor.io/citizen428/git-
tutorial-10-common-...](https://www.codementor.io/citizen428/git-
tutorial-10-common-git-problems-and-how-to-fix-them-aajv0katd)

------
Tomis02
Can someone explain to me the fascination for git, despite the constant stream
of "how to fix [ _insert various git issues_ ]" articles showing it's very
difficult to use, at least compared to the alternatives? Most people's work
streams only need something as simple as hg, which would also save them a lot
of time and hassle.

My personal impression is that it's a fashion thing (people think it's cool to
waste a lot of time on git, because git is cool and fixing git problems feels
like real work, because you're using your keyboard and all that), but maybe
someone has a different perspective.

------
majewsky
I'm seeing only github gist URLs instead of code snippets. What became of
progressive enhancement?

~~~
StavrosK
Nothing. They actually are links, not embedded gists.

------
arenaninja
Out of all these, I wish I could use git bisect the most. Working on large
codebases with large teams, the command itself is a godsend.

Unfortunately a PC with Symantec Endpoint Protection makes the filesystem dog
slow to the point that the one time I needed it and it should've taken about
13 steps to find where the bug was introduced, it was faster to redo the
feature without accessing the previous code

~~~
majewsky
You mean Symantec?

~~~
arenaninja
Ah yes. Fixed :)

------
nottorp
So why do i have to open 10 more tabs to see the actual commands? Or am I
supposed to blindly run them without knowing what they are?

------
Groxx
As much as I like rerere, I have had it result in silently[1] producing the
wrong end result. Especially since I merge / rebase frequently, and end up
recording lots of small conflict resolutions. Always always always check non-
clean merges by hand or you'll eventually be surprised.

And sometimes I just resolved it incorrectly once, and now it always does it
wrong. Is there a way to make rerere forget a resolution?

[1]: relatively speaking. it doesn't fail / pause the operation, so it's
"silent", even though it prints out that it applied a conflict-fix.

------
microtherion
Was I the only one who was expecting something along THOSE lines?
[https://i.pinimg.com/originals/4d/ca/1c/4dca1ce93db819647f2f...](https://i.pinimg.com/originals/4d/ca/1c/4dca1ce93db819647f2f87fb92769561.jpg)

------
StavrosK

        function fuckgit
            rm -rf /tmp/fuckgit/
            git clone --no-checkout (git config --get remote.origin.url) /tmp/fuckgit/
            rm -rf .git/
            mv /tmp/fuckgit/.git .
            rm -rf /tmp/fuckgit/
        end

~~~
jwilk
What shell is this?

You use /tmp in an insecure way. Please use "mktemp -d" for creating temporary
directories.

~~~
StavrosK
It's fish. What's insecure about the way I'm using it?

~~~
jwilk
/tmp is world-writable. Any local user could create /tmp/fuckgit and stuff it
with malicous code.

~~~
teddyh
Or create /tmp/fuckgit as a symbolic link beforehand, pointing to a directory
which will be deleted by the first command in your function.

------
paulddraper
Need "missing blob" (corrupted git repo).

That problem is a depressing one and not uncommon [1]

[1]
[https://stackoverflow.com/q/18678853/1212596](https://stackoverflow.com/q/18678853/1212596)

------
throw7
incredibly annoying how the examples are links to another site. had to stop at
the 3rd example.

