Live data from Hacker News

On undoing, fixing, or removing commits in git

sethrobertson.github.io

31–40 of 74 posts

Re: On undoing, fixing, or removing commits in git

#31
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.

Re: On undoing, fixing, or removing commits in git

#32
post #24
post #11

Earlier quoted context omitted.

First, your use of the word "most" is inherently incompatible with the phrase "quite safe". Second, why would a version control system make it so difficult to roll back to an old version that it's easier to restore from backup? This is insane. Third, I'm well aware of this, and of course you should be making backups of your git repositories (and everything else). But those backups should be there to protect against h…

You're discounting the idea that someone might want to destructively rewrite their history. Here's an example: What if you want to retain history, but remove a password that was hardcoded into a source file? The simple options are: - Remove the hard-coded password, and create a new repository with the current state of the code as a starting point. - Start a new repository with the current code state, but keep the old…

I'm not discounting it, I simply don't agree with how git implements it.

IMO the correct option is to create a new repository that has the same history as the old repository minus the offending commit (or possibly with an edited version of that commit that leaves out the offending string).

Because it creates a new repository, there's no risk of data loss in your old repository. Once you're confident that the operation succeeded, you can swap them.

I haven't had to do this for a long time, but as I recall, this is basically how svn does it. It works fine.

The problem with git is that it makes this far too easy and it works by editing existing repositories rather than creating new ones. So instead of once-in-a-blue-moon repository hacking to get rid of that password you accidentally committed, you get people rewriting history because they think the real history isn't "clean". I know a lot of people who routinely edit their local history before pushing changes to a shared repository because they don't want other people to see their true "dirty" history. This is insane.

Finally, I'm confused about something, so maybe you could clear this up for me. I keep seeing assurances that 1) git does not actually destroy any data, and you can always recover if you screw up and 2) editing history is sometimes a vital necessity for cases like when you commit passwords. You yourself made these assurances in this comment. However, 1 and 2 are obviously mutually exclusive. If you can always recover then you can't actually scrub the repository of accidentally committed passwords and the like. Which one is actually true?

Re: On undoing, fixing, or removing commits in git

#33
post #32
post #24

Earlier quoted context omitted.

You're discounting the idea that someone might want to destructively rewrite their history. Here's an example: What if you want to retain history, but remove a password that was hardcoded into a source file? The simple options are: - Remove the hard-coded password, and create a new repository with the current state of the code as a starting point. - Start a new repository with the current code state, but keep the old…

I'm not discounting it, I simply don't agree with how git implements it. IMO the correct option is to create a new repository that has the same history as the old repository minus the offending commit (or possibly with an edited version of that commit that leaves out the offending string). Because it creates a new repository, there's no risk of data loss in your old repository. Once you're confident that the operatio…

Re: 1 and 2

1) This is almost true. Anything that is committed to Git is recoverable. When you "re-write" history, Git is creating a new set of commits in the history, an "alternate history path." It does not destroy the original commits, but there is no named reference to them (unless you created a branch/tag pointing to this line of commits).

2) In this case, if you want to actually destroy these unreferenced commits, you must run "git gc". This IS a destructive command. It will remove any unreferenced commits from the repository. (gc = garbage collect). If you never garbage collect, you will always have access to anything that was ever committed. It just might be hard to find since the only reference is the ref-log (if it was recent) or the commit hash.

Re: On undoing, fixing, or removing commits in git

#34
post #32
post #24

Earlier quoted context omitted.

You're discounting the idea that someone might want to destructively rewrite their history. Here's an example: What if you want to retain history, but remove a password that was hardcoded into a source file? The simple options are: - Remove the hard-coded password, and create a new repository with the current state of the code as a starting point. - Start a new repository with the current code state, but keep the old…

I'm not discounting it, I simply don't agree with how git implements it. IMO the correct option is to create a new repository that has the same history as the old repository minus the offending commit (or possibly with an edited version of that commit that leaves out the offending string). Because it creates a new repository, there's no risk of data loss in your old repository. Once you're confident that the operatio…

You don't actually know how git implements it, so how can you disagree with it?

There is no such thing as "an edited version" of a commit. A commit is identified by a SHA1 hash of its index of contents. If you change one bit you get a new commit.

You're a C programmer, right? If someone gave you a specification for writing a program to implement git, without telling your what it was, you'd tell them it would take 2 weeks. And that's because you'd reckon it would take 2 hours to knock out a rough version and a couple of days to clean it up.

