I always preach never to force push anything, because that adds ambiguity to the repository server.

In this specific example, we collaborate with a customer and they "skip a step" and force push instead of appropriately pulling and merging. This takes the ambiguity of what code is good, what code is bad, out of their working directory and into the server. Two heads on this branch, which one do I use, etc. I am looking to use a hook to disallow force pushing, I just didn't want to lock down that ability if there was a good use case for it.

We are relatively new (2 or 3 years) to DVCS, moving from SVN previously. What are the arguments for not doing a force push in a DVCS? What exceptions exist for this hard and fast rule?

@gnat I tried to improve the question and make it less subjective. Please advise if you still have concerns.
– maple_shaft♦Oct 1 '14 at 15:32

2

@bjones14 To improve your question and prevent it from being closed, do you think you can try explaining your reasoning why this is a bad idea and a use case for why this is a bad idea?
– maple_shaft♦Oct 1 '14 at 15:43

@maple_shaft In this specific example, we collaborate with a customer and they "skip a step" and force push instead of appropriately pulling and merging. This takes the ambiguity of what code is good, what code is bad, out of their working directory and into the server. Two heads on this branch, which one do I use, etc. I am looking to use a hook to disallow force pushing, I just didn't want to lock down that ability if there was a good use case for it. So far I haven't seen one yet.
– bjones14Oct 1 '14 at 17:25

@maple_shaft upon re-reading, I think I was mistaken. Your edit is much better than I originally thought. Retracted y votes down and close and purged my outdated comments
– gnatOct 1 '14 at 20:57

2

Best is to edit your question rather then embed useful info in comments.
– david.pfxOct 2 '14 at 0:28

2 Answers
2

The main reason not to force a push is that it forces everyone else to do rebases or force pulls, and any outstanding branches will not merge cleanly. Also, when beginners don't really understand how to use DVCS yet, a force push is usually a sign that you forgot a step, like doing a pull or merge first, and you can accidentally lose history or even committed code.

There are some teams who force push regularly as a matter of course. They just build it into their regular workflow. For example, a team that works on one subsystem of the Linux kernel might diverge from the "mainline" but regularly force a push to get itself back synced up. I think you have to have a fairly disciplined and DVCS-experienced team for this to work well, though.

You cannot lose history by force pushing under Mercurial. This is one of its critical differences from Git. All heads are kept, and you end up with a disgusting mass of anonymous branches. But you do not lose history, unless you manually strip or (badly) rebase.
– KevinDec 19 '14 at 17:10

This is written from a git perspective, since the force push isn't unique to Mercurial

There are commands which allow you to change your repo local repo. git commit --amend, rebase are two of the more common things that people do to modify their own repo history. This is perfectly acceptable. I've often done a git commit --amend after forgetting to include the tracking number for github in the message. But its not without peril (as the documentation says)

Ahh, but the bliss of rebasing isn’t without its drawbacks, which can be summed up in a single line:

Do not rebase commits that you have pushed to a public repository.

The thing is that the public repo should be append only. You append commits as you create them. Rewriting the public rep causes all sorts of headaches and causes everyone who has pulled form it to have to adjust their own repos to match.

There are certainly times when you will need to force a push. If you really need to modify that last commit (oppose there was a password in there), or worse, you need to go back and find old files that contain sensitive data.

git push --force is a tool. It is a very heavy handed tool that allows you to do quite a bit of rewriting of history, but it is still a tool (people have written even bigger tools yet titled bfgfor cleaning repos). To say 'never force a push' ignores all those times when you do need to rewrite the history.

In this specific example, we collaborate with a customer and they "skip a step" and force push instead of appropriately pulling and merging. This takes the ambiguity of what code is good, what code is bad, out of their working directory and into the server. Two heads on this branch, which one do I use, etc. I am looking to use a hook to disallow force pushing, I just didn't want to lock down that ability if there was a good use case for it. So far I haven't seen one yet.

The problem that is ebbing encountered, however, is not one with the tool. It is a problem with the people using the tool. If they don't have the... maturity... to handle a force push correctly, then by all means take it away from them. They likely don't need it, don't know when they should use it, or are aware of the problems that it causes. Forcing them to use a proper workflow will certainly mean more work for them... it will also mean less work for you cleaning up. On the balance, its likely that using a better workflow will reduce the overall work done and make things cleaner. Once they are fully aware of how to use the tool, and the proper way the workflow works, then let them have the unfettered toolchain again.