1

I'm contributing to a project on GitHub.

I did the following:

  1. forked the repo
  2. clone the forked repo
  3. created a local branch in my local repo
  4. fixed a bug in the local branch
  5. pushed the changes to my forked repo
  6. made a pull request from that new branch

After many days, I got some comments and I have to make some more changes.

But their code has changed a lot since then. If I have to make a pull request again, I must update my new branch with their updated code and merge my changes.

How do I do this?

EDIT:

Before any of this my git log looked like this:

commit A "feature done" (latest, what I wanted to push)

commit B "feature still acting weird"

I exactly did as VonC suggested (except that I was in my feature branch when I fetched).

My rebase had conflicts. When I tried resolving them I was surprised to find that it was rebasing commit B and not A over the upstream master. I've checked this many times: git log shows exactly what I showed.

Why is it rebasing a previous commit of mine over the upstream master?

EDIT: I fixed the above issue by squashing my 2 commits A and B into one. Don't know why it happened though...

Community
  • 1
  • 1
batman
  • 5,022
  • 11
  • 52
  • 82

1 Answers1

2

You need to:

  • add the original repo as a new remote:

    git remote add upstream https://github.com/user/repo
    
  • fetch from "upstream"

    git fetch upstream
    
  • rebase your brach on top of upstream/master

    git checkout yourBranch
    git rebase upstream/master
    
  • force a push to your fork: that will update your pull request automatically:

    git push --force origin yourBranch
    
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • what happens if I make a pull request on the main reposotory (sic) if it is way ahead of my forked one? This would happen if I attended to the bug after many months in which time the main code would have gone ahead and possibly made conflicting changes. – batman Dec 24 '13 at 14:38
  • @learner that is what the `git fetch` + `git rebase` is for: the fetch will bring the latest of the main repo, and the rebase will replay tour work on top of that most up-to-date main repo commit. Your pull request will done with the most recent version of that main repo. – VonC Dec 24 '13 at 16:29
  • I understand, but what if I didn't do that? Would it become a *dirty* pull request? – batman Dec 24 '13 at 16:30
  • @learner you can rebase your "dirty" pull request on top of upstream/master in an interactive way: `git rebase --interactive`. That way, you can edit/drop/squash any commit you want, in order to get the clean history you want the upstream repo to see. The main point is: whatever you will push back to your branch in your fork will update your pull request automatically. – VonC Dec 24 '13 at 16:33
  • okay, but GitHub shows you a diff when you do a pull request right? How will that diff look if the changes are conflicting like in the case I mentioned? I mean, how will GitHub tell us it is a bad request? If I simply push to my forked repo without rebasing it should still update the pull request like you said. But will that not be a failed pull request? What will such a pull request look like in GitHub? – batman Dec 24 '13 at 17:36
  • @learner the symptom of a bad pull request is that it doesn't apply in a fast-forward manner, without any conflicts. It isn't a question of diff, but of applying your commits on top of the most up-to-date upstream repo commits. – VonC Dec 24 '13 at 18:02
  • Ok, I'm particular about diff, because that is how reviewers will review my code at the first few stages. They shouldn't see unrelated changes introduced by later commits which I didn't pull, right? – batman Dec 24 '13 at 18:16
  • @learner Exactly: that is what the rebase is for: replay your commits on top of the most recent version of upstream repo. The resulting diff will show only your work. – VonC Dec 24 '13 at 19:03
  • @learner Well, if the rebase seems too complex/strange, you can rename your current branch, make your branch on top of upstream/master, and cherry-pick your commits (from your renamed branch), one by one. That way, you will control the order of commits to apply. – VonC Dec 24 '13 at 20:33