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 fromdevelop
namedfeature1
. However,scivision
changed the history ofdevelop
after 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 feature1
Create a branch jane-feature1
in the original repository to copy the forked changes:
cd ~/code/coolprog
git switch -c jane-feature1
Manually 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-feature1
Merge changes into main branch
To incorporate these new features into the develop
branch:
git switch develop
git merge jane-feature1
git push
Jane 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
coolprog
directory 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 develop
Add 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 develop
If 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.