git solução de limpeza de registro de arquivo grande

referência:

https://blog.csdn.net/Y0W1as5eg37urFdS/article/details/123539994

https://www.manongdao.com/article-2342370.html

visão geral

visão geral do git

Git é um software de controle de versão distribuído, originalmente criado por "Linus Torvalds" e lançado em 2005. O propósito original era gerenciar melhor o desenvolvimento do kernel do Linux. O Git salva todas as atualizações históricas sobre o projeto atual no disco local e a velocidade de processamento é rápida. A maioria das operações no Git só precisa acessar arquivos e recursos locais, sem rede em tempo real.

"Git LFS" (Large File Storage - armazenamento de arquivos grandes) é uma pequena ferramenta que pode armazenar quaisquer arquivos especificados, como música, fotos, vídeos, etc. fora do repositório Git e substituí-los por um ponteiro de texto que ocupa menos de 1 KB no repositório Git. Ao armazenar arquivos grandes fora do armazém Git, o tamanho do próprio armazém Git pode ser reduzido, a velocidade de clonagem do armazém Git pode ser acelerada e o Git não perderá desempenho porque o armazém está cheio de arquivos grandes.

Com o Git LFS, por padrão, apenas a versão atual do objeto LFS sob o commit atualmente verificado será baixada. Além disso, ele também pode ser configurado para buscar apenas o conteúdo real de alguns arquivos específicos gerenciados pelo Git LFS, mantendo apenas os ponteiros de arquivos para outros arquivos gerenciados pelo Git LFS, economizando largura de banda e acelerando a velocidade dos armazéns de clonagem; também pode ser configurado para obter a versão mais recente de um arquivo grande por vez, para que seja conveniente verificar as alterações recentes de arquivos grandes.


diretório .git

Embora o diretório oculto do .git não seja contado após o volume do código, ele precisa ser puxado para baixo ao puxar o código, porque contém informações como registros de envio anteriores. Isso fará com que a velocidade de download fique muito lenta.

├── HEAD
├── branches
├── index
├── logs
│   ├── HEAD
│   └── refs
│       └── heads
│           └── master
├── objects
│   ├── 88
│   │   └── 23efd7fa394844ef4af3c649823fa4aedefec5
│   ├── 91
│   │   └── 0fc16f5cc5a91e6712c33aed4aad2cfffccb73
│   ├── 9f
│   │   └── 4d96d5b00d98959ea9960f069585ce42b1349a
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   └── master
    └── tags
  • descrição: para o programa GitWeb
  • config: define configurações específicas para este repositório
  • ganchos: coloque scripts de gancho no lado do cliente ou do servidor
  • HEAD: indica em qual ramo você está atualmente
  • objetos: diretório de armazenamento de objetos Git
  • refs: diretório de armazenamento de referência do Git
  • branches: o diretório onde as referências de branch são colocadas

A razão pela qual o diretório .git se torna maior

  • Ao usar os comandos git add e git commit, o Git gerará um objeto Git, chamado de objeto blob, armazenado no diretório de objetos, atualizará o índice do índice, criará um objeto de árvore e, finalmente, criará um objeto de confirmação. Esses objetos de confirmação apontam para o objeto de árvore de nível superior e objetos de confirmação anteriores.
  • Os objetos criados acima são todos salvos no diretório .git/objects como arquivos. Portanto, quando um arquivo com um tamanho particularmente grande for enviado durante o uso, ele será rastreado e registrado pelo Git na pasta .git/objects.
  • Mesmo que esse arquivo particularmente grande seja excluído posteriormente, na verdade, o Git registrará apenas a operação de exclusão e não excluirá o arquivo da pasta .git, ou seja, a pasta .git não ficará menor.

solução

Opção 1: Reconstruir o armazém

Este método de reconstrução do armazém pode ser considerado uma forma definitiva e relativamente simples. No entanto, essa abordagem geralmente não é viável, a menos que seja seu próprio projeto local.


Cenário 2: Excluir Arquivos Grandes

Localize diretamente o arquivo grande no diretório .git, exclua-o e, em seguida, envie-o para o repositório de código remoto. A premissa de fazer isso é excluir todas as outras ramificações, manter a ramificação master ou principal, limpar todas as ramificações do projeto atual no servidor git e enviar novamente. O que precisa ser observado aqui é que a operação é arriscada e as consequências são por sua conta e risco.

  1. Clique com o botão direito do mouse no diretório raiz do projeto git e use Git Bash Here para abrir a janela de comando do Git

  2. Encontre os cinco maiores arquivos de registro de confirmação no projeto git

    git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -5
    
    # 命令说明:
    # 	verify-pack	显示已打包的内容(找大文件)
    # 	sort -k 3 -g	以第三列排序
    

    Resultados da execução (atualmente, a introdução é baseada nas cinco maiores consultas):

    dbad6eb20d31a5aefe132b74b2137cd10105c574 blob   16684712 7287784 86721282
    6c858bc93421b2db41dafc2bfd4eb82c77c50266 blob   17504576 8257957 47764046
    416088453a2514ada98ba639af3ff298510b4246 blob   22216104 10854126 75719527
    f0d8d3b476526af42b4e06f390a1b4925580e99b blob   22435760 10589160 16678516
    553ba826b92c9d42acb1e586774ac697661588c9 blob   29814552 12998052 60871184
    
  3. As letras na primeira linha são realmente equivalentes ao id do arquivo. Use o seguinte comando para descobrir o nome do arquivo correspondente ao id

    git rev-list --objects --all | grep dbad6eb20d31a5aefe132b74b2137cd10105c574
    
    # 命令说明:
    # 	rev-list   	列出Git仓库中的所有提交记录
    # 	--objects  	列出该提交涉及的所有文件ID
    # 	--all	    所有分支的提交(位于/refs下的所有引用)
    
    

    Resultados do

    dbad6eb20d31a5aefe132b74b2137cd10105c574 Pods/UMengUShare/UShareSDK/SocialLibraries/WeChat/WechatSDK/libWeChatSDK.a
    
  4. Excluir registros de arquivos grandes

    git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch Pods/UMengUShare/UShareSDK/SocialLibraries/WeChat/WechatSDK/libWeChatSDK.a' --tag-name-filter cat -- --all
    
    # 命令说明
    # 	filter-branch	重写Git仓库中的提交
    # 	--index-filter	指定后面命令进行删除
    # 	--all			所有分支的提交(位于/refs下的所有引用)
    

    Depois que o código acima é executado, o seguinte erro pode ser relatado

    WARNING: git-filter-branch has a glut of gotchas generating mangled history
         rewrites.  Hit Ctrl-C before proceeding to abort, then use an
         alternative filtering tool such as 'git filter-repo'
         (https://github.com/newren/git-filter-repo/) instead.  See the
         filter-branch manual page for more details; to squelch this warning,
         set FILTER_BRANCH_SQUELCH_WARNING=1.
    Proceeding with filter-branch...
    
    Cannot rewrite branches: You have unstaged changes.
    

    Se o erro acima ocorrer, execute o seguinte comando (pule esta etapa se nenhum erro for relatado)

    git stash
    

    Em seguida, execute o comando remove novamente

    Resultados do

    WARNING: git-filter-branch has a glut of gotchas generating mangled history
         rewrites.  Hit Ctrl-C before proceeding to abort, then use an
         alternative filtering tool such as 'git filter-repo'
         (https://github.com/newren/git-filter-repo/) instead.  See the
         filter-branch manual page for more details; to squelch this warning,
         set FILTER_BRANCH_SQUELCH_WARNING=1.
    Proceeding with filter-branch...
    
    Rewrite 967ff01a8b2bc7d7f6c90630ede38a2135ba5813 (1/41) (0 seconds passed, remaiRewrite 9674de7f9f8ed029785421f2246bb9d41786cc49 (2/41) (0 seconds passed, remaiRewrite e04ab331167f24b7d26d69e169386e690081af74 (3/41) (0 seconds passed, remaiRewrite 997e93fdaff75162eda8e5c6ee6d3265ce61fe96 (4/41) (0 seconds passed, 
    Rewrite 429d321e2ee4c54d8d96b35a8e35d021bd8930f1 (35/41) (3 seconds passed, remaining 0 predicted)    rm 'Pods/UMengUShare/UShareSDK/SocialLibraries/WeChat/WechatSDK/libWeChatSDK.a'
    
    Ref 'refs/heads/master' was rewritten
    Ref 'refs/remotes/origin/master' was rewritten
    WARNING: Ref 'refs/remotes/origin/master' is unchanged
    Ref 'refs/stash' was rewritten
    
  5. limpar

    rm -rf .git/refs/original/
    git reflog expire --expire=now --all
    git gc --prune=now
    
  6. Forçar Push Remoto

    git push --force --all
    
    # 让远程仓库变小
    git remote prune origin
    

Solução 3: Use a ferramenta git repo-clean para limpar (pró-teste, recomendado)

git repo-clean é uma ferramenta de extensão Git desenvolvida em Golang que tem as funções de escanear, limpar e reescrever registros de commit para arquivos grandes em armazéns Git.

Para código-fonte e detalhes de download e instalação, consulte: https://gitee.com/oschina/git-repo-clean

Recomenda-se usar a instalação do pacote binário , que é simples e conveniente


usar :

Existem duas maneiras de usá-lo, uma é a linha de comando e a outra é interativa.

As opções atuais são as seguintes:

  -v, --verbose		显示处理的详细过程
  -V, --version		显示 git-repo-clean 版本号
  -h, --help		显示使用信息
  -p, --path		指定Git仓库的路径, 默认是当前目录,即'.'
  -s, --scan		扫描Git仓库数据,默认是扫描所有分支中的数据
  -f, --file		直接指定仓库中的文件或目录,与'--scan'不兼容
  -b, --branch		设置需要删除文件的分支, 默认是从所有分支中删除文件
  -l, --limit		设置扫描文件阈值, 比如: '--limit=10m'
  -n, --number		设置显示扫描结果的数量
  -t, --type		设置扫描文件后缀名,即文件类型
  -i, --interactive 	开启交互式操作
  -d, --delete		执行文件删除和历史重写过程
  -L, --lfs		将大文件转换为Git LFS指针文件

Uso da linha de comando:

git repo-clean --verbose --scan --limit=1G --type=tar.gz --number=5

Com a opção --delete, os arquivos digitalizados serão excluídos em lotes e o histórico de confirmação relacionado (incluindo HEAD) será reescrito

git repo-clean --verbose --scan --limit=1G --type=tar.gz --number=5 --delete 

Perceber:

  • Se não houver nenhum comando repo-clean ao entrar na janela de comando bash diretamente do diretório raiz do projeto git e usar o comando repo-clean, você pode inserir cmd através de [Iniciar] no canto inferior esquerdo para entrar na janela de comando e, em seguida, usar o comando para alternar para o diretório raiz do projeto git e, em seguida, usar o comando repo-clean
  • No momento, a operação de varredura e a operação de exclusão são executadas em todas as ramificações por padrão, e --brancha opção especifica apenas a ramificação ao excluir e não pode especificar a ramificação ao digitalizar. Portanto, se esta opção for usada para especificar uma ramificação, os arquivos em outra ramificação podem ser selecionados nos resultados da verificação, portanto, nenhum arquivo será realmente excluído.

Solução 4: use o comando migration para otimizar o diretório .git

Migre depósitos git existentes e use git lfs para gerenciá-los. Depois de reescrever o histórico, você precisa executar git commit --force. Por favor, confirme se a operação local está correta antes de enviar. Se houver várias cópias do warehouse antes de migrar para git lfs, outras cópias podem precisar executar git reset --hard origin/master para redefinir suas ramificações locais. Observe que a execução do comando git reset --hard perderá as alterações locais

git lfs migration: usado para salvar os arquivos atualmente salvos pelo repositório GIT (.git) como arquivos LFS

# 重写master分⽀
# 将历史提交(指的是.git目录)中的*.zip都⽤lfs进⾏管理
$ git lfs migrate import --include-ref=master --include="*.zip"
 
# 重写所有分⽀及标签
# 将历史提交(指的是.git目录)中的*.rar,*.zip都⽤lfs进⾏管理
$ git lfs migrate import --everything --include="*.rar,*.zip"
 
# 切换后需要把切换之后的本地分支提交到远程仓库了,需要手动push更新远程仓库中的各个分支
$ git lfs push --force
 
# 切换成功后,GIT仓库的大小可能并没有变化
# 主要原因可能是之前的提交还在,因此需要做一些清理工作
# 如果不是历史记录非常重要的仓库,建议不要像上述这么做,而是重新建立一个新的仓库
$ git reflog expire --expire-unreachable=now --all
$ git gc --prune=now

expandir

Gerenciar arquivos grandes com lfs

A melhor maneira de evitar os problemas acima é usar o tempo lfspara rastrear, registrar e gerenciar arquivos grandes. Esses arquivos grandes não poluem nosso .gitdiretório, mas também nos permitem usá-los de maneira mais conveniente.

# 1.开启lfs功能
$ git lfs install
 
# 2.追踪所有后缀名为“.psd”的文件
$ git lfs track "*.iso"
 
# 3.追踪单个文件
git lfs track "logo.png"
 
# 4.提交存储信息文件
$ git add .gitattributes
 
# 5.提交并推送到GitHub仓库
$ git add .
$ git commit -m "Add some files"
$ git push origin master

Ao mesmo tempo, existe outro método, que é usar arquivos de forma flexível .gitignorepara excluir diretórios especiais ou arquivos que não são necessários no warehouse a tempo, para evitar que arquivos que não deveriam existir apareçam no code warehouse

.DS_Store
node_modules
/dist
 
*.zip
*.tar.gz

Acho que você gosta

Origin blog.csdn.net/footless_bird/article/details/125686432
Recomendado
Clasificación