Remove a directory permanently from git

后端 未结 6 1026
广开言路
广开言路 2020-11-30 20:44

In my personal git repo, I have a directory that contains thousands of small images that are no longer needed. Is there a way to delete them from the entire git history? I h

相关标签:
6条回答
  • 2020-11-30 21:19

    The ProGit book has an interesting section on Removing Object.

    It does end with this:

    Your history no longer contains a reference to that file.
    However, your reflog and a new set of refs that Git added when you did the filter-branch under .git/refs/original still do, so you have to remove them and then repack the database. You need to get rid of anything that has a pointer to those old commits before you repack:

    $ rm -Rf .git/refs/original
    $ rm -Rf .git/logs/
    $ git gc
    $ git prune --expire 
    

    (git prune --expire is not mandatory but can remove the directory content from the loose objects)
    Backup everything before doing those commands, just in case ;)

    0 讨论(0)
  • 2020-11-30 21:23

    Actually none of these techniques workedfor me. I found the most reliable was was to simply pull locally into another repo:

    git pull file://$(pwd)/myGitRepo
    

    It also saves you the hassle of deletig old tags.

    see the story on my blog: http://stubbisms.wordpress.com/2009/07/10/git-script-to-show-largest-pack-objects-and-trim-your-waist-line/

    0 讨论(0)
  • 2020-11-30 21:24

    Brandon Thomson asked in a comment to Rainer Blome's solution if this just fixed the gitk view or if the refs will be really gone. A good way to check this is to remember one of the sha1 hashes (or a unique prefix of it) of the old commits and try

    $ git ls-tree hash-value
    

    This should show you the content of the repos main folder as it was in this commit. After

    $ rm -Rf .git/refs/original
    $ rm -Rf .git/logs/
    

    as shown by VonC and removing the refs/original/… lines from .git/info/refs and .git/packed-refs as shown by Rainer Blome, a final

    $ git gc --prune=now
    

    made not only the refs, but also the old objects (commits, trees, and blobs) go away. The above shown git ls-tree hash-value proves this. Another nice command to check this is git count-objects -v (run it before the filter-brach and after the pruning and compare the size).

    Note: As I'm not allowed yet to comment on the other answers, I had to write a new one although it mainly combines previous given answers.

    0 讨论(0)
  • 2020-11-30 21:24

    If you want to go the manual cleanup route, there are some more files that may also contain a ref to the position of your original branch before the git-filter-branch. For example, I filtered my "home" branch:

    .git/info/refs:

    179ad3e725816234a7182476825862e28752746d refs/original/refs/heads/home

    .git/packed-refs:

    179ad3e725816234a7182476825862e28752746d refs/original/refs/heads/home

    After I removed those lines, gitk did not show the old commits any more.

    0 讨论(0)
  • 2020-11-30 21:25

    As this is an old question, perhaps some of this wasn't possible back then. This also assumes you're using bash or cygwin.

    Warning: The second and third lines will permanently delete all commits unreachable from your branches/tags.

    After running filter-branch, do

    for ref in $(git for-each-ref --format='%(refname)' refs/original); do git update-ref -d $ref; done
    git reflog expire --expire=now --all
    git gc --prune=now
    

    git for-each-ref --format='%(refname)' gets the reference names, and git update-ref -d deletes the reference. It is generally better not to modify the .git folder directly, and in particular this command handles the case when the refs are in packed-refs.

    The second and third lines are taken directly from How to clean up unused side-branches in your commit trees?.

    0 讨论(0)
  • 2020-11-30 21:26

    git-filter-branch by default saves old refs in refs/original/* namespace.

    You need to delete them, and then do git gc --prune=now

    0 讨论(0)
提交回复
热议问题