The Easy Way ™
Si scopre che questa è una pratica così comune e utile che i signori di Git lo hanno reso davvero facile, ma devi avere una versione più recente di Git (> = 1.7.11 Maggio 2012). Vedi l' appendice per come installare l'ultimo Git. Inoltre, c'è un esempio del mondo reale nella procedura dettagliata di seguito.
Preparare il vecchio repository
cd <big-repo>
git subtree split -P <name-of-folder> -b <name-of-new-branch>
Nota: <name-of-folder>
NON deve contenere caratteri iniziali o finali. Ad esempio, la cartella denominata subproject
DEVE essere passata come subproject
, NOT./subproject/
Nota per utenti Windows: quando la profondità della cartella è> 1, è <name-of-folder>
necessario disporre del separatore di cartelle in stile * nix (/). Ad esempio, la cartella denominata path1\path2\subproject
DEVE essere passata comepath1/path2/subproject
Crea il nuovo repository
mkdir ~/<new-repo> && cd ~/<new-repo>
git init
git pull </path/to/big-repo> <name-of-new-branch>
Collega il nuovo repository a GitHub o ovunque
git remote add origin <git@github.com:user/new-repo.git>
git push -u origin master
Pulizia all'interno <big-repo>
, se lo si desidera
git rm -rf <name-of-folder>
Nota : questo lascia tutti i riferimenti storici nel repository.Vedi l' Appendice di seguito se sei effettivamente preoccupato di aver commesso una password o devi ridurre le dimensioni del file della tua .git
cartella.
...
Procedura dettagliata
Questi sono gli stessi passaggi di cui sopra , ma seguendo i miei esatti passaggi per il mio repository invece di utilizzare <meta-named-things>
.
Ecco un progetto che ho per l'implementazione di moduli browser JavaScript nel nodo:
tree ~/node-browser-compat
node-browser-compat
├── ArrayBuffer
├── Audio
├── Blob
├── FormData
├── atob
├── btoa
├── location
└── navigator
Voglio dividere una singola cartella btoa
, in un repository Git separato
cd ~/node-browser-compat/
git subtree split -P btoa -b btoa-only
Ora ho una nuova filiale, btoa-only
che ha solo commit btoa
e voglio creare un nuovo repository.
mkdir ~/btoa/ && cd ~/btoa/
git init
git pull ~/node-browser-compat btoa-only
Quindi creo un nuovo repository su GitHub o Bitbucket o qualsiasi altra cosa e lo aggiungo come origin
git remote add origin git@github.com:node-browser-compat/btoa.git
git push -u origin master
Giorno felice!
Nota: Se si è creato un pronti contro termine con una README.md
, .gitignore
e LICENSE
, è necessario tirare prima:
git pull origin master
git push origin master
Infine, desidero rimuovere la cartella dal repository più grande
git rm -rf btoa
...
Appendice
Git più recente su macOS
Per ottenere l'ultima versione di Git usando Homebrew :
brew install git
Git più recente su Ubuntu
sudo apt-get update
sudo apt-get install git
git --version
Se non funziona (hai una versione molto vecchia di Ubuntu), prova
sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install git
Se il problema persiste, prova
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
Grazie a rui.araujo dai commenti.
Cancella la tua storia
Per impostazione predefinita, la rimozione dei file da Git in realtà non li rimuove, si impegna semplicemente a non essere più lì. Se desideri effettivamente rimuovere i riferimenti storici (ovvero hai una password impegnata), devi farlo:
git filter-branch --prune-empty --tree-filter 'rm -rf <name-of-folder>' HEAD
Dopodiché puoi verificare che il tuo file o la tua cartella non compaiano più nella cronologia di Git
git log -- <name-of-folder> # should show nothing
Tuttavia, non puoi "spingere" le eliminazioni su GitHub e simili. Se provi riceverai un errore e dovrai farlo git pull
prima che tu possa farlo git push
- e poi tornerai ad avere tutto nella tua storia.
Pertanto, se si desidera eliminare la cronologia da "origine", ovvero eliminarla da GitHub, Bitbucket, ecc., È necessario eliminare il repository e ripetere il push di una copia eliminata del repository. Ma aspetta - c'è di più ! - Se sei davvero preoccupato di eliminare una password o qualcosa del genere, dovrai eliminare il backup (vedi sotto).
rendere .git
più piccolo
Il comando di eliminazione della cronologia sopra menzionato lascia ancora un mucchio di file di backup - perché Git è fin troppo gentile nell'aiutarti a non rovinare il tuo repository per caso. Alla fine cancellerà i file orfani nel corso dei giorni e dei mesi, ma li lascerà lì per un po 'nel caso in cui ti rendi conto che hai eliminato accidentalmente qualcosa che non volevi.
Quindi, se vuoi davvero svuotare il cestino per ridurre immediatamente la dimensione del clone di un repository, devi fare tutte queste cose davvero strane:
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
Detto questo, consiglierei di non eseguire questi passaggi a meno che tu non sappia che è necessario - nel caso in cui tu abbia potato la sottodirectory sbagliata, sai? I file di backup non dovrebbero essere clonati quando si effettua il push del repository, saranno solo nella copia locale.
Credito
git filter-branch
vedere la mia risposta qui sotto.