tag - ¿Hacer que la confirmación actual sea la única confirmación(inicial) en un repositorio Git?
git config--global (12)
Lo que me gustaría hacer es eliminar TODO el historial de versiones del repositorio Git local, para que el contenido actual del repositorio aparezca como el único compromiso (y, por lo tanto, las versiones anteriores de los archivos dentro del repositorio no se almacenan).
Una respuesta más conceptual:
git automáticamente la basura recolecta confirmaciones antiguas si no hay etiquetas / ramas / ref. Así que simplemente tiene que eliminar todas las etiquetas / ramas y crear un nuevo compromiso huérfano, asociado con cualquier rama. Por convención, permitiría que el master
la rama apunte a ese compromiso.
Los antiguos, inalcanzables compromisos nunca serán vistos por nadie a menos que vayan a cavar con comandos de git de bajo nivel. Si eso es suficiente para usted, me detendría allí y dejaría que el GC automático haga su trabajo cuando lo desee. Si desea deshacerse de ellos de inmediato, puede usar git gc
(posiblemente con --aggressive --prune=all
). Para el repositorio de git remoto, no hay forma de forzar eso, a menos que tenga acceso de shell a su sistema de archivos.
Actualmente tengo un repositorio Git local, que presiona a un repositorio Github.
El repositorio local tiene ~ 10 confirmaciones, y el repositorio Github es un duplicado sincronizado de esto.
Lo que me gustaría hacer es eliminar TODO el historial de versiones del repositorio Git local, para que el contenido actual del repositorio aparezca como el único compromiso (y, por lo tanto, las versiones anteriores de los archivos dentro del repositorio no se almacenan).
Entonces me gustaría empujar estos cambios a Github.
He investigado el rebase de Git, pero esto parece ser más adecuado para eliminar versiones específicas. Otra solución potencial es eliminar el repositorio local y crear uno nuevo, ¡aunque esto probablemente creará mucho trabajo!
ETA: hay directorios / archivos específicos que no están rastreados; si es posible me gustaría mantener el no seguimiento de estos archivos.
Para eliminar la última confirmación de git, simplemente puede ejecutar
git reset --hard HEAD^
Si está eliminando múltiples confirmaciones de la parte superior, puede ejecutar
git reset --hard HEAD~2
para eliminar las dos últimas confirmaciones. Puede aumentar el número para eliminar aún más confirmaciones.
Git tutoturial aquí proporciona ayuda sobre cómo purgar el repositorio:
desea eliminar el archivo del historial y agregarlo a .gitignore para asegurarse de que no se vuelva a confirmar accidentalmente. Para nuestros ejemplos, vamos a eliminar Rakefile del repositorio de gemas GitHub.
git clone https://github.com/defunkt/github-gem.git
cd github-gem
git filter-branch --force --index-filter /
''git rm --cached --ignore-unmatch Rakefile'' /
--prune-empty --tag-name-filter cat -- --all
Ahora que hemos borrado el archivo de la historia, asegurémonos de no volver a cometerlo accidentalmente.
echo "Rakefile" >> .gitignore
git add .gitignore
git commit -m "Add Rakefile to .gitignore"
Si está satisfecho con el estado del repositorio, necesita forzar los cambios para sobrescribir el repositorio remoto.
git push origin master --force
Aquí está el enfoque de la fuerza bruta. También elimina la configuración del repositorio.
Nota : ¡Esto NO funciona si el repositorio tiene submódulos! Si está utilizando submódulos, debería usar, por ejemplo, rebase interactivo
Paso 1: eliminar todo el historial ( asegúrese de tener una copia de seguridad, esto no se puede revertir )
rm -rf .git
Paso 2: reconstruir el repositorio de Git con solo el contenido actual
git init
git add .
git commit -m "Initial commit"
Paso 3: empujar a GitHub.
git remote add origin <github-uri>
git push -u --force origin master
El método a continuación es exactamente reproducible, por lo que no hay necesidad de ejecutar clone nuevamente si ambas partes fueron consistentes, simplemente ejecute el script en la otra parte también.
git log -n1 --format=%H >.git/info/grafts
git filter-branch -f
rm .git/info/grafts
Si luego quieres limpiarlo, prueba este script:
http://sam.nipl.net/b/git-gc-all-ferocious
Escribí un script que "mata el historial" para cada rama en el repositorio:
http://sam.nipl.net/b/git-kill-history
Véase también: http://sam.nipl.net/b/confirm
Este es mi enfoque favorito:
git branch new_branch_name $(echo "commit message" | git commit-tree HEAD^{tree})
Esto creará una nueva rama con un compromiso que agrega todo en HEAD. No altera nada más, por lo que es completamente seguro.
La única solución que funciona para mí (y mantiene los submódulos en funcionamiento) es
git checkout --orphan newBranch
git add -A # Add all files and commit them
git commit
git branch -D master # Deletes the master branch
git branch -m master # Rename the current branch to master
git push -f origin master # Force push master branch to github
git gc --aggressive --prune=all # remove the old files
Eliminar .git/
siempre causa grandes problemas cuando tengo submódulos. Usar git rebase --root
alguna manera me causaría conflictos (y tardaría mucho tiempo desde que tenía mucha historia).
La otra opción, que podría resultar una gran cantidad de trabajo si tiene muchas confirmaciones, es una rebase interactiva (asumiendo que su versión de git es> = 1.7.12): git rebase --root -i
Cuando se le presente una lista de confirmaciones en su editor:
- Cambie "pick" a "reword" para la primera confirmación
- Cambia "pick" a "fixup" cada otro commit
Guardar y cerrar. Git comenzará a rebasar.
Al final, tendrías un nuevo root commit que es una combinación de todos los que vinieron después.
La ventaja es que no tiene que eliminar su repositorio y, si tiene dudas, siempre tiene un respaldo.
Si realmente quiere bombardear su historial, restablezca el maestro a este compromiso y elimine todas las demás ramas.
Para ello, utilice el comando Shallow Clone git clone --depth 1 URL - Clones solo la HEAD actual del repositorio
Puedes usar clones poco profundos (git> 1.9):
git clone --depth depth remote-url
Lectura adicional: http://blogs.atlassian.com/2014/05/handle-big-repositories-git/
Resolví un problema similar simplemente eliminando la carpeta .git
de mi proyecto y reintegrándome con el control de versiones a través de IntelliJ. Nota: la carpeta .git
está oculta. Puede verlo en el terminal con ls -a
, y luego eliminarlo usando rm -rf .git
.
Variante del método propuesto por larsmans :
Guarda tu lista de untrackfiles:
git ls-files --others --exclude-standard > /tmp/my_untracked_files
Guarda tu configuración git:
mv .git/config /tmp/
Luego realiza los primeros pasos de larsmans:
rm -rf .git
git init
git add .
Restaura tu configuración:
mv /tmp/config .git/
Desmarque los archivos sin seguimiento:
cat /tmp/my_untracked_files | xargs -0 git rm --cached
Entonces cometa:
git commit -m "Initial commit"
Y finalmente empuje a su repositorio:
git push -u --force origin master
git for-each-ref --format=''git update-ref -d %(refname)'' /
refs/{heads,tags} | sh -x
current=$(git commit-tree -m ''Initial commit'' `git write-tree`)
git update-ref -m ''Initial commit'' `git symbolic-ref HEAD` $current
Esto eliminará todas las sucursales y etiquetas locales, realizará una única confirmación sin historial con el estado de su compra actual en cualquier sucursal actual y dejará todo lo demás sobre su repo sin tocar. A continuación, puede forzar a sus controles remotos a su gusto.