Dos preguntas:
Estoy tratando de poner una confirmación antes de que TODOS se comprometan.
La confirmación inferior tiene 660fb2a76211f36ec9a67d0454a90eab469e9fd0
como SHA. Cuando git rebase -i 660fb2a76211f36ec9a67d0454a90eab469e9fd0
cada confirmación, pero la última aparece en la list.
Realmente necesito este compromiso para aparecer, así que puedo poner el primer compromiso como el último!
Cuando pongo el primer commit como primero en la list (es decir, segundo commit en total, porque el primero no está en la list como se mencionó anteriormente) me sale un error: error: could not apply b722c76... v1.4.3 BEAT release
¡Simplemente lo corté del final de la list y lo puse en la cima! ¡No cambié el número!
También intenté esto varias veces. El mismo resultado.
Eso es todo hasta ahora. Si tiene preguntas, ¡adelante y pregunte!
Acabo de descubrir viejas copys de security de mi proyecto. Estas copys de security se crearon antes de usar git.
Ahora me gustaría agregarlos a mi repository como commits antiguos. Eso significaría que tengo que poner estos commit en frente de todos los commits.
Ahora hay varios problemas con esto:
Si algo no está claro, por favor mencionarlo. ¡Solucionaré el problema entonces!
Una última cosa:
Lo publiqué en GitHub. Y utilicé principalmente su software para comprometer compromisos. Entonces, ¿cómo puedo volver a enviar esto a GitHub?
Encontré otra manera, un poco más simple de hacer esto, usando la bandera --root
de git rebase
. Lo probé con un repository mío, así que sé que funciona (al less para una historia completamente lineal , más sobre eso al final).
Vamos a jugar seguro y hacer una copy de security, en caso de que terminemos haciendo algo desastroso y perdiendo sus datos:
git clone original-repo backup-repo
Verifica la sucursal huérfana. Especificar una confirmación / bifurcación de punto de inicio es opcional, si deja ese argumento fuera, entonces Git utilizará por defecto su confirmación actual como punto de inicio (sigue el patrón de la syntax de bifurcación estándar):
git checkout --orphan new-master firstCommitOfOldMaster
Especifiqué la raíz del antiguo maestro como punto de inicio, porque probablemente hará que el siguiente paso sea más rápido (eliminando los files del directory de trabajo).
La creación de la twig huérfana new-master
de su antiguo maestro podría dejar atrás los files en su directory e índice de trabajo, dependiendo de cuál era el estado de los files en la confirmación de la cual participó:
El índice y el tree de trabajo se ajustan como si previamente hubiera ejecutado
git checkout <start_point>
. Esto le permite iniciar un nuevo historial que registra un set de routes similares a<start_point>
ejecutandogit commit -a
para realizar la confirmación de raíz. – Documentos de pago de git
Lo que querrás hacer ahora es borrar por completo el estado de la twig, para que realmente comiences de nuevo desde cero (ejecuta desde la carpeta de nivel superior):
git rm -rf .
Esta es la explicación de los documentos:
Si desea iniciar un historial desconectado que registra un set de routes que es totalmente diferente de la de
<start_point>
, entonces debe borrar el índice y el tree de trabajo inmediatamente después de crear la twig huérfana ejecutandogit rm -rf .
desde el nivel superior del tree de trabajo. Después, estará listo para preparar sus nuevos files, repoblar el tree de trabajo, copyrlos de otro lugar, extraer un tarball, etc.
new-master
Ahora querrá comenzar a comprometer su trabajo anterior en el new-master
. Cuando termines, volverás a ubicar tu antiguo maestro en la parte superior.
No estoy exactamente seguro de cómo están organizadas las carpetas de respaldo, pero supongo que cada una de ellas es solo una copy dateda de la carpeta de su proyecto, nombrada en YYYY-MM-DD
, por ejemplo, 2013-01-30
. Puede agregar los contenidos de cada carpeta como una nueva confirmación manualmente, o puede escribir una secuencia de commands para automatizar el process.
Supongamos que tiene todas sus carpetas de respaldo en una carpeta superior llamada backup
que se encuentra en el mismo directory que la carpeta principal del proyecto. Luego, aquí hay un pseudocódigo para una secuencia de commands para automatizar el process de confirmación de cada carpeta:
# Get backups and sort them from oldest to newest backups = open("backups").toList().sort("date ascending") for each (backup in backups) copy files from backup to project folder execute `git add "*"` execute `git commit --date="#{backup.date}" --message="#{backup.date}"`
El script anterior solo agregará y modificará files entre commits. Si cualquiera de sus copys de security elimina, mueve o cambia el nombre de los files, el script no registrará eso. Tendrá que escribir un script más inteligente para hacer eso (tal vez algo que haga uso de git diff
u otra herramienta diferente) o grabar esos cambios manualmente.
master
en el new-master
¡HE AQUÍ EL IMPRESIONANTE PODER QUE ES GIT! ¡Ahora vamos a REESCRIBIR TU HISTORIA COMPLETA! Recita estas arcanas palabras de poder y observa cómo sucede la magia !:
git rebase --onto new-master --root master
TA-DA! Puede que tenga que resolver conflictos entre la última confirmación de new-master
y la primera confirmación de master
, pero aparte de eso, ¡debería ser!
El indicador --root
to rebase
soluciona el problema que teníamos antes sobre el hecho de que, normalmente, rebase
no funcionará en la primera confirmación (raíz) de un repository de Git. La bandera --root
básicamente le dice a Git que la incluya en la rebase
:
Rebase todos los commits accesibles desde
<branch>
, en lugar de limitarlos con un<upstream>
. Esto le permite volver a establecer la base de la (s) confirmación (es) raíz (es) en una twig. Cuando se utiliza con--onto
, omitirá los cambios que ya están contenidos en<newbase>
(en lugar de<upstream>
) mientras que sin--onto
funcionará en cada cambio. – Rebase docs
Solo para asegurarnos de no desorderar el código, querremos comparar el estado actual y final del master
con su estado antes de hacer la rebase
. Cualquiera de los siguientes commands funcionará (son idénticos). Mientras estás en la twig master
:
git diff orig_head # "Original" head git diff master@{1} # Master at its 1st prior position
Si no obtienes salida del diff
, significa que el estado final de tu master
rebasado es idéntico a lo que era antes de la rebase
. ¡Buen trabajo!
Ahora los pasos anteriores funcionarán bien si tienes un historial perfectamente lineal , es decir, no tienes ningún commit de fusión. No estoy seguro de si funcionará si lo hace. En mi respuesta anterior a continuación, mencioné que usar el --preserve-merges
con rebase
podría ayudarlo a mantener esas fusiones, pero los documentos mencionan que ese indicador también interactúa con los --onto
y --root
:
Cuando [
--root
es] utilizado junto con--onto
y--preserve-merges
, todas las confirmaciones de raíz se reescribirán para tener<newbase>
como principal en su lugar. – Rebase docs
No estoy exactamente seguro de lo que eso significa en este momento … Podría tener que probarlo y ver qué pasa. ¿Significa que si tienes más de 1 confirmación raíz (como 10, por ejemplo), entonces 9 de esas confirmaciones raíz terminarán siendo reorderadas en la última que actúa como la nueva raíz? Eso no parece el comportamiento que quisiéramos. Solo queremos preservar las confluencias de fusión para que una raíz se vuelva a basar en otra.
MGA tuvo la idea correcta con rebase
. No estoy seguro de si esto solucionará tu problema, pero tal vez necesites hacer una nueva confirmación de raíz en tu repository, agregar tus files de copy de security como nuevos commits encima, y luego networkingistribuir tu antiguo gráfico de commit en la parte superior.
Por ejemplo, el git checkout
tiene una bandera --orphan
según la documentation :
--orphan <new_branch>
Cree una nueva sucursal huérfana, denominada<new_branch>
, iniciada desde<start_point>
y cambie a ella. El primer compromiso realizado en esta nueva twig no tendrá padres y será la raíz de una nueva historia totalmente desconectada de todas las otras twigs y compromisos.
Entonces quizás puedas probar
git checkout --orphan <temp_branch>
Luego, envíe sus files de respaldo a él. Luego, con temp_branch
desprotegido, hazlo
git cherry-pick <first commit from master> git rebase --onto temp_branch <first commit from master> master
Creo que probablemente necesites cherry-pick
el primer commit porque el segundo argumento para rebase --onto
es la antigua base de la twig que quieres volver a establecer (en este caso, master
), y la base anterior no está incluida. Así que es por eso que creo que debes cherry-pick
para getlo, ya que no tiene una base de compromiso, por lo que no puedes especificar uno en la base de rebase
.
También tenga en count que si su historial de compromisos no es lineal (es decir, tiene compromisos de fusión), entonces la rebase
normalmente no los conservará. Tiene una bandera --preserve-merges
, pero nunca la he usado antes, así que no estoy seguro de cómo funcionará. De los documentos :
-p
--preserve-merges
En lugar de ignorar las fusiones, intente recrearlas.Esto utiliza la maquinaria
--interactive
internamente, pero combinarla con la opción--interactive
explícita generalmente no es una buena idea a less que sepa lo que está haciendo (consulte los ERRORES a continuación).
Entonces, ¿quizás todo eso funcionará?
1) Puedes usar git rebase
. En este caso, podrías hacer lo siguiente:
Lo primero es lo primero, cometer los cambios anteriores. Entonces:
$ git rebase --interactive master
Esto abrirá un file con sus confirmaciones en un editor de text. Simplemente cambie el order de los commits (corte / pegue sus últimos commits para ser los primeros, incluido el command "pick" a la izquierda), guarde y cierre el editor. En este punto comenzará la rebase. Para continuar cuando le soliciten confirmación, escriba:
$ git rebase --continue
Hasta que todo esté hecho. Más información aquí .
2) No conozco ningún método para hacerlo más rápido, pero ya debería ser bastante rápido.
3) Para cambiar la date de una confirmación, debe cambiar GIT_AUTHOR_DATE y GIT_COMMITTER_DATE. Para esto, hay un bonito ejemplo en la respuesta aceptada para esta pregunta de StackOverflow .
¡Espero eso ayude!