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.

  1. 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
    
  2. Make a branch jane-feature1 in your original repo to copy the forked changes into
    cd ~/code/coolprog
    git checkout -b jane-feature1
    
  3. Use meld to manually merge the changes jane made in her feature1 branch
    meld . /tmp/coolprog
    
  4. 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.
  5. For any new files that need to be tracked by Git: git add filename
  6. 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="[email protected]" git commit --author="Jane <[email protected]>"
    

    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.

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

  1. In your repo
    git checkout develop
       
    git merge jane-feature1
       
    git push
    
  2. 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.

  1. 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
    
  2. 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
    
  3. 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.

Tags:

Categories:

Updated:

Leave a Comment