Merge 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:

  • original Git repo: github.com/username/coolprog main branch develop
  • forked Git repo: 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 can reduce the risk of screwing up months/years of work versus 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

cd ${TMPDIR}
git clone https://github.invalid/jane/coolprog

cd coolprog
git switch feature1

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

cd ~/code/coolprog

git switch -c jane-feature1

Manually merge the changes jane made in their feature1 branch using compare folders.

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 switch 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.invalid/jane/coolprog/settings
  3. Fork original repo again https://github.invalid/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 the 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 consider the “Easy” way instead.

Clone forked repo into a temporary directory:

cd ${TMPDIR}
git clone https://github.invalid/jane/coolprog

cd coolprog
git switch develop

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

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

git rebase upstream/develop

git switch 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. Force-pushing overwrites Git history i.e. erases 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.