Pregunta ¿Hace que la confirmación actual sea la única confirmación (inicial) en un repositorio de Git?


Actualmente tengo un repositorio local de Git, que llevo a un repositorio de Github.

El repositorio local tiene ~ 10 commits, 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 local de Git, de modo que los contenidos actuales del repositorio aparezcan como el único compromiso (y, por lo tanto, las versiones anteriores de los archivos del repositorio no se almacenan).

Entonces me gustaría llevar estos cambios a Github.

Investigué la rebase de Git, pero parece ser más adecuada para eliminar versiones específicas. Otra posible solución es eliminar el repositorio local y crear uno nuevo, ¡aunque esto probablemente genere mucho trabajo!

ETA: hay directorios / archivos específicos que no se han rastreado; si es posible, me gustaría mantener el seguimiento de estos archivos.


507
2018-03-13 11:41


origen


Respuestas:


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, debe usar, p. rebase interactivo

Paso 1: eliminar todo el historial (Asegúrate de tener una copia de seguridad, esto no se puede revertir)

rm -rf .git

Paso 2: reconstruye el repositorio de Git con solo el contenido actual

git init
git add .
git commit -m "Initial commit"

Paso 3: presiona a GitHub.

git remote add origin <github-uri>
git push -u --force origin master

802
2017-10-27 18:16



La única solución que funciona para mí (y hace que los submódulos funcionen) 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

Eliminando .git/ siempre causa grandes problemas cuando tengo submódulos. Utilizando git rebase --root de alguna manera causaría conflictos para mí (y tomará mucho tiempo, ya que tenía mucha historia).


448
2018-03-22 13:53



Este es mi enfoque favorito:

git branch new_branch_name $(echo "commit message" | git commit-tree HEAD^{tree})

Esto creará una nueva rama con una confirmación que agrega todo en HEAD. No altera nada más, por lo que es completamente seguro.


67
2018-03-14 20:24



La otra opción, que podría resultar un montón de trabajo si tienes muchas confirmaciones, es una rebase interactiva (suponiendo que tu versión de git sea> = 1.7.12):git rebase --root -i

Cuando se le presente una lista de confirmaciones en su editor:

  • Cambiar "pick" a "reword" para el primer commit
  • Cambia "pick" a "fixup" cada dos commit

Guardar y cerrar. Git comenzará a rebasar.

Al final, tendrías una nueva confirmación raíz que es una combinación de todas las que vinieron después.

La ventaja es que no tiene que eliminar su repositorio y, si tiene dudas, siempre tiene una alternativa.

Si realmente quieres nukear tu historial, restablece el maestro a este compromiso y elimina todas las demás ramas.


29
2018-04-19 08:58



Variante de larsmansmétodo propuesto por

Guarde su lista de untrackfiles:

git ls-files --others --exclude-standard > /tmp/my_untracked_files

Guarde su configuración de git:

mv .git/config /tmp/

A continuación, realice los primeros pasos de larsmans:

rm -rf .git
git init
git add .

Restaure su configuración:

mv /tmp/config .git/

Destrabar los archivos sin seguimiento:

cat /tmp/my_untracked_files | xargs -0 git rm --cached

Entonces cometer:

git commit -m "Initial commit"

Y finalmente empuje a su repositorio:

git push -u --force origin master

15
2018-03-12 14:53



Cree una bifurcación, copie todos los contenidos, comprométala y luego elimine la rama principal:

git checkout --orphan newBranch; git add -A ;git commit -am 'first commit' ;git branch -D master;git branch -m master; git push -f origin master; git gc --aggressive --prune=all

6
2018-04-04 11:05



Podría usar superficial clones (git> 1.9):

git clone --depth depth remote-url

Otras lecturas: http://blogs.atlassian.com/2014/05/handle-big-repositories-git/


5
2018-02-06 16:46



El siguiente método es exactamente reproducible, por lo que no es necesario volver a ejecutar el clon si ambos lados son consistentes, solo ejecuta el script en el otro lado 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 la historia" para cada rama en el repositorio:

http://sam.nipl.net/b/git-kill-history

ver también: http://sam.nipl.net/b/confirm


2
2018-04-05 01:42



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 ramas y etiquetas locales, hará una única confirmación sin historial con el estado de su pago actual en cualquier sucursal que esté actualizada y dejará intacto todo lo demás sobre su depósito. A continuación, puede forzar empujar a sus controles remotos como desee.


1
2018-04-04 11:27