• 请不要在回答技术问题时复制粘贴 AI 生成的内容
bonfy
V2EX  ›  程序员

Git 问题求教 - git rm 大文件但是.git 文件夹还是很大,怎么处理

  •  
  •   bonfy · Dec 1, 2016 · 7380 views
    This topic created in 3625 days ago, the information mentioned may be changed or developed.
    git 的时候不小心把 test 的内容都 commit 进去了

    (我明明已经加.gitignore 了,还是会 add 进去。。。当然这个我先不纠结了)

    现在的问题是已经 rm 了,但是.git 里面还是有 pack 文件很大,怎么搞呢,明明就是几 kb 的事,现在 clone 下来就是几 MB,99%都是.git 里面的 pack 文件

    老司机有遇到这个问题的么? 除了重新建 Repo 还有其他法子不?
    24 replies  •  2016-12-02 05:57:56 +08:00
    fds
    fds
    Dec 1, 2016
    1
    你怎么 rm 的?把 commit 从历史版本里删掉了么?没有的话用 git reset --hard 回到以前,然后 git push --force 强制覆盖。
    lrh3321
    lrh3321
    Dec 1, 2016
    2
    都已经被提交过了就无解了
    除非你先 checkout 到 commit 之前
    然后, 把最新分支的内容覆盖一次
    接着,重新提交
    再 -f 推送到服务器
    song4
    song4
    Dec 1, 2016
    3
    一旦文件添加进去,就一直在里面了,直接 rm 是没办法把这个文件从历史提交里面移除的。

    你需要的是把文件从整个历史里面抹掉:

    git filter-branch --index-filter \
    'git rm --cached --ignore-unmatch path/to/your/file' \
    --tag-name-filter cat -- --all
    bonfy
    bonfy
    OP
    Dec 1, 2016
    4
    @fds 没把 commit 删掉。。。 我试试 git reset...
    bonfy
    bonfy
    OP
    Dec 1, 2016
    5
    @lrh3321 已经提交了。。。。
    bonfy
    bonfy
    OP
    Dec 1, 2016
    6
    @song4 我试试。。。
    Citrus
    Citrus
    Dec 1, 2016❤️2
    7
    先说方法,你需要这个简单的小工具:
    https://rtyley.github.io/bfg-repo-cleaner/

    然后说原理:
    因为 Git 会记录你 所有 的历史提交,所以为了回滚需要,只要是在 Git 中存在过一次的文件,就会被永久记录下来,不论当前是否存在。
    bonfy
    bonfy
    OP
    Dec 1, 2016
    8
    @Citrus  这个牛,都已经上升到工具了。。。 Star 好多,看来和我同样问题的 git 新手好多
    TangMonk
    TangMonk
    Dec 1, 2016
    9
    git rm --cached test
    fan123199
    fan123199
    Dec 1, 2016
    11
    @song4 git filter-branch --index-filter \
    'git rm --cached --ignore-unmatch path/to/your/file' \
    --tag-name-filter cat -- --all

    这个方法学习了,但是不知道对其他成员有没有影响(比如他 pull 或 push 时出错。)。 git 官方说, 修改 public repo 的已有 commit , 会有大影响。
    song4
    song4
    Dec 1, 2016
    12
    @fan123199 如果调用了这个方法,在向远端 push 的时候,必须强制覆盖:

    git push origin --force --all


    所以这是一个危险操作,务必再三确认啊!
    fan123199
    fan123199
    Dec 1, 2016
    13
    @bonfy 这不是新手问题,如果你的 test 变动还在 HEAD ,那么很简单,按 1L 办,如果又加了新 commit ,那就难办了,所以要认真对待每个 commit ,特别是 push 的时候。
    song4
    song4
    Dec 1, 2016
    14
    另外,分享一篇文章, Github 官方帮助告诉你怎样从仓库里彻底移除敏感信息: https://help.github.com/articles/remove-sensitive-data/
    fan123199
    fan123199
    Dec 1, 2016
    15
    @song4 这个时候,是不是跟 filter 有关的 commit 的 hash 值都会变成新的。如果是的话,感觉是重做了整个 branch 的感觉。这个在公有 repo 还是太危险,行不通。 最好只在本地完成。
    song4
    song4
    Dec 1, 2016
    16
    @fan123199 确实是你说的这样。

    建议尽量不要用这个极端的方法,除非在某些极端的情况下(比如不小心把密钥提交到了版本库里)。
    laiqs2011
    laiqs2011
    Dec 1, 2016
    17
    git gc 试试?
    bonfy
    bonfy
    OP
    Dec 1, 2016
    18
    @chousb 这个好像就是 @song4 提的那个。 不过有小弟还是令人羡慕啊:)
    shibingsw
    shibingsw
    Dec 1, 2016
    19
    @song4 这个正解
    msg7086
    msg7086
    Dec 1, 2016
    20
    @fan123199 文件就在历史里,你要么改变历史,要么接受历史。
    删除文件的话,当然所有 Hash 都要变的。
    fivesmallq
    fivesmallq
    Dec 1, 2016
    21
    之前遇到过 ,可以参考下 http://nll.im/post/clean-up-git-repo.html
    bonfy
    bonfy
    OP
    Dec 1, 2016
    22
    谢谢各位,我最后还是 git reset , git push --force 重新提交解决的

    核弹级选项: filter-branch 估计也是正解,但是看着就吓人,没勇气尝试。。。
    Sunnyyoung
    Sunnyyoung
    Dec 1, 2016
    23
    ## 命令

    `git filter-branch --tree-filter 'rm -rf test/' --tag-name-filter cat HEAD --all`

    ## 说明

    `--all` : 所有分支
    `--tree-filter`: 需要执行的命令
    `--tag-name-filter cat` : Tag 也做修改
    DravenJohnson
    DravenJohnson
    Dec 2, 2016
    24
    需要 Clean 历史 Commit ,后晌几个说的都可以
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4418 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 249ms · UTC 05:46 · PVG 13:46 · LAX 21:46 · JFK 00:46
    ♥ Do have faith in what you're doing.