How do I properly force a Git push?
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?
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.
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
orrewrite
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.
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
use this following command:
git push -f origin master
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.
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.
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
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.
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
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
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.
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.
精彩评论