1778

I've set up a remote non-bare "main" repo and cloned it to my computer. I made some local changes, updated my local repository, and pushed the changes back to my remote repo. Things were fine up to that point.

Now, I had to change something in the remote repo. Then I changed something in my local repo. I realized that the change to the remote repo was not needed. So I tried to git push from my local repo to my remote repo, but I got an error like:

To prevent you from losing history, non-fast-forward updates were rejected Merge the remote changes before pushing again. See the 'Note about fast-forwards' section of git push --help for details.

I thought that probably a

git push --force

would force my local copy to push changes to the remote one and make it the same. It does force the update, but when I go back to the remote repo and make a commit, I notice that the files contain outdated changes (ones that the main remote repo previously had).

As I mentioned in the comments to one of the answers:

[I] tried forcing, but when going back to master server to save the changes, i get outdated staging. Thus, when i commit the repositories are not the same. And when i try to use git push again, i get the same error.

How can I fix this issue?

Community
  • 1
  • 1
Spyros
  • 46,820
  • 25
  • 86
  • 129
  • 4
    You will soon (git1.8.5, Q4 2013) be able to [do a `git push -force` more carefully](http://stackoverflow.com/a/18505634/6309). – VonC Sep 10 '13 at 08:42
  • 1
    Related: [Force git to overwrite remote files on push](http://stackoverflow.com/q/10510462/456814). –  Jul 15 '14 at 21:42
  • 14
    [As I detail in my own answer](http://stackoverflow.com/a/24987161/456814), `git push --force` is indeed another valid way to force push, and will push branches just as well as `git push origin master --force` with Git's default `push.default config settings`, though which branches specifically get pushed differs between Git versions prior to 2.0 versus after 2.0. –  Aug 05 '14 at 17:51
  • 8
    `git push --force` works fine these days, FWIW... – rogerdpack Apr 10 '18 at 20:25
  • 10
    `git push --force-with-lease` works even better :), it will refuse to update a branch unless it is the state that you expect. (see https://developer.atlassian.com/blog/2015/04/force-with-lease/) – spoorcc Jan 14 '19 at 07:58
  • **just be careful folks** > When you force push code to the master branch [remote repo] it deletes the previous code present in the master branch . > and force update your code with the previous code. **i.e when you force push previous code will bereplace by your code.** [check out this blog for more info ](https://evilmartians.com/chronicles/git-push---force-and-how-to-deal-with-it) Happy Coding :) – Sumit Mar 14 '21 at 07:01
  • I tried `git push origin some_branch --force` but it always returned `Everything is up-to-date` message. But, `git push origin your_branch:some_branch --force` and this was what I was missing. Hope it helps! – Akhil Jun 30 '22 at 18:45

12 Answers12

3110

Just do:

git push origin <your_branch_name> --force

or if you have a specific repo:

git push https://git.... --force

This will delete your previous commit(s) and push your current one.

It may not be proper, but if anyone stumbles upon this page, thought they might want a simple solution...

Short flag

Also note that -f is short for --force, so

git push origin <your_branch_name> -f

will also work.

Alex Zhukovskiy
  • 9,565
  • 11
  • 75
  • 151
Katie
  • 45,622
  • 19
  • 93
  • 125
  • 74
    You can use `git push origin +master` instead, which allow you push multiple refspecs without forcing them all. – nickgrim Nov 20 '13 at 10:36
  • 12
    Be aware that, if you accidentally do just `git push --force`, you might end up messing you master branch (depending on your push default behavior).. Which might suck.. a bit.. :D – Jeewes Aug 06 '14 at 07:18
  • 20
    @Jeewes starting with Git version 2.0, the *default* behavior of `git push --force` is basically to force push the currently checked-out branch to its remote-counter part, so if you have the master branch checked out, then it's identical to `git push origin master --force`. It'll be different if you're using the `matching` setting for `push.default`, which is the default for Git versions prior to 2.0. `matching` pushes *all* locals branches to remote ones that have the same name, so force pushing then could definitely be not what you want to do... –  Aug 12 '14 at 14:22
  • 1
    @Jeewes But with Git 2.0, the default is safer, or at least it's no more dangerous than `git push origin master --force` is. –  Aug 12 '14 at 14:24
  • Oops, **not worked** for mee (!), but I used `git push -f `, is not the same?? See (need to correct?) http://stackoverflow.com/a/10728449/287948 – Peter Krauss Feb 14 '16 at 13:31
  • 3
    push -f is good but not recoomended for master since most corporate repositories have -f disabled for master. the `merge -s ours` worked for me – mihai May 26 '16 at 21:27
  • More generally: `git push -f ` – Autumn Leonard Jun 06 '17 at 15:28
  • unfortunately on gitlab you will still have old history. – chovy Dec 21 '18 at 05:58
  • 2
    Don't forget that your remote repo permissions (read: Azure DevOps) for your account, might not grant permission to force push. In that case, you'll need an administrator to set your permissions. – LargeDachshund Apr 27 '21 at 17:30
  • --force-with-lease is a better option because it will not push if the state of the remote has changed since the last pull – openCivilisation May 10 '22 at 02:31
  • I was always doing `git push origin +mybranch` then one day I've accidentally done `git push origin :mybranch` and deleted my branch and blocked the Pull Request so that it couldn't be reopened and made everyone's day more difficult TL;DR just use `git push origin mybranch -f` – equivalent8 Feb 07 '23 at 20:31
312

And if push --force doesn't work you can do push --delete. Look at 2nd line on this instance:

git reset --hard HEAD~3  # reset current branch to 3 commits ago
git push origin master --delete  # do a very very bad bad thing
git push origin master  # regular push

But beware...

Never ever go back on a public git history!

In other words:

  • Don't ever force push on a public repository.
  • Don't do this or anything that can break someone's pull.
  • Don't ever reset or rewrite history in a repo someone might have already pulled.

Of course there are exceptionally rare exceptions even to this rule, but in most cases it's not needed to do it and it will generate problems to everyone else.

Do a revert instead.

And always be careful with what you push to a public repo. Reverting:

git revert -n HEAD~3..HEAD  # prepare a new commit reverting last 3 commits
git commit -m "sorry - revert last 3 commits because I was not careful"
git push origin master  # regular push

In effect, both origin HEADs (from the revert and from the evil reset) will contain the same files.


edit to add updated info and more arguments around push --force

Consider pushing force with lease instead of push, but still prefer revert

Another problem push --force may bring is when someone push anything before you do, but after you've already fetched. If you push force your rebased version now you will replace work from others.

git push --force-with-lease introduced in the git 1.8.5 (thanks to @VonC comment on the question) tries to address this specific issue. Basically, it will bring an error and not push if the remote was modified since your latest fetch.

This is good if you're really sure a push --force is needed, but still want to prevent more problems. I'd go as far to say it should be the default push --force behaviour. But it's still far from being an excuse to force a push. People who fetched before your rebase will still have lots of troubles, which could be easily avoided if you had reverted instead.

And since we're talking about git --push instances...

Why would anyone want to force push?

@linquize brought a good push force example on the comments: sensitive data. You've wrongly leaked data that shouldn't be pushed. If you're fast enough, you can "fix"* it by forcing a push on top.

* The data will still be on the remote unless you also do a garbage collect, or clean it somehow. There is also the obvious potential for it to be spread by others who'd fetched it already, but you get the idea.

Community
  • 1
  • 1
cregox
  • 17,674
  • 15
  • 85
  • 116
  • Looks like it's possible to do a pull after this, but hard http://stackoverflow.com/questions/9813816/git-pull-after-forced-update – rogerdpack Sep 24 '13 at 18:52
  • 1
    The problem, @rogerdpack, isn't if it's doable. It is. But it can sum up to a big disaster. The more someone do it (force push) and the less often you update (pull) from the public repo, the bigger the disaster. It can dismantle the world as you know it!!!111 At least the world comprising of that particular repository. – cregox Sep 24 '13 at 19:14
  • 5
    If you have sensitive data, force push it – linquize Nov 26 '13 at 04:58
  • @linquize not following. I'd say if you have sensitive data, revert it. – cregox Nov 26 '13 at 11:59
  • 3
    @Cawas: I think he means that if you are trying to remove sensitive data from the repository, then you *want* to rewrite history. If you revert, the sensitive data is still there in the earlier commit. That said, if someone else has already pulled from the repository, then rewriting history won't help you prevent them from accessing the sensitive data - it's already too late at that point. – Stuart Golodetz Dec 12 '13 at 09:38
  • 1
    @StuartGolodetz thanks for clarifying! I completely misinterpreted "*sensitive*" there - I was thinking just "important" and not "classified". – cregox Dec 12 '13 at 12:58
  • 3
    `git push origin master --delete # do a very very bad bad thing git push origin master # regular push` this actually solved my problem perfectly (on a repo with only me and my friend). maybe it's wrong for public repos but for a private one this is a life saver. – Can Poyrazoğlu Jan 26 '14 at 23:44
  • There is also the case that you are not pushing to a public server. You are pushing to some other repo to build on a dev box or something, and no one is interested in the old version of your work. – Joe May 21 '15 at 15:15
  • 1
    Why would anyone want to force push? May be someone has made a commit that you want to discard completely. http://stackoverflow.com/questions/37132584/git-remove-last-commits-from-remote-made-by-someone-else – Abhishek May 10 '16 at 08:27
  • 7
    this happens automatically with some repo managers, a.k.a. auto-squash etc. force pushing after finishing a feature branch to reduce commits is common and expected. – FlavorScape Jan 11 '19 at 20:37
  • Do NOT delete remote branch - rename it – Anton Duzenko Nov 24 '22 at 17:02
28

If I'm on my local branch A, and I want to force push local branch B to the origin branch C I can use the following syntax:

git push --force origin B:C
IcedDante
  • 6,145
  • 12
  • 57
  • 100
  • 3
    I found out that even I'm on my local branch B, I still need to do `git push --force origin B:C`. In my case, it seems that `git push --force origin C` will only push from local master to remote C branch, regardless of which branch I'm currently on. `git version 2.3.8 (Apple Git-58)` – Weishi Z Oct 10 '15 at 05:28
  • 1
    This helped me when moving a repository from the previous `master` branch to the new `main` branch. Just used `master:main` and it worked as I needed! – Ícaro Jan 04 '22 at 19:58
22

use this following command:

git push -f origin master
mustafa Elsayed
  • 247
  • 2
  • 2
  • 3
    Maybe give some more explanation about why this answer is preferable to the other ones, and what makes it different. – Adam Apr 10 '17 at 15:41
  • 1
    oh ,sorry for inconvenience , I was having the same problem and this command solve it , i thought i should share it . – mustafa Elsayed Apr 11 '17 at 14:30
  • 23
    It's just the same as the others, you just changed the position of the `-f` flag... – svelandiag May 31 '17 at 15:38
19

First of all, I would not make any changes directly in the "main" repo. If you really want to have a "main" repo, then you should only push to it, never change it directly.

Regarding the error you are getting, have you tried git pull from your local repo, and then git push to the main repo? What you are currently doing (if I understood it well) is forcing the push and then losing your changes in the "main" repo. You should merge the changes locally first.

ubik
  • 4,440
  • 2
  • 23
  • 29
  • 1
    yes i tried a pull but i'm losing losing data because of that pull. I want to make my main repos as my local is, without first updating from the main. – Spyros Apr 01 '11 at 06:28
  • 3
    In that case use `git push -f`, but then if you change your main repo again, you have to go back to your local repo and `git pull`, so that it gets in sync with the latest changes. Then you can do your work, and push again. If you follow this "push-pull" workflow, you won't get the kind of error you were complaining about. – ubik Apr 01 '11 at 17:22
  • yeah, i understand that this was my fault :/ I will try that and get back in a little while thanx – Spyros Apr 01 '11 at 18:56
  • 1
    tried forcing, but when going back to master server to save the changes, i get outdated staging. Thus, when i commit the repositories are not the same. And when i try to use git push again, i get the same error. – Spyros Apr 02 '11 at 18:11
11

git push --force would do the job, although git push --force-with-lease is a safer command

git push --force overwrites the remote branch, while git push --force-with-lease only overwrites the remote branch if your local copy is aware of all of the commits on the remote branch. This difference makes it significantly more difficult to destroy someone else’s changes on the project.

Jackie Santana
  • 1,290
  • 14
  • 15
10

I would really recommend to:

  • push only to the main repo

  • make sure that main repo is a bare repo, in order to never have any problem with the main repo working tree being not in sync with its .git base. See "How to push a local git repository to another computer?"

  • If you do have to make modification in the main (bare) repo, clone it (on the main server), do your modification and push back to it

In other words, keep a bare repo accessible both from the main server and the local computer, in order to have a single upstream repo from/to which to pull/pull.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Can you even push to a non-bare git repository? – hd1 Aug 08 '21 at 18:13
  • @hd1 Yes, since Git 2.4 (Q2 2015): https://stackoverflow.com/a/42745909/6309, which references https://stackoverflow.com/a/34575157/6309. – VonC Aug 08 '21 at 20:33
8

I had the same question but figured it out finally. What you most likely need to do is run the following two git commands (replacing hash with the git commit revision number):

git checkout <hash>
git push -f HEAD:master
Brian M.
  • 107
  • 1
  • 2
5

This was our solution for replacing master on a corporate gitHub repository while maintaining history.

push -f to master on corporate repositories is often disabled to maintain branch history. This solution worked for us.

git fetch desiredOrigin
git checkout -b master desiredOrigin/master // get origin master

git checkout currentBranch  // move to target branch
git merge -s ours master  // merge using ours over master
// vim will open for the commit message
git checkout master  // move to master
git merge currentBranch  // merge resolved changes into master

push your branch to desiredOrigin and create a PR

mihai
  • 4,184
  • 3
  • 26
  • 27
5

if you are authenticating with Github access token, try this:

  • git remote set-url origin https://YourTokenNum@github.com/UserName/ProjectName

  • git push --force --set-upstream origin master

Maifee Ul Asad
  • 3,992
  • 6
  • 38
  • 86
SilverTech
  • 399
  • 4
  • 11
2

Using --force-with-lease might be a better option:

git push <remote> <branch> --force-with-lease

It makes sure no one has updated the branch before you modified it, so you don't overwrite their changes.

Maicon Mauricio
  • 2,052
  • 1
  • 13
  • 29
1

My issue was--I did:

git checkout arbitrary_commit
git push origin master --force

which was not the right thing to do. Instead I had to:

git reset HEAD~3
git push origin master --force

Note: the number 3 is just an example. You should put your own number.

tash
  • 711
  • 5
  • 13