Search code examples
gitgithubgit-mergegit-merge-conflictbfg-repo-cleaner

Git cant create pull request | different commit histories | bfg --delete-files | git merge --allow-unrelated-histories


For the past year we've been working with a staging and master branches, testing our changes before merging to master.Now when trying to pull request from staging to master I'm facing an error message on GitHub saying "master and staging are entirely different commit histories."

This worked perfectly well until we needed some help from Fiverr developers and decided to mess with our history - deleting the history of an env.ts file that in the past had a mistaken commit with api keys and sensitive data.

So to cover this mistake, I decided to run bfg --delete-files /src/env.ts Which is supposed to delete the file from history, leaving just the latest version.

Well, it worked, the history of this file was deleted - so no more sensitive data there.

Fast forward a week - I want to merge some new change from staging to master and aparently the branch have lost sync. Github is showing me for staging that "This branch is 644 commits ahead of, 634 commits behind master." And when trying to create a pull request "master and staging are entirely different commit histories.".

I've seen this question with the answer from PaianuVlad23, suggesting to run "git merge staging --allow-unrelated-histories". But I would love to receive your help tailored to my unique case of deleting history.

Creating a new staging branch is out of the question currently, I really want to get this back in sync.

Executed : bfg --delete-files /src/env.ts This changed my history and apparently staging and master are no longer in sync.

Now I'm afraid of proceeding without proper consultation. I've also tried to find git experts on fiverr and upwork, but I couldn't really find anyone who dealt with similar cases.

Edit : checked my master branch on github, thats what I'm currently seeing master seems compltely cut off from all other branches history wise


Solution

  • The same commit id means both commits are the same and have the same histories. If you change or delete a commit, all following commits have to be rewritten with new ids.

    When you deleted those files you changed those commits. Git wrote new commits with new commit ids, and had to also rewrite all the following commits.

    But any tags and branches will remain pointing at the old history. It's likely master is pointing at the new history, and staging is pointing at the old history.

    a - b - c - d - e [staging]
         \
          c1 - d1 - e1 - f - g [master]
    

    (Note: Github and git log both lie and show a linear history. A tool such as GitKraken or git log --graph --decorate will show the true history.)

    In the example above, c got rewritten which means d and e also got rewritten. master points at the new history, staging at the old history. There's also a couple new commits to master (f and g) just to make the example interesting.

    If there have been no commits to staging, simplest thing would be to delete staging and recreate it so it points at commit g (master)

    $ git branch -f staging master
    a - b - c - d - e
         \
          c1 - d1 - e1 - f - g [master]
                               [staging]
    

    If there have been commits to staging, let's say h - i, you can rebase staging on master. If you just rebase, it might resurrect the deleted file in b. So you have to tell it to only rebase part of staging. Probably just the new part.

    In the example below, we want to move h and i ontop of master. So we'll tell Git to rebase from e (but not including e) to staging (which is i).

    a - b - c - d - e - h - i [staging]
         \
          c1 - d1 - e1 - f - g [master]
    
    $ git switch staging
    $ git rebase --onto master e staging
    a - b - c - d - e - h - i
         \
          c1 - d1 - e1 - f - g [master]
                              \
                               h1 - i1 [staging]
    

    The unreferenced commits will be garbage collected.

    You may have to also recreate your tags on the new history.