It's easy to accidentally force-push to the wrong branch. If you're on the wrong branch (e.g. you think you're on your personal dev branch and want to update it after a rebase but you're actually on the mainline) `git push -f` will ruthlessly clobber the remote.
Github/PR workflows often (usually?) recommend cleaning up pull requests (via rebase -i) in the same way submissions of patchsets get reorganised and cleaned up after comment then resubmitted (whether to a mailing list or a patch review tool like gerrit) rather than adding new cruft on top of the initial patchset.
That does indeed require "foot shooting" as the old branch needs to be replaced by the new one, lest each resubmission lose all existing discussion and comments and each tentative change ends up using half a dozen different pull requests.
That being said, like you, I use hg, haven't used git very much.
And especially, especially if this is a team branch. At least make a copy of the old branch with a backup name, so you can undo your damages easily. It takes like 1 second.
e.g.:
# yes!
git push origin my-feature-branch
git push origin master
# no!
git push --force origin master
nsfyn55 makes a good point about protection from others, though. Maintaining my own fork, and using pull requests to the central repo, seems to help avoid others clobbering master, but that seems to be more of a reflection of my organization's Git workflow.If your team treats Git the way we used to use Mercurial, where each developer will merge their changes into master and then push it, you're going to be in a WORLD of hurt. (It's likely we were doing it wrong there, too. I didn't really grok distributed source control until we moved to Git.)
If you use the Github Flow [0], the merging is done in the UI of your Github (or Gitlab/etc) instance, rather than directly with `git`. (I believe Atlassian's stash has a similar but slightly different recommended workflow.) The keys for us are:
- One team repo is the "official" repo. (e.g., UI/foo-widget)
- Each dev forks the repo, and pushes their branches on that fork
(e.g. gknoy/foo-widget:gk-feature)
- Pull Requests are made from the dev's repo __to the official one__
(e.g. from gknoy/foo-widget's gk-feature branch
to UI/foo-widget's master branch)
Some teams instead opt to have each dev make branches on the same (official) repo. I prefer the extra safety net of maintaining my own fork. If I were to mistakenly commit something (or merge something, or rebase something) incorrectly, and totally fubar my repo's master branch, and then push that up to my origin before noticing it, I can recover it easily (rename branches, checkout the commit that should be the head, re-push). Worst case, I can delete my fork and re-fork it. ;) If I were to do that on a repo that I have shared access to, I'd have much more anxiety.Incidentally, I've made exactly that mistake (merged or committed something onto my local master, and then pushed it to my origin) TWICE, and caught when others have when doing code reviews. The first time, I panicked and deleted/re-created my forked repo. The second time, I fixed it by juggling branches, and it was substantially easier. (Slower: it took me ~20 minutes I think?) In neither case did my mistakes affect anyone else, though, since the repo I messed up was my own.)
This is, of course, based heavily on Github's suggested practices, since we use Github Enterprise at work. Were I using Stash or GitLab, there would likely be some changes, but I think the team workflow really benefits when you dive all-in on Git's distributed nature.