133 votos

¿Insertar una confirmación antes de la confirmación de raíz en Git?

He preguntado acerca de cómo aplastar a los dos primeros se compromete en un repositorio git.

Mientras que las soluciones son bastante interesantes y no realmente como mente-deformación como algunas otras cosas en git, están todavía un poco de la proverbial bolsa de daño si es necesario repetir el procedimiento varias veces a lo largo del desarrollo de su proyecto.

Así que, prefiero ir a través del dolor sólo una vez y, a continuación, ser capaz de para siempre utilizar el interactivo estándar de reajuste.

Lo que yo quiero hacer, entonces, es tener un vacío inicial se comprometen a que existe con el único propósito de ser la primera. Ningún código, ni nada de nada. Sólo ocupa un espacio, por lo que pueden ser la base para reajuste.

Mi pregunta es, entonces, tener un repositorio existente, ¿cómo hago para insertar una nueva, vacía cometer antes de la primera, y el cambio de los demás hacia adelante?

180voto

Aristotle Pagaltzis Puntos 43253

He aquí un limpiador de aplicación de la misma solución, que funciona sin la necesidad de crear un repositorio adicional, preocuparte más por ahí con mandos a distancia, y corregir el desprendimiento de la cabeza:

# first you need a new empty branch; let's call it `newroot`
git checkout --orphan newroot
git rm -rf .

# then you apply the same steps
git commit --allow-empty -m 'root commit'
git rebase --onto newroot --root master
git branch -d newroot

Listo, has terminado en master con su historia reescrita para incluir un vacío de la raíz.


NB.: en las antiguas versiones de Git que carecen --orphan cambiar a checkout, usted necesita la instalación de cañerías para crear un vacío rama:

git symbolic-ref HEAD refs/heads/newroot
git rm --cached -r .
git clean -f -d

21voto

Antony Hatchkins Puntos 5831

La combinación de respuestas de Aristotle Pagaltzis y de Uwe Kleine-König y el comentario de Richard Bronosky.

git symbolic-ref HEAD refs/heads/newroot
git rm --cached -r .
git clean -f -d
# touch .gitignore && git add .gitignore # if necessary
git commit --allow-empty -m 'initial'
git rebase --onto newroot --root master
git branch -d newroot

(sólo para poner todo en un solo lugar)

7voto

Kent Puntos 304

Me gusta la respuesta de Aristóteles. Pero se encontró que para un repositorio de gran tamaño (>5000 confirma) filtro-de la rama funciona mejor que rebase por varias razones 1) es más rápido 2) no requiere la intervención humana, cuando hay un conflicto de combinación. 3) se pueden reescribir las etiquetas -- conservación de los mismos. Tenga en cuenta que el filtro de sucursal de obras porque no hay ninguna pregunta sobre el contenido de cada commit -- es exactamente la misma que antes de este 'reajuste'.

Mis pasos son:

# first you need a new empty branch; let's call it `newroot`
git symbolic-ref HEAD refs/heads/newroot
git rm --cached -r .
git clean -f -d

# then you apply the same steps
git commit --allow-empty -m 'root commit'

# then use filter-branch to rebase everything on newroot
git filter-branch --parent-filter 'sed "s/^\$/-p <sha of newroot>/"' --tag-name-filter cat master

Tenga en cuenta que los '--etiqueta-nombre-filtro de gato' opciones que significa que las etiquetas serán reescritos a punto para el recién creado se compromete.

5voto

Uwe Kleine-König Puntos 1020

git rebase --root --onto $emptyrootcommit

debe hacer el truco fácilmente

3voto

kch Puntos 25855

Bueno, aquí está lo que me ocurrió:

# Just setting variables on top for clarity.
# Set this to the path to your original repository.
ORIGINAL_REPO=/path/to/original/repository

# Create a new repository…
mkdir fun
cd fun
git init
# …and add an initial empty commit to it
git commit --allow-empty -m "The first evil."

# Add the original repository as a remote
git remote add previous $ORIGINAL_REPO
git fetch previous

# Get the hash for the first commit in the original repository
FIRST=`git log previous/master --pretty=format:%H  --reverse | head -1`
# Cherry-pick it
git cherry-pick $FIRST
# Then rebase the remainder of the original branch on top of the newly 
# cherry-picked, previously first commit, which is happily the second 
# on this branch, right after the empty one.
git rebase --onto master master previous/master

# rebase --onto leaves your head detached, I don't really know why)
# So now you overwrite your master branch with the newly rebased tree.
# You're now kinda done.
git branch -f master
git checkout master
# But do clean up: remove the remote, you don't need it anymore
git remote rm previous

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X