A few days ago I posted some Git tips and tricks, one of which was that you should use
--force-with-lease any time you want to use
Why should you do this? Basically
--force can be destructive and
--force-with-lease is a little more careful before changing history. Let's hear from this Atlassian blog post again:
--force-with-leasedoes is refuse to update a branch unless it is the state that we expect; i.e. nobody has updated the branch upstream. In practice this works by checking that the upstream ref is what we expect, because refs are hashes, and implicitly encode the chain of parents into their value.
If you're already familiar with this concept you might be using an alias to invoke
--force-with-lease. Mine looks like this:
lease = push --force-with-lease
This allows me to type
git lease and have the same effect as
git push --force-with-lease. If this works for you then perfect! You don't really need to read any further.
The problem I have is that in a lot of my command line usage, Git and otherwise, I regularly type
--force for various reasons. It's muscle memory that I've developed, and I regularly find myself force pushing the wrong way. It's bad and I feel bad. So bad that I spent some time recently working on this quick and dirty (but also kind of neat) solution to short circuit my use of the bad force altogether:
(Writing shell commands is not my strong suit, so if you see ways this can be improved I am all ears.)
This is a shell function I've added to my ZSH profile. Here's a quick breakdown of what it does:
- First, it overrides the
gitcommand. (I know it's probably not a great idea overriding git, don't email me, do this at your own risk, whatever)
- It looks for use of the
push. If that isn't found, continue on regularly.
- If you're using
--force, continue on regularly.
- If you are using
--force, replace that argument with
- If you're using
--forceand you really need it, you can add
--seriouslyto avoid having it replaced with
- In any case, any other arguments are still applied regularly.
So now we can do the following:
# Regular use of --force-with-lease unaffected ➜ example git:(master) ✗ git push --force-with-lease Everything up-to-date # Use of --force overridden ➜ example git:(master) ✗ git push --force Detected use of --force! Using --force-with-lease instead. If you're absolutely sure you can override with --force --seriously. Everything up-to-date # Use of --force not overridden if --seriously ➜ example git:(master) ✗ git push --force --seriously Heads up! Using --force and not --force-with-lease. Everything up-to-date
That's it! Now I can lazily avoid having to change my ways. Would love to hear what you think.