问题
I cleaned the Git repository (Bitbucket cloud) with bfg, but the last commit remained uncleaned (as written in the bfg documentation: By default the BFG doesn't modify the contents of your latest commit on your master (or 'HEAD') branch, even though it will clean all the commits before it.).
However, I didn’t see it and wanted to run git gc
in a Bitbucket.
For this I did "git reset --hard HEAD
" and rolled back to it then "git push --force
".
But repository size increased?!
Now I have this commit with the old history left in the repository, and bfg cannot clean it, what should I do?
How can I remove it, since it is no longer attached to the working tree?
回答1:
You can tell BFG to change the last commit too with the --no-blob-protection
flag. *(This is from the BFG-Repo-Cleander documentation).
Alternatively, you can create a new commit that removes the bad file and then run BFG normally.
回答2:
I wrote in bitbucket support, they ran the script "git gc" on server and the old story was cleaned
回答3:
Try again, this time using newren/git-filter-repo, which will replace BFG and git filter-branch
As mentioned in its documentation:
[there is] an extra steps to delete the other tags and do another gc are still required to clean out the old objects and avoid mixing new and old history before pushing somewhere
git filter-repo
does avoid confusing users (and prevent accidental re-pushing of old stuff) due to mixing old repo and rewritten repo together.
Note: on the server side (ie, where you are pushing to), a git gc needs to be run, which is done regularly but not immediately.
That is the case for GitHub, as well as BitBucket.
See Atlassian documentation "How to perform a manual garbage collection on a repository"
Bitbucket implements its own garbage collection logic without relying on
git gc
anymore (this is achieved by setting the [gc] auto = 0 on all repositories).
When a fork is created, the pruneexpire=never is added to the git configuration and this is removed when the last fork is deleted.
As mentioned here:
BitBucket will run
git gc
themselves in response to doinggit reset --hard HEAD~1
(which discards last commit) followed bygit push -f
.
So in your case:
git commit --allow-empty -m "empty commit"
git push
git reflog expire --expire-unreachable="30m" --all
git prune --expire="30m" -v
git gc --prune="30m"
git reset --hard HEAD~1
git push -f
And a git gc
should be done on BitBucket side!
来源:https://stackoverflow.com/questions/58570649/how-clean-git-repository-with-commit-which-not-in-work-tree