Seriously, it's that simple. Just go learn how it works.

Re: On undoing, fixing, or removing commits in git

#35
post #9

"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.

I understand your puzzlement, I found this confusing too at first. But then I realized it makes sense -- one of git's strengths is that you can rewrite the history. The " point " of a version control system, at least with git, is not backup which retains all history, but rather versioning which retains the history you want to retain. Obviously, if you choose not to edit the history, then you never need to back up in…

An easy way to do that, is the way I tend to do it; Create a new branch based off the one you're rewriting history in, and that will actually keep all of that for you even after you rewrite it all. Makes it really easy to restore later with git reset if you need it.

Re: On undoing, fixing, or removing commits in git

#36
post #13

Earlier quoted context omitted.

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 I…

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.

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.

Re: On undoing, fixing, or removing commits in git

#37
post #32
post #24

Earlier quoted context omitted.

You're discounting the idea that someone might want to destructively rewrite their history. Here's an example: What if you want to retain history, but remove a password that was hardcoded into a source file? The simple options are: - Remove the hard-coded password, and create a new repository with the current state of the code as a starting point. - Start a new repository with the current code state, but keep the old…

I'm not discounting it, I simply don't agree with how git implements it. IMO the correct option is to create a new repository that has the same history as the old repository minus the offending commit (or possibly with an edited version of that commit that leaves out the offending string). Because it creates a new repository, there's no risk of data loss in your old repository. Once you're confident that the operatio…

I know a lot of people who routinely edit their local history before pushing changes to a shared repository because they don't want other people to see their true "dirty" history. This is insane.

This is no more insane than editing a source code file before you save it to the file system. Git is used as a development tool as well as version control, and developers are therefore encouraged to commit often, even if the code does not actually compile yet. There is no more need to fill the published history with all of these WIP commits than there is for me to know about every goddamn keystroke you made while you were dicking around with that config file.

Re: On undoing, fixing, or removing commits in git

#38
post #9

"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.

It makes it fast and easy to back out if you screw anything up. Even if the data is still there, it can be complex to pull it back out and configure it the way it was when you started (as the commands in this tutorial demonstrate.) So a fast, easy snapshot before executing complex commands is a smart move.

Re: On undoing, fixing, or removing commits in git

#39
post #9

"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.

I agree that git is both a great advance and seems fundamentally broken at the same time. One of git's advances is that it treats commits as snapshots of the entire tree rather than diffs[1]. A snapshot might as well be a tarball of the whole directory, except that git uses references to previous snapshots to store it efficiently. So in this aspect, git is like a backup tool plus compression. It's not quite a useful tool just for making compressed backups of source code, though, because data is buried in opaque internal files in the .git directory and can't be untangled from the commit history. You can't get at your data without going through git's tools, which means you might need to make your own backups in case git goes insane, and you can't use the backup functionality without creating indelible history.

I'm thinking that the repository could be moved out of the working directory and placed in its own file that's not invisible. If the repo was reified into a visible file, then repos would be portable and you could ftp them. The backup functionality could be separated from the history-tracking functionality, so you could make backups freely without adding noise to the commit history. A backup would basically be a tarball that you could append to a repo file, taking advantage of previous entries for compression. Commits, however they were implemented, could reference snapshots, but they needn't be 1:1.

[1] http://git-scm.com/book/ch1-3.html

Re: On undoing, fixing, or removing commits in git

#40
post #34
post #32

Earlier quoted context omitted.

I'm not discounting it, I simply don't agree with how git implements it. IMO the correct option is to create a new repository that has the same history as the old repository minus the offending commit (or possibly with an edited version of that commit that leaves out the offending string). Because it creates a new repository, there's no risk of data loss in your old repository. Once you're confident that the operatio…

You don't actually know how git implements it, so how can you disagree with it? There is no such thing as "an edited version" of a commit. A commit is identified by a SHA1 hash of its index of contents. If you change one bit you get a new commit . You're a C programmer, right? If someone gave you a specification for writing a program to implement git, without telling your what it was, you'd tell them it would take 2…

I understand how it works. Of course there's such thing as "an edited version" of a commit: it's a new commit that you create by taking an existing one and altering it. If you want to argue about terminology, please be my guest, but that's all your dispute is.
Post reply on HN