4 ms·
Wouldn't it be great if your scm actually kept all your changes no matter what?
by spullara 16y ago
Wouldn't it be great if your scm actually kept all your changes no matter what?
- pwim 16y agoAs far as I understand, git actually always keeps your changes. It is just the pointers that can be overridden if you force an update. For instance, git reflog show origin/master shows even remote forced-updates. So although it looked like the commit was lost, it was still there, just not immediately visible, and was fully recoverable.
- docgnome 16y agoYou can lose commits if you use git gc but you're probably aware of what you're doing when you do that.
- dilap 16y agoEven with git gc you have to try pretty hard to lose updates -- I believe by default it will leave stuff only reachable from the reflog around for 90 days. (I <3 git.)
- rtomayko 16y agoYeah, exactly. We (GitHub) use reflogs on the server, so everything that was pushed was in the repository and can't be gc'd out for at least 90 days. The master branch ref was just pointing at the wrong commit due to the forced pushes.
- tomstuart 16y agoReflogs are a lifesaving Git feature, but I imagine a large proportion of "casual" Git users don't know they exist, not least because a lot of people's Git education comes from poking around the GitHub interface. It'd be amazing if GitHub began exposing reflogs through the web somehow.
- josegonzalez 16y agoI mean, "-f" is for forcing overwriting of changes. The other developer had several recourses. The awesome ProGIT book: http://progit.org/ http://progit.org/ The hotness of the GitReady: http://gitready.com/ http://gitready.com/ The great MAN pages of course: http://www.kernel.org/pub/software/scm/git/docs/ http://www.kernel.org/pub/software/scm/git/docs/ GitCasting like a boss: http://gitcasts.com/ http://gitcasts.com/ GIT users on IRC: irc://freenode.net/git And of course, Github itself. They're awesome in a box: http://help.github.com/ http://help.github.com/ Regardless, it's nice to see a developer publicly admit the error of his ways, and even nicer to see other developers brush it off and keep going as they give support.
- matt_yoho 16y agoBald-faced pimping of a resource the company I work for, EdgeCase, put together as well: http://gitimmersion.com/ http://gitimmersion.com/
- js2 16y agoThat's like saying: wouldn't it be great if your filesystem kept all your files no matter what. Well, no, there are instances where you want to actually throw things out. The push man page specifically says: -f, --force Usually, the command refuses to update a remote ref that is not an ancestor of the local ref used to overwrite it. This flag disables the check. This can cause the remote repository to lose commits; use it with care. And even with that, the commit wasn't lost yet. It likely in the reflog of the remote repo, and in the history of whichever repo the change was originally pushed from. That said, there are ways to lose work with git that aren't recoverable ("reset --hard" silently overwrites uncommitted work), but this isn't one of them.
- groby_b 16y agoThe difference being that an SCM records the history of your project. It would certainly be possible to record this simply as a "forced overwrite" in the history. Which git sort-of does (reflog). And then, after it prevented you from shooting yourself into the foot, it gives you a loaded Howitzer pointed at your face. (git reflog expire/git prune/git gc) I love git dearly, but that's still a large flaw in its design. There is no reason to ever lose history.
- spullara 16y agoSo it appears that every response to my message said that it wasn't lost but would be in 90 days if no one noticed. That is not the definition of 'never loses changes'. The fact of the matter is that someone that doesn't understand the way git works can cause irreversible damage without recourse if not discovered. In many source control systems this is not the case. I still use git on github even with this flaw.
- tomstuart 16y agoYou can configure git-receive-pack to not allow ref deletes (receive.denyDeletes) or any ref updates which aren't fast-forwards (receive.denyNonFastForwards), which makes this kind of data loss impossible. With Gitolite you can even set this permission per-user per-branch (https://github.com/sitaramc/gitolite#_main_features https://github.com/sitaramc/gitolite#_main_features) so that the great power is only given to those with the great responsibility to handle it. Of course, somebody still has to know and care enough to want to tweak the default configuration, and it doesn't help with GitHub for the moment, but I wouldn't be surprised if they added finer-grained branch permissions in future.
- sgentle 16y agoI think, though, that for "never loses changes" to be meaningful it has to be shorthand for "never loses changes unless you do unsafe things". I mean, it certainly loses changes if you don't push to anywhere and then delete your .git directory. The -f should mean "don't do this, it will probably wreck your shit". Unfortunately certain tools seem to require it way too often so it seems to be going the way of the venerable confirm dialog. "Deleted all my files? I dunno, some funny box popped up and I hit OK. Was that it?"
- azernik 16y agoThis user training gets even worse because git, when refusing to perform an unsafe operation, trains the user to force instead of training the user to fix the problem. For example, the developer who overwrote the commits in the case in question probably did so after seeing the following error message: abort: push creates new remote heads on branch 'default'! (did you forget to merge? use push -f to force) While it mentions merging, the only recognizable command line ("push -f") is for a destructive operation, instead of the operation (pull or merge, depending on the situation) that will actually fix the unsafe condition. Putting an even partial command line in front of a developer is like putting an OK button in front of a non-technical user - they tend to just use it to see if it (superficially) works. When it (subtly) fails, a novice user will not notice, and will just remember "push -f" as the Right Way to Use Git.