10 ms·
How to undo almost anything with Git
- alphydan 11y agountil this happens: http://renooble.tumblr.com/post/18845123629/git-funny-scary-story http://renooble.tumblr.com/post/18845123629/git-funny-scary-...
- mmanfrin 11y agoMy only real git crisis was when I accidentally `git push -f`ed what I thought was my own branch, but actually the `develop` branch. On a monday. After a weekend where about a hundred commits had been cherry picked and merged in to develop by a dev not in the office. None of my coworkers had recent versions of develop. The thing that ended up saving me was our CI -- we autodeployed passing builds to our staging env; so we were able to ssh in and `git push -f` back from staging to our repo.
- jordigh 11y agoMercurial Evolve is a safe and distributed alternative to `git push --force`: https://www.youtube.com/watch?v=4OlDm3akbqg https://www.youtube.com/watch?v=4OlDm3akbqg
- herge 11y agoFor what it's worth, you could have looked at the reflog of the git repo on the server and it would still have a reference (the hexadecimal hash) to the develop branch before your git push -f.
- mmanfrin 11y agoWe had the hash, but no one had it locally and we could not pull it down since I had overwritten the history.
- simoncion 11y agoThis isn't a criticism. I'm either missing info, and am making a fool of myself, or telling you about something you didn't know was possible: You either had git configured on the server to git-gc after every push, or were unable to ssh into the server? If neither one of those is true, then -IIRC- you could have either: 1) Logged in to the server, rewritten the affected repo's branch to point to the pre-disaster commit hash. 2) Pull down the repo's .git directory from the server, rewrite the branch, and force push that. Would either one of those have been more work than working with your CI system?
- dsp1234 11y agoGit generally doesn't delete commits until a garbage collection is done (and assuming no other references). If you find yourself in this situation again, then try: git reflog show remotes/origin/develop This will show the reflog for the branch, then you can find the hash just before your push, check it out, then force push it back. I've recovered from other developer's accidental force pushes in less than 5 minutes, with no commits lost.
- jordigh 11y agoBut if the remote has advanced since you pushed, you'll still need to reflog on the remote server, right?
- lmm 11y agoSomeone must have pushed the version the remote was at, so the correct commit would be on someone's devbox.
- mmanfrin 11y agoIt was a series of PRs merged on github, no one in the office had a current branch of develop.
- dsp1234 11y agoIt looks like you can use the GitHub API to get the events for the specific repo, which would include your force push, and the hash of the previous commit. Some instructions at https://objectpartners.com/2014/02/11/recovering-a-commit-from-githubs-reflog/ https://objectpartners.com/2014/02/11/recovering-a-commit-fr... edit: This should be in reply to jordigh's comment above
- lmm 11y agoIf it's just a matter of "merging" couldn't you just merge those branches again? Or do you resolve conflicts on github or some such (something that's never fit my workflow but I can imagine others using it)?
- _ikke_ 11y agoI always recommend people to use `git push --force-with-lease`. It's more to type, but it verifies if the remote branch is the same as the remote tracking branch, so you don't accidentally rewrite branches someone else has pushed to.
- rectangletangle 11y agoYou can just alias it in your bash profile, if it's too much to type. alias gitpushf='git push --force-with-lease'
- Peaker 11y agoJust make an alias pushf = push --force-with-lease, and it becomes even less to type! :-)
- matwood 11y agoPlaces like bitbucket let you mark branches (like master and develop) as non-deletable and non-rebaseable. Basically it prevents errors like yours.
- smtddr 11y agoSeriously. I don't understand why github doesn't provide at least the ability to lock the master branch against any action other than a merge from another branch. Merging a branch that causes major damage is unlikely if there's any kind of review process and generating a revert to "undo" that damage is a one button thing in the github-webUI if you do it immediately, or at least before master gets other commits on top of it. But I'd think everyone's workflow would stop because they'd have a ton of conflicts from a screwed up master. In fact, let me ask HN. Does anyone work in a place where devs commit directly to master? I can't even imagine that workflow. Everything I've seen or heard of is PullRequests, code-review, +1, then merge to master.
- yawaramin 11y ago> Everything I've seen or heard of is PullRequests, code-review, +1, then merge to master. That won't help you when you think you're pushing to and from your own branch, but are accidentally on develop and force-pushing to the remote develop branch.
- detaro 11y agoBut if your process is only merging PRs, then locking the master against pushes as he proposes would create no further issues, preventing that from happening. If you need to modify the master directly, it would complicate things.
- deleted 11y ago[deleted]
- matwood 11y agoThat's where locking down the branches and preventing rebases comes into play. It prevents someone from accidentally doing what you describe. Most people only know github and I don't think they expose this locking feature in their UI which is a shame.
- chjj 11y agoMy most recent major git crisis wasn't reversable by git. A little while ago, I accidentally did a `git clean -xdf` on my home directory (wrong tmux tab). I index my home directory: just the most important config files, among other notes and text files. That `git clean` call wiped half my home directory before I realized what was happening and frantically tried to ^C and ^\ it. I had to find other ways to recover my files. The deleted files weren't essentially important, which is why I didn't back them up frequently or index them, but they were moderately important. That was a bad day. I realize it's probably better to dump everything in ~/.config and index that instead, while maintaining symlinks in ~/. It was just the way I had it set up.
- ossreality 11y agoYou know to fix this? Symlink your bullshit in ~/ to some other directory. I have a "my_config" repo on GitHub that contains personalized home files. Shockingly!!!!! they're not stored in my home directory because that would be an absurd idea! Instead .{vimrc,profile,bashrc} are symlinked to ~/code/{mysusername}/my_config/{_vimrc,_profile,_bashrc). Guess how many times I've wiped out my home dir? (it's zero, zero times)
- leni536 11y agoI suggest to use GNU stow for managing config files and keep your repo in a separate directory.
- tomjen3 11y agoHow is this not undoable with whatever the reverse merge command is? Second why ever use force merge?
- erikb 11y agoMaybe that was why I always `git fetch && git push -f`. But luckily since a few months it's not a problem anymore if you configured your git correctly, because now it only force pushes your current branch.
- Peaker 11y agoJust make an alias pushf = push --force-with-lease, and it becomes even less to type! :-)
- Kiro 11y agoWhat kind of workflow do you use where a git push -f is necessary? Just curious, I'm no git expert.
- npongratz 11y agoI've used the following flow chart to help determine strategies to get myself out of messes: http://justinhileman.info/article/git-pretty/ http://justinhileman.info/article/git-pretty/ Just another way of presenting similar information. No affiliation, just a satisfied consumer of the info :)
- mikekchar 11y agoHa ha! I like the part of the flow where it goes: "Is anyone downstream?" -> yes -> "Enough to form a lynch mob?" -> no -> "Do you hate them?" -> yes -> "We're going to do an interactive rebase".
- joshribakoff 11y agoI use this one. Also the same information, but its in paragraph form like the OP, but with hyperlinked questions to jump around like you would in a flow chart. http://sethrobertson.github.io/GitFixUm/fixup.html http://sethrobertson.github.io/GitFixUm/fixup.html
- thyrsus 11y agoSomething I'm still working out.... I have a directory tree full of test data. As the project goes along, the test data will evolve, and thus should go under revision control. Testing needs to start with known files, so, hey!, git checkout test_data - except that means my latest code revisions need to go into the test_data branch even before they're tested :-(. Then the tests make their changes to the data, which the tests check, and which I then want to throw away. So: "git checkout test_data -f; git clean -f" -- except that cleans out the source code area as well as the test data area. I'm thinking the test data should be separate repository. Is that a mistake? [Edit] I've tried looking at stackoverflow.com, but searching for "git testing" returned ~7000 articles, the first few hundred of which didn't look relevant.
- phaemon 11y agoYou can do: git checkout test_data 'testdata/' to only grab the 'testdata/' directory from that branch. You can do this with files with a pattern, like '*.c', as well.
- nothrabannosir 11y agotry putting test data templates in test_templates (under rev control), and doing rm -rf test_data, cp -r test_templates test_data at the start of your testing routine. Put test_data in .gitignore. does that help?
- lmm 11y agoKeep the "pristine" version of the test data in src/ (checked into git), have the build process copy it into target/ (or build/ or whatever you want to call it; either way, ignored in git) before starting testing.
- thyrsus 11y agoThanks! On the one hand, git seems to restore the test data to its initial state faster than rm -r; cp -r, but I'm getting a strong hint from these answers that keeping the test data explicitly in sync with the code is worth the minor delay.
- pjc50 11y ago
- deleted 11y ago[deleted]
- johnnymonster 11y agoThis does not cover the only scenario which I was hoping it would. I accidentally pushed my api key/password to github and I want to "undo" that push and completely remove the history locally and on an origin? This is so obscure across many different outlets. And go ahead, flame me for pushing my password/api key to github, but all of you know you have done this at least once in your life!
- deleted 11y ago[deleted]
- akerl_ 11y agohttps://help.github.com/articles/remove-sensitive-data/ https://help.github.com/articles/remove-sensitive-data/ That said, as the article points out, you need to consider them compromised once they've been pushed and rotate the creds.
- pimlottc 11y agoTo add to this, this is not just good paranoid practice. Don't just think you're safe because you fixed it 5 minutes later and probably no one noticed. There are sites that monitor the global github commit feed looking for things like AWS credentials and SSH keys. If it's been pushed to a public github repo for even a moment, it's been grabbed.
- scott_karana 11y agoEven slightly more obscure things, like the config file for Sublime SFTP (`sftp-config.json`) have been personally observed as a target of crawling.
- seanp2k2 11y agoIt's still useful to know how to use e.g. BFG for e.g. Situations where you push a password to private git / GH :)
- hrez 11y agoIf it is a public repo it's compromised, period. Change keys/passwords ASAP regardless of what you do with the repo.
- crimsonalucard 11y agoas great as git is, I wish there was something more intuitive. Git is definitely one of the more confusing tools out there.
- VLM 11y agoI'm curious if you don't like the concepts of how it works or the UI or maybe the workflow. A workflow example would be doing a rebase after a push is almost universally seen as naughty so why permit it without some kind of UI like --I-really-know-what-i-am-doing=yes or something? WRT the UI itself, I've read a couple people claiming the emacs magit package is easier to use than the CLI itself, which would isolate the problem to the GUI. I have not personally invested the time into magit and would find comments on that theory by people who have experimented to be interesting. http://magit.vc/ http://magit.vc/
- zyxley 11y agoGit's CLI is just awful in a bunch of ways. There's a bunch of commands that do two or more different things depending on how you use them, and whole piles of cryptic and incomprehensible error messages. Heck, the just the contrast between `git add <file>` and `git reset HEAD <file>` is terrible.
- mnarayan01 11y agoI wouldn't describe the CLI as "awful", though I hear your complaint. Not sure where you're going with `add` versus `reset` though. `git rm --cached ${file}` would presumably do what you want with parallel syntax.
- zyxley 11y agoThe sane way to do it would be to have something like `git stage` and `git unstage`, as distinct single-purpose commands.
- 11y ago
- ocdtrekkie 11y agoThis is pretty useful for Git noobs like me.
- js2 11y agoWas this taken from https://news.ycombinator.com/item?id=9661349 https://news.ycombinator.com/item?id=9661349 or is it just a coincidence?
- chriscool 11y agoInstead of "git reset --hard stuff", I recommend "git reset --keep stuff" as it will not delete uncommited files in the working directory.
- jgraham 11y agoThat is reasonable, depending on what you are trying to achieve,, but I think the explanation you gave is a bit misleading. Neither --hard nor --keep affect files that have never been comitted. The difference is that --keep aborts if it would affect a file that is tracked, but has uncommitted changes.
- nbouscal 11y agoThis is pretty good, I had never seen autosquash before. Another rebase flag that I find useful is --onto. For example, to rebase only the most recent N commits of a branch onto master: git rebase HEAD~N --onto master
- daxelrod 11y agoSee also http://sethrobertson.github.io/GitFixUm/fixup.html http://sethrobertson.github.io/GitFixUm/fixup.html which has helped me immensely in the past.
- chx 11y agoThough I walk through the valley of the shadow of rebase, I will fear no evil: for reflog are with me (sorry, couldn't resist)
- forrestthewoods 11y agoI'm so glad I use Perforce. Yeah branches are a bit cumbersome. But it's idiot proof. There is literally no way for any artist to cause irreversible harm. They can't even do harm that isn't easy to fix with a few clicks in an easy to use, easy to understand, easy to discover GUI. I suppose one of the key features of Git is the ability to rewrite history. It makes a lot of sense in the context of an open source project pulling in changes from the wild. For most of us such utilities aren't just useless they're actively harmful. Never leave me P4. Please God never leave me.
- jebblue 11y agoWith Git though, I can and do have many micro repositories scattered around my disks. My bin and Documents directories almost always have their own repositories each. Git works great for this as well as being a tool to help teams with code management. I do have to Google a lot of stuff for it but it works really well and this article is a good summary.
- erikb 11y agoI'm a huge git fan but I have to agree. At least some of the VCSs out there should be non self-destructive. Git is really bad if not all users of a repo take the time to learn to use it efficiently.
- learnstats2 11y ago> Git is really bad if not all users of a repo take the time to learn to use it efficiently. The "if" clause here happens rarely enough that I can quote just the first four words of the sentence: "Git is really bad." There are 2000 words here on how to undo.
- erikb 11y agoWell, git should not be the default, but that doesn't make it a bad tool. Think about different heads for screw drivers. Just because you have bought a set and there is one you never or seldom use, doesn't mean it's a bad head. The moment someone has a screw which needs that head suddenly all other heads are useless and that's the best head you can have. Right? (I'm not so sure what the right English word for "head" is, I hope it still makes sense even if I use the wrong one) Or another example. Cars are a highly specialised tools. Nobody is allowed to use one if they haven't shown that they have learned to use it properly via standardized exams. Maybe if a company uses a lot of git the mistake is that they don't require people to learn it properly first, either by offering courses or by filtering in the hiring process. And since I've spent month learning it and now can use it even in potentially destructive situations like "git rebase -i" I can tell you that for me it's way more useful than SVN or CVS ever were.
- vacri 11y agoOne particularly tricky thing that this page doesn't mention is removing binary blobs (or any file) from the history. Someone committed tens of megabytes of binary stuff to one of our repos. A later commit 'fixed' this by removing them. But those binary blobs are still there, because it's a historical commit, meaning every time you clone the repo (or similar) you get huge amounts of crap. Maybe --squash will fix it? Something to look at, I guess.
- Skinney 11y agoAs far as I know, you need to use rebase --interactive and delete the commit(s) that introduced the blobs. This will, however, create a new tree which can be painful for everyone involved.
- victoria1111 11y agoDR Grace Ude IS THE ONLY SPELL CASTER TO TRUST!(greatspellofsolutiontemple@gmail.com) will be of great help to you. I never believed in spell casting but After 4 years of dating my hobby, he left me because I lost my womb . I felt like my life has come to an end, I almost committed suicide, i was emotionally down for a very long time. Thanks to the spell caster called Dr Grace whom i met online after my friend Tracy told me about how she helped her. She testified about how Dr Grace brought back her Ex in less than 3 days and reversed the effect of her lost womb, and at the end of her testimony she dropped Dr Grace's email address. I decided to give Dr Grace a try. I contacted her via email and explained my problems to her. In just 3 days, my Hubby came begging. We resolved our issues, and we are even happier than before, to God be the glory, am pregnant now, Dr Grace is really a gifted woman and i will not stop publishing her because she is a wonderful woman... Come to think of it I didn't pay much and all I have to do is send her little 250 dollars which she used in providing the materials used for the spell. Even my pastor said that God works mysteriously, that some women are used by God to help others. If you have a problem and you are looking for a real and genuine spell caster to solve all your problems for you. Contact Dr Grace anytime, she is the answer to your problems. Here's her contact (greatspellofsolutiontemple@gmail.com)
- jokoon 11y agogit checkout is what I want to do most of the time, but I always have been confused with svn checkout, so I never could remember it.