Merge conflicts updating from upstream
Solution 1
It could be, that upstream has rewritten history (rebase, amend, …) – they shouldn't do that, but you'll never know.
Since you say you don't have any local changes or commits, you should bring your repository back to a clean state by resetting your branch:
git reset --hard upstream/allwinner-v3.0-android-v2
(This will discard any local changes and make commits of current HEAD unreachable!)
The above assumes that you will (force) push the newly reset state of your branch to your remote repository, otherwise you will encounter the conflicts again when you try to pull from origin
.
git push origin +allwinner-v3.0-android-v2
If you already had committed yourself locally, you'd have to rebase (or cherry-pick) your commits on top of the upstream branch, and then do a push to origin. That way you will re-write your local history the same way upstream did and apply your changes on top, i.e.:
git rebase --onto upstream/branch \
last-original-upstream-commit-before-yours \
your-branch
Solution 2
The show-branch
output means that upstream
and HEAD
have each added two commits since their common ancestor (assuming that's the full output). (See also: http://www.gitguys.com/topics/git-show-branch-to-see-branches-and-their-commits/) If you haven't committed anything yourself, that does mean that upstream pushed a rebase (or something else that changed the history). Since you haven't committed anything, knittl's answer is exactly what you want.
For what it's worth, I also love git log --oneline --graph --decorate --remotes --branches
for this. You'll get an ASCII graph with all your branches and remotes, so you can visualize what happened where.
David Given
Updated on June 09, 2022Comments
-
David Given almost 2 years
I'm trying to get started with git on a github project. (I've been using CVS, SVN and hg for years; git is hard to get my head around). I'm following the instructions as precisely as I can and simply cannot make it work.
I clone my forked project:
git clone [email protected]:davidgiven/linux-allwinner.git
As recommended, I add an 'upstream' remote that tracks the project that my one is forked from:
git remote add upstream https://github.com/amery/linux-allwinner.git
I fetch from it:
git fetch upstream
All this works fine. But, it's been a week or so since I forked the project, and upstream have been making changes. So I want to pull in those changes. I'm currently in the right branch --- allwinner-v3.0-android-v2 --- so I merge from upstream into my branch:
git merge upstream/allwinner-v3.0-android-v2
...and I get merge conflicts.
CONFLICT (add/add): Merge conflict in arch/arm/mach-sun5i/pm/standby/common.h CONFLICT (add/add): Merge conflict in arch/arm/mach-sun5i/pm/standby/Makefile CONFLICT (add/add): Merge conflict in arch/arm/mach-sun5i/pm/standby.S CONFLICT (add/add): Merge conflict in arch/arm/mach-sun5i/pm/Makefile [etc]
Now, I've checked in nothing; I haven't started work yet, and my project is completely untouched since I forked it. Therefore it should not be possible to have any conflicts. But there are some; what's going on, and how do I fix it?
Update:
git show-branch HEAD upstream/allwinner-v3.0-android-v2
shows this, which I have to say I don't understand a word of:! [HEAD] arm: sun3i: add getioaddr macro ! [upstream/allwinner-v3.0-android-v2] arm: sun3i: updated irq handling and machine_desc to 3.0 -- + [upstream/allwinner-v3.0-android-v2] arm: sun3i: updated irq handling and machine_desc to 3.0 + [upstream/allwinner-v3.0-android-v2^] arm: sunxi: renable early_printk in all _defconfig except crane's + [HEAD] arm: sun3i: add getioaddr macro + [HEAD^] arm: sun3i: add dummy machine type
-
David Given almost 12 yearsI've tried that. Unfortunately it doesn't help... now
git push
fails, telling me that I need togit pull
first; butgit pull
produces the same merge errors that I head before. This is actually what I'd expect; my understanding is thatgit reset
changes the current branch to the one specified, so I now simply have a copy ofupstream/allwinner-v3.0-android-v2
checked out locally asallwinner-v3.0-android-v2
. But since the conflicts are happening betweenorigin/...
andupstream/...
, the only thing that's changed is when the conflicts happen. -
knittl almost 12 years@DavidGiven: git push to where? It will fail, since your push is not fast-forward any more. You mention in your question that you have not committed anything, so maybe a single forced push is the way to go?
-
David Given almost 12 years
git push origin allwinner-v3.0-android-v2
. (Which, incidentally, does precisely the same thing as a baregit push
.) TBH, I want to know understand what's going on here; I don't have any commits yet, but I do want to start work on this pretty soon, so I need a general solution in case it happens again rather than a nuke-everything solution. -
knittl almost 12 yearsTry
git pull --rebase
(I think origin or upstream edited their history) -
David Given almost 12 yearsSo:
git reset --hard origin/allwinner-v3.0-android-v2
(to make sure my branch is clean); thengit pull --rebase upstream allwinner-v3.0-android-v2
; and... I get a very familiar set of merge conflicts. Aaargh! -
knittl almost 12 yearsorigin/all… and upstream/all… are different branches/commits. Merging/rebasing them is likely to produce conflicts – they are different lines of development. Fetch both remotes and visualize them with
gitk origin/allwinner-v3.0-android-v2...upstream/allwinner-v3.0-android-v2
. It's difficult to give a simple answer without knowing the exact history. -
David Given almost 12 yearsorigin should be a direct fork of upstream --- I forked the project, waited a week, and now I'm trying to pull changes from upstream. This is why I'm confused that I'm getting conflicts. There should be nothing to conflict. upstream's changes should be applying cleanly, because origin is a copy of upstream as it was before the changes got added. And, unfortunately, while I can run gitk and see... something... I simply don't understand what I'm looking at. I think I can see that upstream has moved on two checkins since origin, but it also seems to show a checkin below origin, which is odd.
-
knittl almost 12 yearsAs mentioned in the first paragraph of my answer (and the second answer to this question), it looks like
upstream
has rewritten history. You have to do a reset and then force-push the history rewrite to yourorigin
remote repo. Otherwise you keep dragging those discarded commits around (and they will continue to create merge conflicts) -
ellotheth almost 12 yearsThere's a whole section on recovering from an upstream rebase in the
rebase
docs, it might be helpful if you want a really thorough treatment: schacon.github.com/git/… -
David Given almost 12 yearsApparently history changes don't work the way I thought they did; you know, the sane way... so I finally gave in and did the reset/push, and now everything works. But I still need to know how to fix this properly; if upstream do this again while I have stuff committed, I'll be stuffed.
-
David Given almost 12 yearsAlso, if you add the
push -f
to your answer, I'll accept it. Thanks very much. -
Chris over 8 yearsI assume that the
+
in front of the branch name means aforced update
- at least it worked for me - maybe the-f
would have also worked..? -
knittl over 8 years@Chris: yes,
+branchname
translates to a forced push. Back then (in 2012)git push
did not support the-f
/--force
option, it was added later.