Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to merge upstream without losing changes?

Tags:

git

github

I'm in a bit of a pickle.

I started development on a fork of a repo a few months ago. I made some changes. I was about to push my code back to the master as a pull request, but I realized there were quite a few changes in the meantime...

So, following the instructions at Github under "Pull in Upstream Changes" I tried:

$ git remote add upstream ...  # savon/httpi
$ git fetch upstream
$ git merge upstream/master
$ git push origin/master       # coldnebo/httpi

However, now my fork is rather messy. I'm still rather a novice with git, so instead of trying to guess what the terminology is I'll simply show you what I got and what I expected:

  • wanted this: (Showing 7 changed files with 112 additions and 5 deletions.) https://github.com/savonrb/httpi/pull/59/files

This is the diff I want. Is there any way to rebase/revert and do this without losing my changes?

  • got this: (324 commits covering nearly the entire project plus 4 new branches... OUCH!!) https://github.com/coldnebo/httpi/commits/master

what a mess.

maybe git pull would have been better?

It's not many changes, so if it's unrecoverable I can always manually diff and remaster it, but I'm looking for the "right way" to do this in the future.

like image 854
Larry Kyrala Avatar asked Jan 07 '13 15:01

Larry Kyrala


2 Answers

You should always create new branch for each Pull Request your create. Before you going to push it to github to create the request, you should rebase your branch to the latest upstream branch.

Github says you use git merge for this, I prefer to use git rebase upstream/master if there aren't much changes, this will prevent merge commits.


Sometimes the rebasing can't continue, because something what you have changed was already changed in the upstream branch. For instance, assume that you have a text.txtfile like:

Lorem ipsum

You create a PR to update this to Lorem ipsum! and the upstream branch already changed this to Hello World If you do a rebase, to make your code up to date before creating a request, you get a merge conflict. The file is updated with conflict markers and you can choose which version you want to use and you can even edit it, in our example we get this in text.txt:

<<<<<<< YOUR_PR_BRANCH
Lorem Ipsum
=======
Hello World
>>>>>>> THE_UPSTREAM_BRANCH

After this, add the updated files with git add and execute git rebase --continue.

like image 100
Wouter J Avatar answered Nov 08 '22 05:11

Wouter J


Ok, if your repo is fubar, then here's steps to recover:

$ git remote update     # make sure origin and upstream are up to date
$ git checkout master
$ git branch my_changes   # just to make sure my stuff isn't lost
$ git reset --hard upstream/master
$ git status
# On branch master
# Your branch is behind 'origin/master' by 8 commits, and can be fast-forwarded.
#

Ignore that fast-forward crap, it won't help you, just reset the master.

$ git push origin +master   # now, fork matches upstream/master

Now, how to recover the previous work so it's reviewable?

$ git diff --no-ext-diff --no-prefix master..my_changes > patchfile
$ patch -p0 < patchfile   # apply the patchfile to master
$ git diff     # to verify patch visually.
$ rm patchfile   # clean up
$ rake spec      # verify that it really works.
$ git add .
$ git status     # double triple verify
$ git commit .
$ git push origin master

That sucked. I tried doing rebase, but it kept saying "no changes" and didn't ask me to check anything in? I'm pretty sure I don't understand what's going on here, which is why I posted my struggle so someone can explain how I could have avoided this mess and gotten from A to B more elegantly now that it's fully documented. I'm willing to chalk this up to git inexperience, but I figure that pulling changes should be a really common thing in git -- I must be missing something.

like image 44
Larry Kyrala Avatar answered Nov 08 '22 04:11

Larry Kyrala