Estoy fallando en entender como usar git-rebase, y considero el siguiente ejemplo.
Vamos a empezar un repositorio en ~/tmp/repo:
$ git init
Luego agrega un archivo foo
$ echo "hello world" > foo
que luego se agrega y se compromete:
$ git add foo
$ git commit -m "Added foo"
A continuación, comencé un repositorio remoto. En ~/tmp/bare.git corrí
$ git init --bare
Para enlazar repo a bare.git corrí
$ git remote add origin ../bare.git/
$ git push --set-upstream origin master
A continuación, vamos a la rama, agregue un archivo y establezca un flujo ascendente para la nueva rama b1:
$ git checkout -b b1
$ echo "bar" > foo2
$ git add foo2
$ git commit -m "add foo2 in b1"
$ git push --set-upstream origin b1
Ahora es el momento de volver a master y cambiar algo allí:
$ echo "change foo" > foo
$ git commit -a -m "changed foo in master"
$ git push
En este punto en master el archivo foo Contiene cambiado foo , mientras en b1 aún es Hola Mundo . Finalmente, quiero sincronizar. b1 con el progreso realizado en master.
$ git checkout b1
$ git fetch origin
$ git rebase origin/master
En este punto git st devoluciones:
# On branch b1
# Your branch and 'origin/b1' have diverged,
# and have 2 and 1 different commit each, respectively.
# (use "git pull" to merge the remote branch into yours)
#
nothing to commit, working directory clean
En este punto el contenido de foo en la rama b1 es cambiar foo también. Entonces, ¿qué significa esta advertencia? Esperaba que hiciera una git push, Git sugiere hacer git pull... De acuerdo a esta respuesta , esto es más o menos eso, y en su comentario @FrerichRaabe dice explícitamente que no necesito hacer un tirón. ¿Que está pasando aqui? ¿Cuál es el peligro, cómo se debe proceder? ¿Cómo debe mantenerse la historia consistente? ¿Cuál es la interacción entre el caso descrito anteriormente y la siguiente cita:
No vuelva a marcar las confirmaciones que haya enviado a un repositorio público.
tomado de libro pro git .
Supongo que está relacionado de alguna manera, y si no me encantaría saber por qué. ¿Cuál es la relación entre el escenario anterior y el procedimiento que describí? en este post .
fuente

git stDa esa salida porque Git sabe que tu local.b1rama está siguiendoorigin/b1, así que eso es lo que quieres reajustar. Tu corresgit rebase origin/masterSin embargo, por lo que ha vuelto a basar ("repetido") sub1cometer encima deorigin/master.origin/masterymasterse actualizan, debería rebaseorigin/b1enorigin/mastery luego hacergit pullcuandob1¿Se verifica para extraer el rebase al repositorio local?git pully nunca rebasa una rama remota (por ejemplo,origin/master) en cualquier otra cosa.origin/b1yb1no son lo mismo. Esto es bastante obvio, pero ¿cuál es la forma correcta de solucionarlo? ¿O arreglarlo significa desordenar la historia como se explicó @heavyd?Respuestas:
La razón por la que no desea volver a generar las confirmaciones que ha enviado a un repositorio público es porque
git-rebaseEl comando cambia la historia.Ahora, ¿qué significa eso y por qué es malo? Primero, sugeriría leer esta sección del libro git. A partir de eso, aprenderá que las confirmaciones consisten en un puntero a un objeto de árbol (instantánea de los archivos) y un puntero a la confirmación principal. Ahora, cuando "cambia el historial" volviendo a basar las confirmaciones sobre las nuevas confirmaciones, está cambiando el puntero principal de las confirmaciones que ya ha realizado, lo que a su vez cambia el ID de sus confirmaciones.
La razón por la que esto es malo es que si comparte sus compromisos públicamente, y otros comienzan un trabajo adicional basado en esos compromisos, luego realiza un cambio en esos compromisos, sus árboles ya no están sincronizados.
Todo esto se puede ver emitiendo
git-logComandos mientras realizas tu ejemplo. Corrí estos justo antes de ejecutar el comando rebase:Y ahora después de realizar la rebase,
origin/masteryorigin/b1son lo mismo, perob1es ahora:Notará que la confirmación "foo2 agregado en b1" tiene una ID diferente a la de los comandos de registro anteriores. Si confirma este cambio en su repositorio público, ahora tiene dos confirmaciones que tienen el mismo trabajo realizado en ellos y eso causa problemas.
Ahora suponga que, en lugar de volver a basar b1 en la parte superior del maestro, simplemente fusionó el maestro en b1, su registro se vería así:
Notará la confirmación adicional que representa la combinación de las dos confirmaciones anteriores. Esta historia ahora puede ser compartida y todos serán felices.
git-log --graphTambién puede ayudar a arrojar algo de luz adicional sobre lo que está sucediendo.fuente
origin/b1solo lo uso yo mismo - asumiendo que es una especie de respaldo deb1. ¿Qué efecto tiene este supuesto sobre la situación? ¿Tiene sentido en este caso hacer?git push --force¿O algo similar justo después de la rebase?git merge mastercuando elfooLa sucursal está desprotegida. De nuevo, pruébalo por ti mismo y usagit-logpara ver que esta pasandomasterSe considera una rama estable mientras quefoo(o cualquier otra rama) no es estable. La fusión de estable en inestable es indeseable, por lo tanto, el trabajo adicional. Estoy tratando de averiguar si hay accesos directos o no.Tarde en la fiesta, pero aquí está la respuesta para la posteridad:
git rebaseestá destinado a ser utilizado localmente. Reescribe el historial, lo que permite una "línea principal" muy agradable, pero es peligroso en un entorno multiusuario.Si:
Entonces eso podría tiene sentido hacer esto por forzando La historia a reescribir. Haga su rebase y luego:
Si alguna de estas suposiciones no se cumplió, puede vivir para lamentar esta acción :-)
Lee más en esta entrada de blog
fuente