How clean git repository with commit which not in work tree

冷暖自知 提交于 2019-12-23 03:28:14

问题


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 doing git reset --hard HEAD~1 (which discards last commit) followed by git 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!