The Easy Way ™
Resulta que esta es una práctica tan común y útil que los señores superiores de Git lo hicieron realmente fácil, pero debe tener una versión más nueva de Git (> = 1.7.11 de mayo de 2012). Consulte el apéndice sobre cómo instalar el último Git. Además, hay un ejemplo del mundo real en el tutorial a continuación.
Prepara el viejo repositorio
cd <big-repo>
git subtree split -P <name-of-folder> -b <name-of-new-branch>
Nota: <name-of-folder>
NO debe contener caracteres iniciales o finales. Por ejemplo, la carpeta llamada subproject
DEBE pasar como subproject
, NO./subproject/
Nota para usuarios de Windows: cuando la profundidad de la carpeta es> 1, <name-of-folder>
debe tener un separador de carpeta de estilo * nix (/). Por ejemplo, la carpeta llamada path1\path2\subproject
DEBE pasar comopath1/path2/subproject
Crea el nuevo repositorio
mkdir ~/<new-repo> && cd ~/<new-repo>
git init
git pull </path/to/big-repo> <name-of-new-branch>
Enlace el nuevo repositorio a GitHub o donde sea
git remote add origin <git@github.com:user/new-repo.git>
git push -u origin master
Limpieza interior <big-repo>
, si lo desea
git rm -rf <name-of-folder>
Nota : Esto deja todas las referencias históricas en el repositorio. Consulte el Apéndice a continuación si realmente le preocupa haber cometido una contraseña o si necesita disminuir el tamaño del archivo de su .git
carpeta.
...
Tutorial
Estos son los mismos pasos que los anteriores , pero seguir mis pasos exactos para mi repositorio en lugar de usarlos <meta-named-things>
.
Aquí hay un proyecto que tengo para implementar módulos de navegador JavaScript en el nodo:
tree ~/node-browser-compat
node-browser-compat
├── ArrayBuffer
├── Audio
├── Blob
├── FormData
├── atob
├── btoa
├── location
└── navigator
Quiero dividir una sola carpeta btoa
, en un repositorio Git separado
cd ~/node-browser-compat/
git subtree split -P btoa -b btoa-only
Ahora tengo una nueva rama, btoa-only
que solo tiene commits btoa
y quiero crear un nuevo repositorio.
mkdir ~/btoa/ && cd ~/btoa/
git init
git pull ~/node-browser-compat btoa-only
A continuación, creo un nuevo repositorio en GitHub o Bitbucket, o lo que sea, y lo agrego como origin
git remote add origin git@github.com:node-browser-compat/btoa.git
git push -u origin master
¡Día feliz!
Nota: Si creó un repositorio con a README.md
, .gitignore
y LICENSE
, primero deberá extraer:
git pull origin master
git push origin master
Por último, querré eliminar la carpeta del repositorio más grande
git rm -rf btoa
...
Apéndice
Latest Git en macOS
Para obtener la última versión de Git con Homebrew :
brew install git
Último Git en Ubuntu
sudo apt-get update
sudo apt-get install git
git --version
Si eso no funciona (tiene una versión muy antigua de Ubuntu), intente
sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install git
Si eso todavía no funciona, intente
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
Gracias a rui.araujo por los comentarios.
Limpiando tu historia
De forma predeterminada, eliminar archivos de Git en realidad no los elimina, solo confirma que ya no están allí. Si realmente desea eliminar las referencias históricas (es decir, tiene una contraseña confirmada), debe hacer esto:
git filter-branch --prune-empty --tree-filter 'rm -rf <name-of-folder>' HEAD
Después de eso, puede verificar que su archivo o carpeta ya no aparezca en el historial de Git
git log -- <name-of-folder> # should show nothing
Sin embargo, no puede "empujar" eliminaciones a GitHub y similares. Si lo intentas, obtendrás un error y tendrás que hacerlo git pull
antes de que puedas git push
, y luego volverás a tener todo en tu historial.
Por lo tanto, si desea eliminar el historial del "origen", es decir, eliminarlo de GitHub, Bitbucket, etc., deberá eliminar el repositorio y volver a enviar una copia podada del repositorio. Pero espera, ¡ hay más ! - Si realmente le preocupa deshacerse de una contraseña o algo así, deberá podar la copia de seguridad (consulte a continuación).
Haciendo .git
más pequeño
El comando eliminar historial mencionado anteriormente todavía deja atrás un montón de archivos de copia de seguridad, porque Git es muy amable al ayudarlo a no arruinar su repositorio por accidente. Eventualmente eliminará archivos huérfanos a lo largo de los días y meses, pero los dejará allí por un tiempo en caso de que se dé cuenta de que eliminó accidentalmente algo que no quería.
Entonces, si realmente desea vaciar la basura para reducir el tamaño de clon de un repositorio de inmediato, debe hacer todo esto realmente extraño:
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
Dicho esto, recomendaría no realizar estos pasos a menos que sepa que necesita hacerlo, en caso de que haya eliminado el subdirectorio incorrecto, ¿sabe? Los archivos de copia de seguridad no deben clonarse cuando presiona el repositorio, solo estarán en su copia local.
Crédito
git filter-branch
ver mi respuesta a continuación.