DEV Community

Cover image for Default to safe force pushing in Git (without aliases)
Jody Heavener
Jody Heavener

Posted on • Updated on

Default to safe force pushing in Git (without aliases)

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 --force.

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:

What --force-with-lease does 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
Enter fullscreen mode Exit fullscreen mode

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 git command. (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 push and not --force, continue on regularly.
  • If you are using --force, replace that argument with --force-with-lease.
  • If you're using --force and you really need it, you can add --seriously to avoid having it replaced with --force-with-lease.
  • 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
Enter fullscreen mode Exit fullscreen mode

That's it! Now I can lazily avoid having to change my ways. Would love to hear what you think.

Top comments (0)