Another developer pushed his changes to the remote repository and when I want to push I get the following error:
error: failed to push some refs to 'xxx@yyy'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
How can I upload my changes?
Summary (assuming you're in
master
):If you don't mind creating a merge commit, then this is enough:
If you prefer to avoid the merge commit:
Explanation
In git , a commit is the state of the entire repository at a given time. Also, every developer has a copy of everything and (if they use something like github ) there is a central repository. In this scenario, all developers make
git pull
ygit push
to the central repository and that is the only remote one. So let's imagine that initially the state of your remote repository is:and that you did
git pull
without problems. Your local repository has exactly the same content as the remote repository.You are working happily, but Martín (another developer on the team) does
git push
... so the status of the remote repository becomes this:you finish working on the bug you are fixing and do
git commit
... at that moment, in your local repository you have the following:so far, all perfect... but when you do
git push
, it fails with the error message of the question. This happens because git doesn't know what to do with commit 4... it's supposed to come after commit 2, but in the remote repository, it's 3 after 2.the common version
One option is to do:
What this does is bring the changes from the remote repository to your computer and try to do a merge. If there are no conflicts, the final status on your team is as follows:
the next step is to upload your changes to the remote by doing:
and if annoying Martin didn't upload another change, then it'll work fine. If it fails for the same reason, simply repeat the procedure.
The version of the anti-merge squad
There are several of us who dislike having many merge commits. Why? because they do not add information. Luckily, for crazy people like me, there is a way to do almost the same thing but more neatly.
First we run:
git fetch
fetch the changes from the remote but without touching the branches ... once you dogit fetch
, this is what is left in your repository:this means that:
master
(the branch you normally work on) still points to your commitorigin/master
) points to commit 3so... the magic step is:
when you write that, git stops at
origin/master
(commit 3) and repeats the changes that were made within commit 4. If there are no conflicts the output is as follows:it is important to note that there is no longer commit 4... we have a commit 5 that is "almost almost" like 4, but different (because it points to commit 3, it has another parent... and that is enough for it to be another ).
if there are conflicts, you are going to have to correct them (the console tells you which files are the ones to fix), add them (using
git add
) and finally continue with the rebase (usinggit rebase --continue
).Finally, it is necessary to upload the changes to the remote (that was what you wanted to do from the first moment, right?). For that:
And ready!
Conflicts exist and will always exist (regardless of whether you do a merge commit or not). Personally, I prefer to avoid merge commits at all costs.
And I'll leave you with one last image so you can see why it might be nice to avoid merge commits... without merge commits, the branch structure becomes much clearer:
The graphics were made with draw.io and are available here