Merging git fork changes with unrelated histories

If you’ve rewritten history of a Git repo, but someone has forked your repo before you rewrote history, they will be unable to merge (and definitely DO NOT force the merge!) because of the unrelated history. This method corrects their history in their forked branches to match yours.

In this synthetic example:

  • my Git repo: https://github.com/scivision/coolprog main branch develop
  • forked Git repo:https://github.com/jane/coolprog.
  • Your colleague Jane, Github username jane has made a branch from develop named feature1. But scivision changed history of develop after fork.

The “easy” way is what I do, since I don’t risk screwing up months/years of work as I do with the “Pure Git” way

Easy way

If you first tried the “Pure Git” way, don’t use that directory. git clone the forked repo again.

Clone forked repo into a temporary directory e.g. /tmp or c:\temp

cd /tmp
git clone https://github.com/jane/coolprog

cd coolprog
git checkout feature1

Make a branch jane-feature1 in your original repo to copy the forked changes into

cd ~/code/coolprog

git checkout -b jane-feature1

Use meld to manually merge the changes jane made in her feature1 branch

meld . /tmp/coolprog

Merge the files that meld GUI shows manually. Note that your repo will likely have a lot of files that aren’t in the fork due to .gitignore.

For any new files that need to be tracked by Git: git add filename

When satisfied that you manually merged the changes, to give proper credit to jane, commit the changes in your jane-feature1 with

GIT_COMMITTER_NAME="Jane" GIT_COMMITTER_EMAIL="jane@users.noreply.github.com" git commit --author="Jane <jane@users.noreply.github.com>"

Note that we didn’t put Jane’s real-life email in to avoid giving spammers her email address. You can verify this worked with git log.

Upload changes to your Git repo

git push -u origin jane-feature1

Merge changes into main branch

If you want to make these new features part of develop branch:

In your repo

git checkout develop

git merge jane-feature1

git push

Jane make a new fork of your repo, deleting her old fork with all the incorrect history, else you’ll have to do this all over again for her future changes.

Reforking current repo

Have Jane refork from your Github repo with the corrected history, as this will clean up the big mess of “unrelated changes”.

To do this, assuming Jane hasn’t made any further changes, she would

  1. delete the coolprog directory on her computer
  2. “delete repository” at the bottom of https://github.com/jane/coolprog/settings
  3. Fork original repo again https://github.com/scivision/coolprog#fork-destination-box

Conclusion

This procedure is not normally necessary, it’s only for the case where Git history has been rewritten before Jane forked my repo.

Pure Git

This way requires Jane to force push, and Jane has to execute these commands (or give you write access to her forked repo). This is risky, so I use the “Easy” way instead.

Clone forked repo into a temporary directory e.g. /tmp or c:\temp

cd /tmp
git clone https://github.com/jane/coolprog

cd coolprog
git checkout develop

Add original repo as upstream of fork (in the the same directory as step 1)

git remote add upstream https://github.com/scivision/coolprog
git fetch upstream

git rebase upstream/develop

git checkout feature1
git rebase develop

If these changes worked, and you’ve confirmed the git history is OK, you can git push -f. Be sure you have secure, independent copies of the Github repo, as force-pushing can totally wreck the Git history! Don’t destroy months/years of work!

Sometimes for Git repos with a long, complicated history this doesn’t work, and would be time consuming to fix. In that case, let’s try the “easy” way.