64

I'm trying to force push a rebase of a feature branch to a remote repository. To be a bit safer, I'm trying to use --force-with-lease to make sure no other changes have happened in the branch since I last fetched it.

This is failing for reasons I don't understand:

$ git branch
* my-branch
  master

$ git push --force-with-lease origin my-branch -u
To gitlab.com:example/my-project.git
 ! [rejected]        my-branch -> my-branch (stale info)
error: failed to push some refs to 'git@gitlab.com:example/my-project.git'

I tried a fetch to see if my local cache had somehow gotten out of sync:

$ git fetch

$ git push --force-with-lease origin my-branch -u
To gitlab.com:example/my-project.git
 ! [rejected]        my-branch -> my-branch (stale info)
error: failed to push some refs to 'git@gitlab.com:example/my-project.git'

I tried simplifying the push command a bit:

$ git push --force-with-lease
To gitlab.com:example/my-project.git
 ! [rejected]        my-branch -> my-branch (stale info)
error: failed to push some refs to 'git@gitlab.com:example/my-project.git'

I tried limiting the check to my branch:

$ git push --force-with-lease=my-branch:origin/my-branch
To gitlab.com:example/my-project.git
 ! [rejected]        my-branch -> my-branch (stale info)
error: failed to push some refs to 'git@gitlab.com:example/my-project.git'

As you can see, it fails the same way every time.

Why is my push failing, and how do I fix it?

Laurence Gonsalves
  • 137,896
  • 35
  • 246
  • 299
  • (1) Is there already an upstream set on `my-branch`? If so, what is it? (2) What's your fetch refspec for `origin`? – torek May 17 '19 at 18:32
  • @torek I found out that the problem was that the branch had been deleted on the remote, and pull/fetch don't sync deletions by default. This is why my local appeared to be in sync with the remote even when it wasn't. `--prune` when pulling/fetching corrects this. – Laurence Gonsalves May 17 '19 at 19:34

5 Answers5

59

In my case a plain git fetch followed by the push again solved the problem.

Bohumir Zamecnik
  • 2,450
  • 28
  • 23
  • 2
    Beware that a `git fetch; git push --force-with-lease` is practically the same as `git push --force`. The "lease" you get with `--force-with-lease` by default is based on confirming that the remote refs that will be updated are the same as what you last fetched, so fetching immediately before only "protects" against someone else pushing in that fraction of a second. – Laurence Gonsalves Jun 05 '23 at 17:30
45

In this case it turned out that the problem was that the remote branch had been deleted, but there was still a copy of it in my local repo. Fetch doesn't delete local copies by default, which is why it had no effect.

Adding the --prune option to my initial git pull (before doing my rebase) corrects this problem.

Laurence Gonsalves
  • 137,896
  • 35
  • 246
  • 299
  • 1
    You might also want to set `fetch.prune` to `true` in your personal (`--global`) Git configuration. It's interesting that `git push --force-with-lease` considers the value stale when there's literally *no* value on the remote to which you're pushing. That's a valid way to look at it, but not helpful: `--force-with-lease` should probably just consider this case to be "ok to force". – torek May 17 '19 at 20:29
9

If you have just done your rebase and don't want to start over again please run git remote prune origin. If you then run git push --force-with-lease again, it will work.

PieterT2000
  • 304
  • 2
  • 12
2

You may face this issue, when you're checked out to the pr using gh pr checkout <num> and trying to force push after making some changes.

The correct way to push to someone else pr is to add a remote to their repo and checkout to the branch which was used to create the pr. Then you can push your commits. It'll appear in the pr.

Krishna
  • 6,107
  • 2
  • 40
  • 43
  • In this case, I find it easier to `--force` once it's confirmed `local` was up to date with `remote` before the `rebase`. Adding one remote per GitHub user gets unwieldy quickly – DA_123 Feb 21 '23 at 16:14
0

I think that --force-with-lease may have some issues with shallow clones. There have been a few times for me where I get this message but --force works - if this happens for you, check whether you might be on a shallow checkout.

Unfortunately I don't know of any resolution to this other than converting the shallow clone to a full one, or just using -f instead.

Trevor Gross
  • 454
  • 3
  • 11