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.
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.
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.
edit: This should be in reply to jordigh's comment above
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.
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.
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.
Most people only know github and I don't think they expose this locking feature in their UI which is a shame.
Branches also encourage a workflow [in my experience] where the devs implement multiple unfinished features on different branches. That's another form of technical debt. If everyone works right on master, it is more natural to finish a feature before moving onto the next.
I've also had to rewrite history on a git repository to remove things like binary files.
In the top level comment for this thread, I'd say the situation could have been avoided if that developer were cherry-picking to the git repo on his computer, then pushing that branch to the server. The history would be present on both that dev's computer as well as the server, so losing the history on the server would not affect the branch on that developer's machine. Not sure if the comment implies the developer had SSH'd to a live server & performed his cherry-pick there, but that's how it sounds.
The only use I've found for [feature] branches in my day to day work is a place for a junior developer or un-trusted OSS contributors to push changes for me to review before I merge them in. If I'm on an experienced team, I find things go smoothest if we all stay on master.
You can solve that by regularly merging or rebasing master onto your feature branch (as described in Fowler's article).
I think this is probably common in places that have used SVN/Perforce/Whatever since forever and migrated to Git because it's now a "best practice"
alias gitpushf='git push --force-with-lease'
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?
Second why ever use force merge?