No, you cannot.
The hash of each commit includes not just the hashed contents of all the files in the index, but also the hashes of the commit's parents.
"Corrected B" would have a different parent than it has now. That would change the hash.
It is possible to fix this, but it is not possible to avoid force-pushing the fix, and have everyone force-pull it, once that's done.
The only real way to fix this would be the following process:
git checkout A
Check out the parent commit, before the branch forked. Then, create two work branches:
git checkout -b corrected-mainline
git checkout -b corrected-fork
You're now on the corrected-fork branch. Now, on this branch, you should be able to git cherry-pick
all the commits up to the F
commit, skipping the commit with the huge files, and its revert. If any of these commits are a merge, do the same merge.
Now, do the same on the corrected-mainline
branch
git checkout corrected-mainline
Now, git cherry-pick
all the commits on the mainline branch, up to the last commit before the G
merge. Then, do a merge with the corrected-fork
branch. This is now your corrected G
merge commit.
Finish cherry-picking any commits that were originally on top of G
in your diagram, finishing with the last commit on your original branch.
At this point, the contents of your work branch should be the same as the contents of your original branch. Verify that this is so.
Then, delete your original branch, the rename your work branch to its name. Or, use git reset --hard
to reset your original branch to your corrected work branch.
Then do a git push --force
, to push your corrected branch up. Of course, anyone that pulls the branch will end up getting a force-pull.