Entendiendo y memorizando los parámetros de git rebase

8

Hasta ahora, la parte más confusa de git se está basando en otra rama. Específicamente, son los argumentos de la línea de comando los que son confusos.

Cada vez que quiero volver a colocar una pequeña parte de una rama en la punta de otra, tengo que revisar la documentación de git rebase y me lleva entre 5 y 10 minutos entender qué deben ser cada uno de los 3 argumentos principales.

git rebase <upstream> <branch> --onto <newbase>

¿Cuál es una buena regla general para ayudarme a memorizar a qué se debe configurar cada uno de estos 3 parámetros, dado cualquier tipo de rebase en otra rama?

Tenga en cuenta que he revisado la documentación de git-rebase una y otra vez, una y otra vez y otra vez (y otra vez), pero siempre es difícil de entender (como un aburrido documento científico o algo así). Entonces, en este punto, siento que necesito involucrar a otras personas para que me ayuden a comprenderlo.

Mi objetivo es que nunca debería tener que revisar la documentación para estos parámetros básicos. No he podido memorizarlos hasta ahora, y ya he hecho un montón de rebases. Por lo tanto, es un poco raro que haya podido memorizar todos los demás comandos y sus parámetros hasta ahora, pero no se ha vuelto a generar con --onto .

    
pregunta void.pointer 25.03.2014 - 14:31

2 respuestas

7

Vamos a omitir --onto por el momento. upstream y branch son bastante básicos, y en realidad son una especie de mímica checkout y branch . El segundo argumento es opcional:

git branch <newbranch>
git branch <newbranch> <base>
git checkout -b <newbranch>
git checkout -b <newbranch> <base>
git rebase <upstream>
git rebase <upstream> <branch>

(Además, los nombres de estos argumentos en rebase , "upstream" y "branch" no son muy descriptivos de IMO. Por lo general, pienso en ellos como peachoftree, <start> y <end> , que es como los usaré: git rebase <start> <end> )

Cuando se omite la segunda rama, el resultado es casi el mismo que la primera comprobación de esa rama y luego hacerlo como si no hubiera especificado esa rama. La excepción es branch que no cambia su rama actual:

git checkout <base> && git branch <newbranch> && git checkout <previous_branch>
git checkout <base> && git checkout -b <newbranch>
git checkout <end>  && git rebase <start>

En cuanto a la comprensión de lo que hace rebase cuando se invoca, primero comencé a pensar en ello como un tipo especial de fusión. En realidad no lo es, pero ayudó cuando empezamos a entender el rebase. Para tomar prestado el ejemplo de peachoftree:

A--B--F--G master
    \
     C--D--E feature

Un git merge master resulta en esto:

A--B--F-----G master
    \        \
     C--D--E--H feature

Mientras que un get rebase master (mientras está en la rama feature !) resulta en esto:

A--B--F--G master
          \
           C'--D'--E' feature

En ambos casos, feature ahora contiene el código de master y feature . Si no estás en feature , el segundo argumento se puede usar para cambiar a él como acceso directo: git rebase master feature hará lo mismo que arriba.

Ahora, para el especial --onto . La parte importante a recordar con esto es que por defecto es <start> si no se especifica. Así que arriba, si especificé --onto específicamente, esto resultaría en lo mismo:

git rebase --onto master master
git rebase --onto master master feature

(No uso --onto sin especificar <end> simplemente porque es más fácil de analizar mentalmente, incluso si esos dos son los mismos si ya están en feature .)

Para ver por qué --onto es útil, aquí hay un ejemplo diferente. Digamos que estaba en feature y noté un error, que luego comencé a corregir, pero por error se bifurcaron% feature en lugar de master :

A--B--F--G master
    \
     C--D--E feature
            \
             H--I bugfix

Lo que quiero es "mover" estas confirmaciones para bugfix para que ya no dependan de feature . Tal como está, cualquier tipo de fusión o rebase que se muestra arriba en esta respuesta tomará los tres feature confirmados junto con los dos bugfix confirmados.

Por ejemplo, git rebase master bugfix es incorrecto. El rango <start> a <end> incluye todas las confirmaciones de feature , que se repiten encima de master :

A--B--F--G master
    \     \
     \     C'--D'--E'--H'--I' bugfix
      \
       C--D--E feature

Lo que realmente queremos es que el rango de confirmaciones de feature a bugfix se reproduzca encima de master . Eso es lo que --onto es para: especificar un objetivo de "reproducción" diferente al de la rama "inicio":

git rebase --onto master feature bugfix

A--B--F--G master
    \     \
     \     H'--I' bugfix
      \
       C--D--E feature
    
respondido por el Izkata 29.06.2014 - 06:18
1

Solo una actualización, la rebasación es principalmente para cuando desea que su historial de confirmaciones parezca lineal si dos ramas se han desarrollado de forma independiente, básicamente reescribe el historial de confirmaciones.

la forma en que me gusta hacerlo es git rebase --onto <target branch> <start branch> <end branch>

donde <target branch> es la rama a la que está rebasando, <start branch> es normalmente la rama desde la cual <end branch> split y <end branch> es la rama a la que está rebasando.

si empiezas con

A--B--F--G master
    \
     C--D--E feature

y hazlo

git rebase --onto master master feature

obtendrás

A--B--F--G master
          \
           C'--D'--E' feature

Otra cosa buena que se debe saber es que <target branch> por defecto es <start branch> para que puedas hacer la misma rebase que

git rebase --onto master feature

Si necesita más ayuda, consulte la Guía de Rebase sin desgarros

    
respondido por el peachoftree 26.03.2014 - 00:18

Lea otras preguntas en las etiquetas