102

Let's say there is a GitHub repository which I want to contribute to. I fork that repository into my GitHub account and I clone the fork from my account in my PC. Fine.

Before working on an issue, I first want to synchronize my fork with the 'original' repository. I go to my account fork, click on New Pull request, make sure that I select mine as base and the original master as head fork, I see the differences (all the commits that people did in the original repository that are not on mine). Then I create the pull request on my fork and I merge those changes in my fork. I go to my local repo and do a git pull, and I have everything synchronized. Fine.

The problem comes now, in my GitHub account now it's always saying 'This branch is X commits ahead', where 'X' is the number of times that I did the synchronize process I described above. So, every time I do a pull request into the original repository (not my fork), is showing that I'm committing my code plus X more commits, that are the merges I did on my fork to synchronize with the original repository.

Of course, I don't want to push those changes into the original repository, since they already have those changes in place, so I don't understand why GitHub keeps saying to me that I have changes to commit.

I think it's something that has to be solved on my GitHub account, because in my local repository there are no changes or issues, actually I even removed it and re-cloned again.

Do you have any ideas?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Fernando Garcia
  • 1,946
  • 2
  • 12
  • 14
  • To understand where the *ahead/behind* numbers come from and how to reproduce them locally in git, see [github - git ahead/behind info between master and branch? - Stack Overflow](https://stackoverflow.com/questions/20433867/git-ahead-behind-info-between-master-and-branch) – nealmcb Jul 28 '20 at 21:38

3 Answers3

162

As you guessed, these extra commits are likely the merge commits from the Pull Requests that you created.

In the future, there's a much easier way to sync your fork with the original repository. In your local repo, after the initial clone do:

git remote add upstream https://github.com/upstream/repo.git

Then, whenever you want to sync the changes from upstream, do:

git pull --rebase upstream master
git push --force-with-lease origin master

(The --rebase and --force-with-lease options will only be necessary if you have commits that haven't been merged into the upstream repo.)

Obligatory warning: Since a rebase rewrites history, this can be dangerous / disruptive for anyone else working on this branch. Be sure you clearly communicate what you have done with anyone you are collaborating with. Since this is a personal fork, I assume this won't be an issue for you.


Now to fix your current issue after the fact.

  1. Add the upstream remote as described above.
  2. Reset your local branch to match upstream:

    git checkout master
    git reset --hard upstream/master
    
  3. If you have created any commits in your fork, you can cherry-pick them onto your updated version of master. If you can't remember or need help finding them, something like

    git log --oneline master origin/master
    

    should show you any commits not in upstream.


Above I assumed that you are only using one branch, master. If you aren't already, I highly recommend that you create a new branch for each feature / bug fix that you work on. Among other benefits, this allows you to start work on another feature / bug fix when you are still waiting for an earlier PR to be merged. If you never commit directly to master, then you can sync without the --rebase or --force-with-lease:

git checkout master
git pull upstream master
git push origin master

To update a feature branch after you have updated master, do:

git checkout myfeature
git rebase master
git push --force-with-lease origin myfeature # if you have already pushed
Muhammad Altabba
  • 2,583
  • 19
  • 31
Scott Weldon
  • 9,673
  • 6
  • 48
  • 67
  • 5
    Wow, that was exactly what I needed. Specially this last line you mentioned: `git push --force-with-lease origin master # if you have already pushed` Saved me. Thanks! – Fernando Garcia Dec 22 '16 at 20:16
  • 4
    best anwer. the third half was what i was looking for to make the changes reflect in other branches – Ishan Srivastava Dec 30 '17 at 17:54
  • I'm having this problem and my repo and i tried the steps above but they do not help. it seems like my code is updated but it thinks it's behind for some reason https://github.com/OpenPCM/openpcm-server – GSUgambit Mar 10 '18 at 19:13
  • @GSUgambit Are you still having this problem? If so, you may want to [ask a new question](https://stackoverflow.com/questions/ask), adding more details about your specific situation. (Feel free to post a link to it here so that I will see it.) – Scott Weldon Aug 02 '18 at 04:12
  • 3
    Why does this "much easier way to sync" require so many steps, including pulling stuff to and from local repo? – user7860670 May 22 '19 at 10:03
  • @VTT: So many steps? It's only two steps per branch after initial setup (aside from `checkout`s to switch branches). And pulling to/from the local repo as opposed to what? Git is a **Distributed** Version Control System (DVCS), so most interaction is with the local repo, with services like GitHub providing merely hosting and the occasional GUI shortcut. – Scott Weldon May 22 '19 at 16:54
  • If you use BitBucket instead of Github then while creating fork it give you check box for sync fork. This is out of box functionality provided where all forked branches are keep updated by bit-bucket from original repository. No need to update fork branches by our own. Just use local branch approach and do not mess up with fork branches. – RoshanKumar Mutha May 22 '18 at 11:48
  • To be clear (because there are a million ways to do it wrong), step "1. Add the upstream remote as described above." is `git remote add upstream https://github.com/upstream/repo.git` AND `git pull --rebase upstream master` (where, hopefully merge commits automagically disappear). Then step "3. If you have created any commits in your fork, you can `cherry-pick`" is `git cherry-pick ` where you can get the hash from the `git log` command (which will still show your old commits, up until you `push`). – Heath Raftery Jan 29 '23 at 03:50
  • `git remote add upstream https://github.com/upstream/repo.git` does not seem to work as no branches are found? No I didn't type it as shown but used the correct url from the original site. What could be causing this? I'd rather get this sorted than having to delete my forked repo and start again! – mcdixon Apr 23 '23 at 12:16
2

Before working on an issue, I first want to synchronize my fork with the 'original' repository. I go to my account fork, click on New Pull request [...]

If you want to update/syncronize github forks, you should not use a Pull Request.

Pull Requests introduce merge commits, which are the source of your error message. (Pull Requests are not fast-forward by default). The merge commits exist in your fork, but not in the source repo.

You don't want to merge their branch with your branch... you want to update your branch to point to the same commit as their branch. You want the branches between forks to be the same.

You can do this in various ways, best explained in other answers:

pkamb
  • 33,281
  • 23
  • 160
  • 191
1

I have the same problem with you and just solved this problem.

To solve this:

  1. 'Reset' your local repo to the moment before the abundant commits

  2. Create a new branch using this amended local repo

  3. 'Publish' this amended local repo to your github repo

  4. Make the changes that you want to PR to github in the amended local repo

  5. 'Commit' this local repo

  6. 'Pull' the commit to your github repo

  7. On your github repo new branch, submit pull request to the upstream repo

Hope this answer could help.

pkamb
  • 33,281
  • 23
  • 160
  • 191
Adam
  • 11
  • 2