DEV Community

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

Posted on • Edited on

1

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:

function git {
# Only touch git if it's the push subcommand
if [[ "$1" == "push" ]]; then
force=false
override=false
for param in "$@"; do
if [[ $param == "--force" ]]; then force=true; fi
if [[ $param == "--seriously" ]]; then override=true; fi
done
# If we're using --force but not --seriously, change it to --force-with-lease
if [[ "$force" = true && "$override" = false ]]; then
echo -e "\033[0;33mDetected use of --force! Using --force-with-lease instead. If you're absolutely sure you can override with --force --seriously.\033[0m"
# Unset --force
for param; do
[[ "$param" = --force ]] || set -- "$@" "$param"; shift
done
# Replace it with --force-with-lease
set -- "push" "$@" "--force-with-lease"; shift
else
if [[ "$override" = true ]]; then
echo -e "\033[0;33mHeads up! Using --force and not --force-with-lease.\033[0m"
fi
# Unset --seriously or git will yell at us
for param; do
[[ "$param" = --seriously ]] || set -- "$@" "$param"; shift
done
fi
fi
command git "$@"
}
view raw git-push.bash hosted with ❤ by GitHub

(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)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay