
On undoing, fixing, or removing commits in git - DanielShir
http://sethrobertson.github.io/GitFixUm/fixup.html
======
sisk
Regarding losing data: it's as simple as diving into the reflog. In order to
remove something from your history, you must do so very explicitly by walking
your commit history, editing each one. There is an automated workflow to
accomplish that (`filter-branch`) but it's definitely not a command anyone I
know has committed to memory.

Accidental mutations can be undone either by `--abort`ing (if the command
supports it) or by checking out an earlier revision from the reflog.

The GC in git is pretty conservative and, while it can be triggered manually,
still makes you jump through some hoops to actually get rid of something.
Steve Klabnik wrote about it[1] a little while back.

In certain cases, you don't have access to the reflog because a change wasn't
made locally. Perhaps someone screwed up a remote you pull from and it
destroyed your history. You can, even still, find, view, and re-associate
orphaned objects. Yeah, it's not terribly intuitive and, again, not a workflow
anyone has probably committed to memory, but the fact that you can recover
from a disaster of that magnitude is pretty amazing.

git provides we developers with a set of tools—powerful tools—and that comes
with a level of responsibility. I'd rather have the ability to responsibly
clean my history than the alternative.

[1] - [http://words.steveklabnik.com/git-history-modification-
and-l...](http://words.steveklabnik.com/git-history-modification-and-libuv)

------
mikeash
"Strongly consider taking a backup of your current working directory and .git
to avoid any possibility of losing data as a result of the use or misuse of
these instructions."

WTF?

What is the _point_ of a version control system if you have to take _backups_
of it to avoid _losing data_ when performing certain operations?

I use git, I like git, but certain aspects of it are fundamentally broken.

~~~
gemma
No, that advice from the article is fundamentally broken. Outside of the
garbage collection system (which runs by default after what, 30 days? 90?),
Git doesn't delete committed content. Any commit you "lose" through rebasing,
amending, resetting, etc. can always be recovered. It's a little more
complicated than renaming a directory, sure, but it's important, and it's not
something a Git tutorial should ignore.

Git IS safe, and ANYTHING involving changes to history can be undone without
resorting to backups. Data loss can occur when you're mucking about with
uncommitted changes, but that's a risk in most other version control systems
as well.

~~~
crystaln
I'm not 100% sure this is true, however it is also a fundamental flaw of git.
There _should_ be a way to remove commits permanently in order to remove
mistakenly checked in large files or private content.

It's also definitely not true with uncommitted changes, including gitignored
files.

~~~
lomnakkus
git filter-branch will let you remove content permanently and irrecoverably if
you really need to.

Regarding uncommitted changes: This is in the same category as forgetting to
do your backup before starting to mess around, IMO. I would encourage anyone
to simply get used to committing extremely often and just using a quick
interactive rebase before pushing.

~~~
mtdewcmu
At the last job where I used git, I'd work in a separate branch, and I started
using `git merge --squash` to merge into the main branch to keep the history
from getting too difficult to follow. When git merges a bunch of different
histories into one, it becomes almost impossible to make sense of if people
make lots of small commits. I shy away from `git rebase`, because it seems
dangerous.

~~~
lomnakkus
Never fear! "git rebase" isn't nearly as dangerous as many have been led to
believe... _unless_ you start rebasing things you've already published/pushed
elsewhere. In that case you need to be very proactive about notifying everyone
who could _possibly_ have checked out your branch, etc. Otherwise: it
certainly takes a little getting used to, but I find a little one-on-one
"mini-mentoring" others with the first few rebases helps them immensely, so if
you have someone who can help you in person it might be a lot easier to get
comfortable with the process that way.

------
rebelidealist
_sigh_ it seems to me that Git is unnecessarily complicated. Wonder what if
"github" started with HG.

~~~
tytso
There are two ways things can be simple or complicated. One is to have a big
button labelled "DWIM", which always does the right thing --- until it
doesn't, and then you have to go out of your way to work around its assumption
of what you want to do.

The other way is to have a number of simple concepts which can be combined in
various powerful ways. Once you understand these simple concepts, you can
compose them to do whatever you need. Git is simple the same way that RISC is
simple, and having a manual transmission is simple. You can do a lot more with
a manual transmission car than you can with an automatic --- but if you're not
careful you can strip the gears. Yet a manual transmission is simpler to
maintain, and more efficient (in the hands of someone who knows how to use it)
than a automatic transmission. If you take a look at the post, you'll see that
the various recipes only use a handful of git commands. Once you've mastered
those commands, things are indeed quite simple.

~~~
crystaln
That would be true if git's command line interface were not so inconsistent
and obtuse. I agree the underlying concepts are simple, which is why the
command line interface is so baffling.

~~~
Crito
The standard git porcelain has it's problems, but they are largely irrelevant
to the question of git's simplicity. Issues like --all/-A, or the -b flag of
git-commit are unfortunate, but they do not affect the underlying simplicity
that tytso is talking about. That underlying simplicity is what makes git a
pleasure to work with despite weird porcelain because it allows you to reason
about operations in git _without_ reasoning about what different commands are
for or can do.

If you want to know if some operation can be done, you don't reason about git-
reset, git-checkout, git-branch, etc.. you reason about the DAG. After you
have a solid mental image of what you are attempting to do to the DAG, it is a
simple matter to decompose that action into a few weird but ultimately
_simple_ incantations with the porcelain. If you are interested in optimizing
how many steps you decompose operations into, then you can learn the esoteria
of a few git operations, but all of the _hard_ thinking, the real problem-
solving, was done in the context of a different abstraction.

------
rspeer
Thanks, this is a useful reference.

I am sad about some of these other comments, which I might paraphrase as "This
doesn't help me, and it might help people who are less skilled than me who
don't deserve to be helped, therefore it's worthless". It's apparently a
common sentiment on this site, but it shouldn't be.

------
caipre
Usability note: after a few clicks through this (so my path had a few entries)
I instinctively clicked up a few levels in the path expecting to be taken to
that point. Instead, that entry was appended as another child.

------
crystaln
The inability to, in any remotely easy way, remove mistakenly checked in large
files and private data has always seemed like a major flaw with git.

~~~
ams6110
The flaw is in having this "private" data in a public repo to begin with. If
your data are private, don't put your project on github.

~~~
crystaln
While I'm certain you and your organization have a perfect record of never
checking inappropriate things into your git repository, mine does not. Even if
all the employees at your company were perfect, there is still a chance of
inappropriate information getting into the repository.

------
mcv
Rule number one: if you're not sure what you're doing, do it in a new branch.
If things go wrong, you can always delete that branch.

And you can always make a branch out of a previous situation. Gitk/gitx make
this particularly easy.

------
elwell
Sentence 2 has typo "or" -> "of"

