Why Does Git Reject Two Pushes In A Row?

- 1 answer

Often when I push changes and then push more changes I see the "rejected, not fast forward" error. This happens when I am the only one using a repository so I know there have been no other changes.

It seems to depend on the time between the pushes. If I do one push and then wait a few minutes before the second push, it does not happen. If I do two pushes quickly, within one minute or so, this happens often or always.

Could this be a result of some timing skew between system clocks? Is it possible that git thinks my second push is before the first one because clocks don't agree perfectly?

In the past I would do git pull to fix this, but that would create difficult merges. Now, I just use the option to force push if the remote has diverged.

I am just confused how git could think the remote has diverged when I am the only one pushing to it? Can anyone clarify the likely causes of this issue?




From the comments we've now determined this is happening because you are doing a quick fix (perhaps a typo or similar) and amending the previous commit. Once you amend a commit that you've already pushed, you will have to force push instead of regular push.

Presumably the reason it seemed like it was timing based, is because you were more likely to amend a commit shortly after committing and pushing a commit you just made a minute ago, whereas working on a new thing and committing that would take more time.

As for why amending requires a force push, Git looks at the commit IDs on your branch and the remote branch when determining if a regular push is allowed. If there are commits on the remote that you don't have on your local branch you are trying to push, it will error unless you force push. Every time you amend a commit, you are changing something about the commit and so a new commit ID will be created, meaning the previous one you already pushed is no longer on your branch.

Tip: when force pushing, it's a good habit to use:

git push --force-with-lease

instead of the more obvious git push --force. The reason is --force-with-lease will still error if there are commits on the remote branch that you haven't fetched yet, meaning you (probably) don't know they're there. If you're the only one working on your branch it's unlikely for there to be new commits out there you don't know about, but if you happen to work on the repo from two different machines it could still happen, if for example you push some commits to your branch from work and forget to fetch (or pull) when you get home.