Merge git fork changes with unrelated histories
If the history of a Git repository has been rewritten, but someone has forked the repository before the history was rewritten, they will be unable to merge due to the unrelated history. This method corrects the history in their forked branches to match the original repository.
In this synthetic example:
- Original Git repository: github.com/username/coolprog main branch develop
- Forked Git repository: github.com/jane/coolprog
- A colleague, Jane, with GitHub username jane, has created a branch fromdevelopnamedfeature1. However,scivisionchanged the history ofdevelopafter the fork.
The “easy” way can reduce the risk of compromising months or years of work compared to the “Pure Git” way.
Easy way
If the “Pure Git” way was attempted first, avoid using that directory.
Instead, git clone the forked repository again.
Clone the forked repository into a temporary directory:
cd ${TMPDIR}
git clone https://github.invalid/jane/coolprog
cd coolprog
git switch feature1Create a branch jane-feature1 in the original repository to copy the forked changes:
cd ~/code/coolprog
git switch -c jane-feature1Manually merge the changes made in the feature1 branch using compare folders.
Note that the repository will likely have many files that are not in the fork due to .gitignore.
For any new files that need to be tracked by Git: git add filename
When satisfied with the manual merge, commit the changes in jane-feature1 to give proper credit to jane:
GIT_COMMITTER_NAME="Jane" GIT_COMMITTER_EMAIL="jane@users.noreply.github.com" git commit --author="Jane <jane@users.noreply.github.com>"Note that Jane’s real-life email is not used to avoid exposing it to spammers. Verify the commit with git log.
Upload the changes to the Git repository:
git push -u origin jane-feature1Merge changes into main branch
To incorporate these new features into the develop branch:
git switch develop
git merge jane-feature1
git pushJane should create a new fork of the repository, deleting the old fork with the incorrect history to avoid repeating this process for future changes.
Reforking current repository
Jane should refork from the original GitHub repository with the corrected history to clean up the “unrelated changes” issue.
To do this, assuming no further changes have been made:
- Delete the coolprogdirectory on the local machine.
- “Delete repository” at the bottom of https://github.invalid/jane/coolprog/settings.
- Fork the original repository again from https://github.invalid/scivision/coolprog#fork-destination-box.
This procedure is typically unnecessary and is only required when Git history has been rewritten before the fork.
Pure Git
This method requires Jane to force push and execute these commands (or grant write access to the forked repository). It is risky, so the “Easy” way is recommended.
Clone the forked repository into a temporary directory:
cd ${TMPDIR}
git clone https://github.invalid/jane/coolprog
cd coolprog
git switch developAdd the original repository as upstream of the fork:
git remote add upstream https://github.invalid/scivision/coolprog
git fetch upstream
git rebase upstream/develop
git switch feature1
git rebase developIf these changes are successful and the Git history is confirmed to be correct, a git push -f can be performed.
Ensure secure, independent copies of the GitHub repository are available, as force-pushing overwrites Git history and may erase 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.