Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

How is push origin HEAD --force-with-lease different from normal git push? Can someone please explain this to me?


It will overwrite the tree on remote as long as remote hasn't changed since you last fetched it. Like --force, but can help to prevent overwriting other people's changes when they push in between you fetching. It doesn't always work, particularly if you have a tool which continuously fetches remote, like an IDE configured to do so such as VSCode. In that case, you will have fetched the other person's changes, and --force-with-lease will happily blow-away anything on remote that might not be in your tree yet.


Oof, thanks for that warning. So it will blow away changes you haven’t merged (only fetched)?

I guess git can’t tell the he difference between “not merged yet” and “don’t want to merge, please destroy”


If you don't want to blow away changes you haven't merged, you shouldn't be doing force at all?


Well, the article presents a seemingly nice workflow that lets you handle local rebases. I was considering it.

However, we use vscode, and I rather like auto fetch. But apparently this workflow would destroy something auto fetched that I might not have even noticed.


The changes still exist in the repo’s reflog (for 30 days by default), but they might not be reachable from the ref’s new tip commit.


When you work with a rebase-oriented workflow, it's very common to submit a PR for review and then address incoming review comments as fixup commits: https://blog.sebastian-daschner.com/entries/git-commit-fixup...

This necessitates force-pushing to your feature branch after all the fixup commits have been approved and then squashed. At that point you can merge the cleaned up feature branch in to your develop or trunk.

`--force-with-lease` is slightly better than `--force` because in the event that you're also working on a collaborative feature branch you won't overwrite any commits that somebody else pushed up that you haven't fetched yet.


This is the kind of workflow that makes me headdesk. Those fixup commits weren't obvious, and will be useful context if a future maintainer ever has to go back to these - they shouldn't be squashed.


It's not really, but there are a couple minor differences in practice.

First, it assumes the name of your upstream repository is "origin" which is fine in most cases as that is what `git clone` defaults to naming the remote.

Second, using `HEAD` always pushes your current checked our branch to your remote with a remote branch of the same name. It's a neat trick to skip the "`git push` -> you need to set your upstream branch -> push command the git outputs" loop.

Lastly, `--force-with-lease` is a safer version of `--force` or `-f` because it tries to ensure that you don't overwrite history accidentally. The `--force-with-lease` flag will fail if a coworker for example pushed a commit to your branch that you didn't know about. Where a regular `--force` would just overwrite that change.

I assume that the command is meant to be "safe" and "foolproof", in that this command should always work.

Since the parent post recommends a lot of rebasing in their other commands, you'll need a `--force` or `--force-with-lease` to push new commits because they won't be "fast forwardable"


If git ever got a redesign from scratch, they should make -f be --force-with-lease, and make -F be --force[-with-prejudice].


A normal push will only advance the remote branch if your local branch has the tip of the remote branch as an ancestor. This ensures you're only adding commits to the remote branch and not replacing any commits on the remote.

But if you've pulled the remote branch, rebased, and now wish to push, the tip of the remote branch is longer an ancestor of your local branch. In this scenario, to update the remote branch you have to do a force push.

But now imaging that another developer has added new commits to the remote branch in the mean time. If you do a force push, you will overwrite those new commits.

Using "--force-with-lease" ensures that the tip of the remote branch hasn't changed since you last pulled it, so that your force push isn't erasing any commits on the remote by accident (i.e. it ensures the remote branch has not changed in between when you last pulled it and your current force push.)


Force with lease is like force push except if the branch you are force pushing to has changed since you last fetched then it will cancel the force push.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: