Git: Subdividir projeto principal

Git: Subdividir projeto principal

Subdividir projeto git

Problema

Tenho um projeto hospedado no gitlab, no qual atingiu o limite de size-pack.
$ git count-objects -vH
warning: garbage found: .git/objects/pack/tmp_pack_hkchbh
count: 846
size: 4.60 MiB
in-pack: 385027
packs: 1
size-pack: 9.56 GiB
prune-packable: 0
garbage: 1
size-garbage: 0 bytes
E apresenta o seguinte erro:
$ git push --all && git push --tag
Counting objects: 30, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (30/30), 1.23 MiB | 54.92 MiB/s, done.
Total 30 (delta 23), reused 22 (delta 16)
remote: GitLab: Your push to this repository would cause it to exceed the size limit of 9.8 GB so it has been rejected. Please contact your GitLab administrator for more information.
..

Levantamento de informações

Vamos descobrir o volume de dados de cada subdiretório do projeto.
$ du -sh ./*
4,0K	./attr_not_good.csv
17M	./build
16K	./CHANGELOG
24M	./data
347M	./dist
20K	./docs
1021M	./exemplos
1,6M	./get-pip.py
124K	./hs_err_pid30290.log
4,0K	./logger.cfg
328K	./logger.log
11M	./logger.log.1
4,0K	./MANIFEST.in
4,0K	./Pipfile
84K	./Pipfile.lock
4,0K	./README.md
56M	./relatorios
4,0K	./requirements-dev.txt
4,0K	./runtests.sh
4,0K	./saj_projects
4,0K	./setup.cfg
8,0K	./setup.py
18M	./src
8,7G	./src_production
8,0K	./temp.txt
4,0K	./tox.ini
5,7M	./view

Aqui podemos identificar que ./exemplos e ./src_production são os maiores diretórios, ocupando ~1021M e ~8700M respectivamente. Então podemos inferir que os vilões consumindo 9.56G são estes.

Escopo

  • Sistema Operacional Linux;
  • gitlab
  • github
Neste projeto em ./exemplos consta o Arquivamento de demandas concluídas e outros exemplos, em ./src_production consta as demandas ativas não arquivadas e implementações jupyter.
Para uma eficaz subdivisão, iremos fracionar no projeto principal em mais três subprojetos. Sendo criado dois subprojetos para arquivamento no gitlab, e um outro subprojeto para jupyter no github.

  1. git@github.com:incolumepy/legis-jupyter.git
  2. git@gitlab.com:development-incolume/saj_projects_arquive0.git
  3. git@gitlab.com:development-incolume/saj_projects_arquive1.git

Implementação

Arquivamento do repositório no estado atual
  1. Crie um novo grupo no gitlab ou github, com nome archived;
  2. Gere um fork, do projeto original para o grupo archived;
  3. Nas configurações do repositório gitlab/github para o fork, altere o "nome do projeto" e "caminho"; ex: saj_projects > saj_projects_on_202008
  4. Neste momento teremos dois repositórios idênticos, em endereços distintos. ex: https://gitlab.com/incolume-archived/saj_projects_on_202008 e https://gitlab.com/development-incolume/saj_projects;
  5. Atenção somente os repositórios estarão idênticos, não o projeto. Wiki, Marcos, Issues, todos estarão em branco no fork.
Preservar o Workdir no estado atual

Provavelmente há mudanças não persistidas. Então sigas estes passos:
  • Crie um repositório local. No sistema de arquivos execute:
    • $ git init --bare saj_projects.git
  • Acesse o diretório com o conteúdo atual do workdir:
    • $ cd saj_projects
    • $ git remote rename origin old
    • $ git remote add origin file:///path/to/saj_projects.git
    • $ git push -u origin --all && git push -u origin --tags
  • Agora o conteúdo completo do workdir, estará armazenado no repositório local file:///path/to/saj_projects.git, totalmente protegido e com garantia de preservação das últimas alterações.
Criar Nova árvore para projeto principal
  • Clone do repositório local
    • $ git clone file:///path/to/saj_projects.git
  • Organize os branches não finalizados. Neste exemplo rebase da issue 861:
    • $ branch=feature/issue#861; git co $branch && git rebase origin/master && git push origin $branch -f
  • Clone do repositório local com registro a partir da data desejada:
    • $ git clone --shallow-since=2020-07-01 file:///path/to/saj_projects.git t4
    • $ cd t4
    • $ git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
    • $ git fetch origin
  • Redirecione o alias origin para o repositório remoto
    • $ git remote rename origin local
    • $ git remote add origin git@gitlab.com:development-incolume/saj_projects.git
  • No gitlab.com encontre Seu projeto GitLab > Settings > Repository > Protected Branches e retire a proteção do master; relembre as opções para colocá-las novamente após este processo.
  • Substitua o master remoto com o novo master "Remasterizado":
    • $ git push origin master -f
  • Recupere os branches, execute os camandos abaixo para cada branch:
    • $ git co feature/issue#861
    • $ git push origin -f feature/issue#861
  • Restaure a proteção do master no gitlab.com,  Seu projeto GitLab > Settings > Repository > Protected Branches;

Fracionamento para exemplos/Arquivo/
  • Clone o repositório que será fracionado:
    • $ git clone --no-hardlinks saj_projects saj_projects_arquive0
  • Filtrar conteúdo a ser fracionado:
    • $ cd saj_projects_arquive0
    • $ git filter-branch --prune-empty --subdirectory-filter exemplos/Arquivados/ master
  • Alterar o repositório remoto:
    • Crie um novo projeto e deixe-o totalmente vazio, e utilize sua url no passo seguinte.
    • $ git remote set-url origin git@gitlab.com:development-incolume/saj_projects_arquive0.git
  • Persistir alterações no novo repositório remoto:
    • $ git push -u origin master

Fracionamento para src_production/issue_jupyter/
  • Clone o repositório que será fracionado:
    • $ git clone --no-hardlinks saj_projects legis-jupyter
  • Filtrar conteúdo a ser fracionado:
    • $ cd legis-jupyter
    • $ git filter-branch --prune-empty --subdirectory-filter src_production/issue_jupyter/ master
  • Alterar o repositório remoto:
    • Crie um novo projeto e deixe-o totalmente vazio.
    • $ git remote set-url origin git@github.com:incolumepy/legis-jupyter.git
  • Persistir alterações no novo repositório remoto:
    • $ git push -u origin master
Mapear subprojetos
$ cd ../saj_projects
$ git remote add legis-jupyter git@github.com:incolumepy/legis-jupyter.git
$ git remote add arquive0 git@gitlab.com:development-incolume/saj_projects_arquive0.git
$ git remote add arquive1 git@gitlab.com:development-incolume/saj_projects_arquive1.git

$ git remote -v
arquive0    git@gitlab.com:development-incolume/saj_projects_arquive0.git (fetch)
arquive0    git@gitlab.com:development-incolume/saj_projects_arquive0.git (push)
arquive1    git@gitlab.com:development-incolume/saj_projects_arquive1.git (fetch)
arquive1    git@gitlab.com:development-incolume/saj_projects_arquive1.git (push)
legis-jupyter    git@github.com:incolumepy/legis-jupyter.git (fetch)
legis-jupyter    git@github.com:incolumepy/legis-jupyter.git (push)
origin    git@gitlab.com:development-incolume/saj_projects.git (fetch)
origin    git@gitlab.com:development-incolume/saj_projects.git (push)

Associar projetos independentes com subarvores
$ git subtree add --prefix=src_production/issue_jupyter legis-jupyter master
$ git subtree add --prefix=exemplos/Arquives/Arquive0 arquive0 master
$ git subtree add --prefix=exemplos/Arquives/Arquive1 arquive1 master

Limpar registros no workdir
$ git reflog expire --all --expire=now
$ git gc --prune=now --aggressive

Comentários