开发者

What does "Git push non-fast-forward updates were rejected" mean?

开发者 https://www.devze.com 2023-02-04 10:07 出处:网络
I\'m using Git to manage my two computers and my development. I\'m trying to commit changes to GitHub, and I got this error:

I'm using Git to manage my two computers and my development. I'm trying to commit changes to GitHub, and I got this error:

Failed to push some refs to <repo>. To prevent you from losing history, non-fast-forward updates were rejected. Merge remote changes before pushing again.

What could be causing t开发者_StackOverflow中文版his, and how can I fix this?

EDIT:

Pulling the repo returns the following:

*branch master->master (non-fast-forward) Already-up-to-date

Pushing still gives me the aforementioned error.


GitHub has a nice section called "Dealing with “non-fast-forward” errors"

This error can be a bit overwhelming at first, do not fear.
Simply put, git cannot make the change on the remote without losing commits, so it refuses the push.
Usually this is caused by another user pushing to the same branch. You can remedy this by fetching and merging the remote branch, or using pull to perform both at once.

In other cases this error is a result of destructive changes made locally by using commands like git commit --amend or git rebase.
While you can override the remote by adding --force to the push command, you should only do so if you are absolutely certain this is what you want to do.
Force-pushes can cause issues for other users that have fetched the remote branch, and is considered bad practice. When in doubt, don’t force-push.


Git cannot make changes on the remote like a fast-forward merge, which a Visual Git Reference illustrates like:

What does "Git push non-fast-forward updates were rejected" mean?

This is not exactly your case, but helps to see what "fast-forward" is (where the HEAD of a branch is simply moved to a new more recent commit).


The "branch master->master (non-fast-forward) Already-up-to-date" is usually for local branches which don't track their remote counter-part.
See for instance this SO question "git pull says up-to-date but git push rejects non-fast forward".
Or the two branches are connected, but in disagreement with their respective history:
See "Never-ending GIT story - what am I doing wrong here?"

This means that your subversion branch and your remote git master branch do not agree on something.
Some change was pushed/committed to one that is not in the other.
Fire up gitk --all, and it should give you a clue as to what went wrong - look for "forks" in the history.


It means that there have been other commits pushed to the remote repository that differ from your commits. You can usually solve this with a

git pull

before you push

Ultimately, "fast-forward" means that the commits can be applied directly on top of the working tree without requiring a merge.


A fast-forward update is where the only changes one one side are after the most recent commit on the other side, so there doesn't need to be any merging. This is saying that you need to merge your changes before you can push.


you might want to use force with push operation in this case

git push origin master --force


Never do a git -f to do push as it can result in later disastrous consequences.

You just need to do a git pull of your local branch.

Ex:

git pull origin 'your_local_branch'

and then do a git push


This could also happen if your remote branch is updated and it's not synchronized with your local repo. so in my case, I created a git repo and added readme file. In my local machine, I created new files to upload in that repo, so I tried to push as I normally would do. After that, I did execute $git pull but it threw me fatal: refusing to merge unrelated histories error (comes as normal text in bash). I tried rebasing, re-staging, and re-committing but still, the issue was not solved. In this case, my goal was to merge it anyways since I wanted to keep both and I was not having any common file between them. So, I allowed unrelated history by passing parameter as follows:

$git pull origin main --allow-unrelated-histories

This command will merge - ignoring the fact that both were at different heads.

Then push it to the origin branch using: $git push -u origin main

If anyone is better at explaining this, feel free to edit this answer.


In my case for exact same error, I was also not the only developer.

So I went to commit & push my changes at same time, seen at bottom of the Commit dialog popup:

What does "Git push non-fast-forward updates were rejected" mean?

...but I made the huge mistake of forgetting to hit the Fetch button to see if I have latest, which I did not.

The commit successfully executed, however not the push, but instead gives the same mentioned error; ...even though other developers didn't alter same files as me, I cannot pull latest as same error is presented.

The GUI Solution

Most of the time I prefer sticking with Sourcetree's GUI (Graphical User Interface). This solution might not be ideal, however this is what got things going again for me without worrying that I may lose my changes or compromise more recent updates from other developers.

STEP 1

Right-click on the commit right before yours to undo your locally committed changes and select Reset current branch to this commit like so:

What does "Git push non-fast-forward updates were rejected" mean?

STEP 2

Once all the loading spinners disappear and Sourcetree is done loading the previous commit, at the top-left of window, click on Pull button...

What does "Git push non-fast-forward updates were rejected" mean?

...then a dialog popup will appear, and click the OK button at bottom-right:

What does "Git push non-fast-forward updates were rejected" mean?

STEP 3

After pulling latest, if you do not get any errors, skip to STEP 4 (next step below). Otherwise if you discover any merge conflicts at this point, like I did with my Web.config file:

What does "Git push non-fast-forward updates were rejected" mean?

...then click on the Stash button at the top, a dialog popup will appear and you will need to write a Descriptive-name-of-your-changes, then click the OK button:

What does "Git push non-fast-forward updates were rejected" mean?

...once Sourcetree is done stashing your altered file(s), repeat actions in STEP 2 (previous step above), and then your local files will have latest changes. Now your changes can be reapplied by opening your STASHES seen at bottom of Sourcetree left column, use the arrow to expand your stashes, then right-click to choose Apply Stash 'Descriptive-name-of-your-changes', and after select OK button in dialog popup that appears:

What does "Git push non-fast-forward updates were rejected" mean?

What does "Git push non-fast-forward updates were rejected" mean?

IF you have any Merge Conflict(s) right now, go to your preferred text-editor, like Visual Studio Code, and in the affected files select the Accept Incoming Change link, then save:

What does "Git push non-fast-forward updates were rejected" mean?

Then back to Sourcetree, click on the Commit button at top:

What does "Git push non-fast-forward updates were rejected" mean?

then right-click on the conflicted file(s), and under Resolve Conflicts select the Mark Resolved option:

What does "Git push non-fast-forward updates were rejected" mean?

STEP 4

Finally!!! We are now able to commit our file(s), also checkmark the Push changes immediately to origin option before clicking the Commit button:

What does "Git push non-fast-forward updates were rejected" mean?

P.S. while writing this, a commit was submitted by another developer right before I got to commit, so had to pretty much repeat steps.


Referring to my answer here... Git push failed, "Non-fast forward updates were rejected"


The safest way to solve this is using --rebase

E.g.

git pull <remote> <branch> --rebase

This may cause conflicts in your local branch, and you will need to fix them manually.

Once you resolve all the conflicts, you can push your change with --force-with-lease

E.g.

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

Using this flag, Git checks if the remote version of the branch is the same as the one you rebase, i.e. if someone pushed a new commit while you were rebasing, the push is rejected, and you will be forced to rebase your branch again.

It is annoying if you are working on a large project with hundreds of commits every hour, but it is still the best way to solve this problem.

AVOID USING --force unless you know exactly what you are doing.

Using --force is destructive because it unconditionally overwrites the remote repository with whatever you have locally.

But with --force-with-lease, ensure you don't overwrite other's work.

See more info on this post in Atlassian's developer blog.


You need to merge and resolve the conflicts locally before you push your changes to remote repo/fork.

1) pull (fetch and merge)

$ git pull remote branch 

2) Push the changes

$ git push remote branch 

Still you have a quick choice to push forcibly by using --force option but should be avoided as it may result in changes loss or affect badly on other contributors.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号