The Easy Way ™
Acontece que essa é uma prática tão comum e útil que os senhores superiores do Git tornaram muito fácil, mas você precisa ter uma versão mais recente do Git (> = 1.7.11 maio de 2012). Veja o apêndice para saber como instalar o Git mais recente. Além disso, há um exemplo do mundo real na explicação abaixo.
Prepare o repo antigo
cd <big-repo>
git subtree split -P <name-of-folder> -b <name-of-new-branch>
Nota: <name-of-folder>
NÃO deve conter caracteres iniciais ou finais. Por exemplo, a pasta denominada subproject
DEVE ser passada como subproject
, NÃO./subproject/
Nota para usuários do Windows: quando a profundidade da pasta for> 1, <name-of-folder>
deve haver * separador de pastas no estilo nix (/). Por exemplo, a pasta denominada path1\path2\subproject
DEVE ser passada comopath1/path2/subproject
Crie o novo repositório
mkdir ~/<new-repo> && cd ~/<new-repo>
git init
git pull </path/to/big-repo> <name-of-new-branch>
Vincule o novo repositório ao GitHub ou a qualquer outro lugar
git remote add origin <git@github.com:user/new-repo.git>
git push -u origin master
Limpeza interna <big-repo>
, se desejado
git rm -rf <name-of-folder>
Nota : Isso deixa todas as referências históricas no repositório. Consulte o Apêndice abaixo se você estiver realmente preocupado em confirmar uma senha ou se precisar diminuir o tamanho do arquivo da sua .git
pasta.
...
Passo a passo
Estas são as mesmas etapas acima , mas seguindo as etapas exatas para o meu repositório em vez de usar <meta-named-things>
.
Aqui está um projeto que tenho para implementar os módulos do navegador JavaScript no nó:
tree ~/node-browser-compat
node-browser-compat
├── ArrayBuffer
├── Audio
├── Blob
├── FormData
├── atob
├── btoa
├── location
└── navigator
Quero dividir uma única pasta btoa
,, em um repositório Git separado
cd ~/node-browser-compat/
git subtree split -P btoa -b btoa-only
Agora tenho uma nova ramificação,, btoa-only
que só tem confirmações btoa
e quero criar um novo repositório.
mkdir ~/btoa/ && cd ~/btoa/
git init
git pull ~/node-browser-compat btoa-only
Em seguida, crio um novo repositório no GitHub ou Bitbucket, ou qualquer outra coisa e adiciono-o como origin
git remote add origin git@github.com:node-browser-compat/btoa.git
git push -u origin master
Dia feliz!
Nota: Se você criou um repositório com a README.md
, .gitignore
e LICENSE
, precisará puxar primeiro:
git pull origin master
git push origin master
Por fim, desejarei remover a pasta do repositório maior
git rm -rf btoa
...
Apêndice
Git mais recente no macOS
Para obter a versão mais recente do Git usando o Homebrew :
brew install git
Últimas Git no Ubuntu
sudo apt-get update
sudo apt-get install git
git --version
Se isso não funcionar (você tem uma versão muito antiga do Ubuntu), tente
sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install git
Se isso ainda não funcionar, tente
sudo chmod +x /usr/share/doc/git/contrib/subtree/git-subtree.sh
sudo ln -s \
/usr/share/doc/git/contrib/subtree/git-subtree.sh \
/usr/lib/git-core/git-subtree
Obrigado a rui.araujo pelos comentários.
Limpando seu histórico
Por padrão, remover arquivos do Git na verdade não os remove, apenas confirma que eles não estão mais lá. Se você realmente deseja remover as referências históricas (por exemplo, uma senha confirmada), é necessário fazer o seguinte:
git filter-branch --prune-empty --tree-filter 'rm -rf <name-of-folder>' HEAD
Depois disso, você pode verificar se seu arquivo ou pasta não aparece mais no histórico do Git
git log -- <name-of-folder> # should show nothing
No entanto, você não pode "empurrar" exclusões para o GitHub e similares. Se você tentar, receberá um erro e precisará fazê- git pull
lo antes de poder git push
- e voltará a ter tudo no seu histórico.
Portanto, se você deseja excluir o histórico da "origem" - ou seja, para excluí-lo do GitHub, Bitbucket, etc -, será necessário excluir o repositório e reenviar uma cópia removida do repositório. Mas espere - há mais ! - Se você estiver realmente preocupado em se livrar de uma senha ou algo parecido, precisará remover o backup (veja abaixo).
Fazendo .git
menor
O comando delete history mencionado acima ainda deixa para trás um monte de arquivos de backup - porque o Git é muito gentil em ajudá-lo a não arruinar seu repositório por acidente. Eventualmente, ele excluirá arquivos órfãos ao longo dos dias e meses, mas os deixará lá por um tempo, caso você perceba que excluiu acidentalmente algo que não queria.
Portanto, se você realmente quiser esvaziar o lixo para reduzir o tamanho do clone de um repositório imediatamente, precisará fazer todas essas coisas realmente estranhas:
rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune=now
git reflog expire --all --expire-unreachable=0
git repack -A -d
git prune
Dito isso, eu recomendaria não executar essas etapas, a menos que você saiba que precisa - apenas no caso de remover o subdiretório errado, sabe? Os arquivos de backup não devem ser clonados quando você envia o repositório, eles estarão apenas na sua cópia local.
Crédito
git filter-branch
minha resposta abaixo.