V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hentailolicon
V2EX  ›  酷工作

github 怎么把大文件 commit 记录删除

  •  
  •   hentailolicon · 251 天前 · 3280 次点击
    这是一个创建于 251 天前的主题,其中的信息可能已经有所发展或是发生改变。

    vscode debug 的时候忘记关的时候把 debug 文件 push 到 github 上了 然后删掉 push 后发现拉取的时候还是需要把这个历史大文件拉下来导致其他人 git pull 很慢 有什么好的办法处理掉吗

    27 条回复    2023-08-24 18:48:17 +08:00
    yuankui
        1
    yuankui  
       251 天前   ❤️ 1
    了解下下面几个命令
    git reset
    git push --force

    谨慎这种 push,除非迫不得已,不然你会被打
    des
        2
    des  
       251 天前
    试试 git filter-branch ,不过用了之后其他人都要删除仓库重新拉取
    zanx817
        3
    zanx817  
       251 天前 via iPhone
    楼上说的是,提前备份好分支再操作
    Leon406
        4
    Leon406  
       251 天前
    反正我感觉前面没有一个人 实际操作过

    发下个人的笔记
    https://gitee.com/LeonShih/notes/blob/master/other/gitlab%E5%88%A0%E9%99%A4%E5%A4%A7%E6%96%87%E4%BB%B6.md
    chenliang0571
        5
    chenliang0571  
       251 天前   ❤️ 1
    git-filter-repo
    des
        6
    des  
       251 天前
    @Leon406 很不幸,我还真用过,起因是同事把测试用的 mp4 文件提交上去了……
    Kisesy
        7
    Kisesy  
       251 天前
    不知道 git 有没有提交时超过某个大小的文件就提示的选项,意外提交真的很烦人
    Leon406
        8
    Leon406  
       251 天前
    @des #6 好吧,你除外
    xiangyuecn
        9
    xiangyuecn  
       251 天前
    论图形界面 和 乌漆嘛黑的命令行控制台,哪个更适合用于作为版本管理工具的 UI🐶

    commit 不检查文件变更就算了,push 也不检查就直接塞进去了?
    857681664
        10
    857681664  
       251 天前
    印象中需要回溯所有以存在大文件 commit 作为父 commit 的 commit ,然后把大文件的 blob 从 commit tree 里删掉,最后强制 push 才能解决
    jiefengwang
        12
    jiefengwang  
       251 天前
    @hentailolicon 可以试一下这个工具,清理之后,让所有人也重新拉一下项目就好了
    xubeiyan
        13
    xubeiyan  
       251 天前 via Android
    首先你要知道在 gayhub 上仓库的和你本地仓库的没有什么区别,push 时覆盖提交(--force )即可
    知道了这点之后那就落到了如何把这个文件从你的提交历史记录删掉了。这个是一个 cherry-pick 问题,使用 git 的命令行特别复杂,但对于一些 GUI 的就特别简单,例如 tortoisegit ,打开这个仓库的提交记录窗口,把包含了这个大文件到删除了这个大文件的提交都选上,选择压扁成一个提交。最后强制 push 到远程仓库即可。
    顺便吐槽一下楼上的几位,git 就学成这样还 reset ,算了吧(
    kinghly
        14
    kinghly  
       251 天前 via Android
    如果只是刚推的,就 reset 后重推;如果已经多了很多新 commit ,考虑 cherry pick 后把对应的分支干掉。
    SimonOne
        15
    SimonOne  
       251 天前
    @xubeiyan #13 是不是等于 git rebase 把删除大文件的提交 squash 到误加大文件的提交,再 git push --force ,然后让其他同事重新拉取。
    fzls
        16
    fzls  
       251 天前
    如果你已经推到远程,且你能确保让所有人都在你改动后重新拉取仓库,那你可以试试下面这个(用它重写 git 历史,然后强制推送,然后要求其他人重新拉取仓库)

    https://github.com/newren/git-filter-repo/
    yuankui
        17
    yuankui  
       250 天前
    @xubeiyan 你大姨妈来了吗? 我看了你的回复我想笑,我也懒得跟你解释 reset 为啥可以.你自己悟吧
    liuqitoday
        19
    liuqitoday  
       250 天前
    git filter-repo
    yalay
        20
    yalay  
       250 天前
    @yuankui 我是这么操作的,别人传二进制上去了
    xubeiyan
        21
    xubeiyan  
       250 天前
    @SimonOne 本质就是这样的,但 squash 还是 edit 需要你去做判断

    大概是从这个回答得到的答案 https://stackoverflow.com/questions/307828/how-do-you-fix-a-bad-merge-and-replay-your-good-commits-onto-a-fixed-merge#answer-23188613

    从中就可以看出 reset 并不是一个好办法,因为你需要 hard reset + rebase 。而上面的 reset 回答全部没有提到这点,说明他们连 hard reset 和 reset 区别是什么都搞不清楚,也不知到后面的 rebase 要经历怎样的苦难

    我的答案大概是 Solution 4 的简化版,其中使用了 Interactive Rebase

    首先,你需要从要移除的提交开始执行 interactive rebase
    `git rebase -i <要移除的前一个提交>~`
    当然也可以指定结束的提交,注意结束的那个提交不会被删除
    `git rebase -i <要移除的提交前一个提交开始> <要移除的提交结束>`

    就可以看到你的提交了,直接把不想要的那几行前面的 pick -> squash 了(默认的操作编辑器是 vim ,感受一下命令行最叼编辑器吧),但你很容易删错,因为你此时看不到到底那几个提交记录了你哪几个文件,更改提交则使用 pick -> edit
    接下来保存退出(什么你连保存退出 vim 都不会那还是趁早放弃吧——)

    再执行`git commit --amend`保存这次修改,最后`git rebase --continue`就完成了这次修改,再 force push 到远端就抹除了,其他人已有你那个提交最简单就是重新 clone 一个,不然还要重新 merge

    其实是很复杂的,你可以随时`git log`看看变化。

    简化到 GUI 上就是打开提交历史,压扁成一个提交,没了就这么简单。

    这是我这么多年和 git 搏斗总结的经验,如果还是有冥顽不化的人非要 reset 那只能祝你早日被 git 气到中风
    SimonOne
        22
    SimonOne  
       250 天前
    @xubeiyan #21 我一般用 sourcetree ,但是没找到这种合并几个提交的地方,所以我用 sourcetree 先看下几个提交,然后再命令行 rebase 合并。但是就我一个人,就一个分支 main ,弄烂了大不了重新远端拉下来重来。
    如果是多人项目,分支有好几个的,我不敢动直接开摆。🙈
    guguji5
        23
    guguji5  
       250 天前
    ![把 100M 的视频提交到 git 后,差点下不了班]( https://zhuanlan.zhihu.com/p/532076688)
    yunyuyuan
        24
    yunyuyuan  
       250 天前
    reset 然后 force push 并不能完全删除,不信可以在 github 的 activity 里看,Force push 的 commit 依然能看到,完全删除需要 BFG ,楼上说过 https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository
    xubeiyan
        25
    xubeiyan  
       250 天前 via Android
    @SimonOne 同事也是推荐我用 source tree ,但我发现竟然没有这种救我于水火的功能,就叛逃到 tortoisegit 门下了。一般多人开发的话还是要商讨有无必要做这件事,确认必须要做然后你们 git 比较熟的人来做这件事,因为这个还是挺危险的操作。顺便如果不想重新 clone ,pull 的时候加上 force 也可以强制覆盖你本地的,但为了不至于丢失原来的数据,一般推荐是重新 clone ,有什么失误也可以保留一份之前的好拯救
    shawndev
        26
    shawndev  
       250 天前
    https://github.com/rtyley/bfg-repo-cleaner

    我们之前的项目用的是 BFG 这个工具,很多国产 SDK 只提供二进制的依赖,几次迭代之后仓库就大过银河系了。
    san3
        27
    san3  
       247 天前
    git filter-branch 可行
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1055 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 18:30 · PVG 02:30 · LAX 11:30 · JFK 14:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.