git: Empujar Comisiones simples, Reorderar con rebase, Compromisos duplicates

Quiero enviar varias confirmaciones individuales a un repository remoto de git. Seguí la respuesta de Geoff que encontré aquí para hacerlo:

¿Cómo puedo enviar una confirmación específica a un control remoto y no a las confirmaciones anteriores?

Los commits que quiero enviar no están a la cabeza, así que tengo que reorderar los commits usando rebase primero y usé estas instrucciones para hacerlo:

http://gitready.com/advanced/2009/03/20/reorder-commits-with-rebase.html

Esencialmente lo he hecho:

git clone git commit git commit ... git pull git rebase -i HEAD~3 git push origin <SHA>:master 

Tengo errores al hacer esto. Entonces comencé a profundizar en el problema. Descubrí que hay confirmaciones duplicadas en mi logging si hago una segunda extracción de git después de la rebase, por ejemplo:

 git clone git commit git commit ... git pull git log --pretty=format:"%h - %an : %s" // log before rebasing git rebase -i HEAD~3 git pull git log --pretty=format:"%h - %an : %s" // log after rebasing git pull git log --pretty=format:"%h - %an : %s" // log after rebasing after pulling 

Así que publiqué esta pregunta:

git: Complicaciones duplicadas después de una rebase local seguida de pull

La respuesta de Roger me llevó a esta pregunta: ¿Por qué veo duplicates después de volver a basar y tirar?

Desde arriba, el logging antes de volver a basar se ve así:

 84e4015 - Me : Local Commit 3 0dbe86a - Me : Local Commit 2 d57ba2a - Me : Merge branch 'master' of remote repository a86ea35 - Me : Local Commit 1 before reordering 2fc4fe7 - Remote User 2 : Remote Commit 2 b7a8656 - Remote User 1 : Remote Commit 1 8ce80fc - Me : Merge branch 'master' of remote repository 

Y el logging después de rebase se ve así:

 cf1ff7b - Me : Local Commit 3 cd14463 - Me : Local Commit 2 b9d44fb - Me : Local Commit 1 after reordering 9777c56 - Remote User 2 : Remote Commit 2 a2d7d8b - Remote User 1 : Remote Commit 1 8ce80fc - Me : Merge branch 'master' of remote repository 

Observe que los 2 commits originales 2fc4fe7 y b7a8656 tienen nuevos SHA; 9777c56 y a2d7d8b. Creo que este es el comienzo del problema.

Ahora, después de hacer otro git pull, el logging se ve así:

 e8e1a85 - Me : Merge branch 'master' of remote repository cf1ff7b - Me : Local Commit 3 cd14463 - Me : Local Commit 2 b9d44fb - Me : Local Commit 1 after reordering 9777c56 - Remote User 2 : Remote Commit 2 a2d7d8b - Remote User 1 : Remote Commit 1 2fc4fe7 - Remote User 2 : Remote Commit 2 // duplicate 2 b7a8656 - Remote User 1 : Remote Commit 1 // duplicate 1 8ce80fc - Me : Merge branch 'master' of remote repository 

Observe que los commit remotos ahora están duplicates y que los SHA originales de los commits remotos, 2fc4fe7 y b7a8656, han regresado.

En la respuesta de Roger, él dijo que parecía ser culpa de otras personas que empujaban a Git y que estaban reescribiendo sus compromisos ya empujados. Pero creo que es mi culpa reescalonar localmente un compromiso empujado.

¿Esto es porque reescribí una confirmación que ya había sido enviada al control remoto? Si es así, ¿qué debería haber hecho para evitar esto? Necesito rebase mis commits para poder enviar un commit único. ¿Debería haber usado un sistema de ramificación para hacer esto? Si es así, ¿cómo usaría las twigs para resolver este problema?

La respuesta corta es que rebase no cambia commits, 1 sino que los copy. Git normalmente oculta los originales, pero si los originales incluyen los compartidos por otros usuarios, usted (y, por supuesto, ellos) todavía ven esos originales.

Como regla general, solo debe modificar sus propias confirmaciones privadas e inéditas. Dado que nadie más tiene una copy de estos por definición, el hecho de que usted haga sus propias copys y luego (a través de rebase) esconda sus originales no es un problema: ahora ve sus copys en lugar de sus originales, y nadie más ve tampoco, y puede continuar rebase si es necesario. Sin embargo, tan pronto como publique (a través de push o similar) una confirmación, ya no podrá cambiarla, porque otra persona ahora tiene una copy de su original, incluida su identificación SHA-1, y aún la tendrá más tarde.

Lo que ha hecho en este caso es volver a establecer una base (es decir, copyr) sus compromisos, así como los suyos. Parte del problema radica en el uso de git pull , que significa "search y luego fusionar", cuando lo que quería era "search y luego rebase". Puede hacer los pasos por separado:

 git fetch git rebase 

o use git pull --rebase :

 git pull --rebase 

que le dice al script de pull que después de hacer la búsqueda, debería hacer una rebase en lugar de una fusión. También puede configurar git para hacer esto automáticamente, sin el argumento --rebase . 2

El principal problema en este momento es que tienes una fusión que probablemente no quisiste. Si es así, deberá "deshacer" esa combinación (con el git reset , ver otras publicaciones de stackoverflow).


1 No puede: un object git, que incluye un compromiso, se nombra por su ID de object, que es una sum de control criptográfica de su contenido. Un commit está compuesto por su (s) ID (s) principal (es), el ID del tree, el autor y el committer (nombre, correo electrónico e indicación de date y hora) del commit y el post de confirmación. Si cambias alguno de estos, obtienes un compromiso nuevo y diferente con una ID diferente.

2 Incluso puede configurarlo para usar git pull --rebase=preserve . Sin embargo, la preservación de las fusiones en las operaciones de rebase es un tema aparte (que ya he tratado anteriormente en las publicaciones de stackoverflow).

    Intereting Posts