Different SHAs for same commit after filter-branch, when I merge to dev or master wouldn't it fail? How can I prevent this?

Viewed 258

I accidentally added a large file to a git repo on a specific branch and had to change the commit history for the branch to remove the file with:

git filter-branch -f --index-filter "git rm -rf --cached --ignore-unmatch path_to_file" HEAD

Now I see different SHAs for the commits on the branch I ran the command, which I am fine with, as the repo is fairly new and only I use it currently. But, when I checked the master branch and the other dev branch, I see the SHAs for the same commit are different. When I do a merge to dev or master (which I didn't do yet) wouldn't it fail? How can I rectify this issue?

The series of git commands that were executed:

git checkout -b move_branch master

add files from location1 commit
add files from location2 commit
add files from location3 commit
merge the master branch of an older repo which was added as a remote   introducing some files including the big file commit 

git filter-branch -f --index-filter "git rm -rf --cached --ignore-unmatch path_to_file" HEAD

add files from location5 commit
add files from location6 commit


A--B--C                             master
        \
X--Y--Z--A--B--C--D--E              move_branch (Z is the commit with  big file)

X--Y--I--J--K--L--M--N              move_branch (after filter-branch)
1 Answers

Merging your branch into master will not fail. It will also not get rid of the large file. You will actually need to run this command on the master branch and force-push this change. Since this rewrites the history of your repository, you will need to communicate and plan this with your team first. This is a destructive action.

If you alone are working on this repository:

This is the easy case. Just do a hard reset on master to the new commits.

git checkout -b fix_commits master
git filter-branch -f --index-filter "git rm -rf --cached --ignore-unmatch path_to_file" HEAD
git checkout master
git reset --hard fix_commits

# Push master if you need to
git push origin HEAD --force

If multiple people work on this repo

Your best course of action is:

  1. Create a new branch from the current master branch, and push it.

    git checkout -b master_before_file_purge
    git push origin -u HEAD
    
  2. Create a new branch to purge the large file, and rewrite its history. Push this branch.

    git checkout -b purge_large_files master
    git filter-branch -f --index-filter "git rm -rf --cached --ignore-unmatch path_to_file" HEAD
    git push origin -u HEAD
    
  3. Work with each teammate individually to rebase their private trees onto purge_large_files

  4. Work with the team to rebase shared branches that are based on master onto purge_large_files (you will likely need to git push origin HEAD --force on those branches)

  5. Do a hard reset on master to purge_large_files:

    git checkout master
    git reset --hard purge_large_files
    git push origin HEAD --force
    
  6. Work with teammates to make sure they can pull master without any troubles.

  7. When time has gone by, delete the "before" branch:

    git checkout master_before_file_purge
    git push origin --delete master_before_file_purge
    

You and your teammates will need to run git gc locally to purge those orphaned commit objects after they pull from origin again.

Related