Hasta ahora, la parte más confusa de git es rebase en otra rama. Específicamente, son los argumentos de la línea de comandos los que son confusos.
Cada vez que quiero volver a crear una pequeña parte de una rama en la punta de otra, tengo que revisar la documentación de git rebase y me lleva unos 5-10 minutos entender cuáles deberían ser los tres 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 libro blanco científico aburrido 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 de 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 inusual que haya podido memorizar todos los demás comandos y sus parámetros hasta ahora, pero no rebase --onto
.
Respuestas:
Saltemos
--onto
por el momento.upstream
ybranch
son bastante básicos, y en realidad son una especie de imitacióncheckout
ybranch
- el segundo argumento es opcional:(Aparte, los nombres de estos argumentos en
rebase
"rama", "aguas arriba" y no son muy descriptivos OMI Me suelen pensar en ellos como peachoftree,.<start>
Y<end>
, que es lo que va a utilizar ellos:git rebase <start> <end>
)Cuando se omite la segunda rama, el resultado es casi el mismo que primero verificando esa rama y luego haciéndolo como si no hubiera especificado esa rama. La excepción es
branch
que no cambia su rama actual:En cuanto a entender qué
rebase
hace cuando se invoca, primero comencé a pensar en ello como un tipo especial de fusión. En realidad no lo es, pero ayudó cuando comencé a entender rebase. Para tomar prestado el ejemplo de peachoftree:A
git merge master
resulta en esto:Mientras que un
git rebase master
(¡mientras está en la ramafeature
!) Da como resultado esto:En ambos casos,
feature
ahora contiene código de ambosmaster
yfeature
. Si no está activadofeature
, el segundo argumento se puede usar para cambiar a él como un acceso directo:git rebase master feature
hará lo mismo que antes.Ahora, para el especial
--onto
. La parte importante a recordar con esto es que su valor predeterminado es<start>
si no se especifica. Entonces, si especifiqué--onto
específicamente, esto resultaría en lo mismo:(No uso
--onto
sin especificar<end>
simplemente porque es más fácil analizar mentalmente, incluso si esos dos son iguales si ya están activadosfeature
).Para ver por qué
--onto
es útil, aquí hay un ejemplo diferente. Digamos que estaba encendidofeature
y noté un error, que luego comencé a solucionar, pero que se bifurcó enfeature
lugar demaster
por error:Lo que quiero es "mover" estas confirmaciones para
bugfix
que ya no dependan de ellasfeature
. Tal como está, cualquier tipo de fusión o rebase que se muestra arriba en esta respuesta tomará los tresfeature
commits junto con los dosbugfix
commits.Por ejemplo,
git rebase master bugfix
está mal. La gama<start>
de<end>
pasa a incluir todas las confirmaciones defeature
que se reproducen en la parte superior demaster
:Lo que realmente queremos es el rango de confirmaciones de
feature
quebugfix
para que se reproduzca en la parte superior demaster
. Para eso--onto
está: especificar un objetivo de "repetición" diferente al de la rama "inicio":git rebase --onto master feature bugfix
fuente
Solo un repaso, el rebase es principalmente para cuando desea que su historial de confirmación parezca lineal si dos ramas se han desarrollado independientemente una de la otra, básicamente reescribe el historial de confirmación.
la forma en que me gusta hacerlo es
git rebase --onto <target branch> <start branch> <end branch>
¿Dónde
<target branch>
está la rama sobre la que está rebasando?<start branch>
Normalmente es la rama de la que se<end branch>
divide y<end branch>
es la rama sobre la que está rebase.si comienzas con
y hacer
conseguirás
Otra cosa buena que debes saber es que el valor
<target branch>
predeterminado es<start branch>
para que puedas hacer ese mismo rebase quesi necesita más ayuda, consulte la guía Rebase sin lágrimas
fuente
master
rama en sí sin cambios. Solo obtienes 'característica' para ramificarse comoG--C'--D'--E'
mientrasmaster
todavía se detiene enG
.<target branch>
y qué<start branch>
son diferentes para ayudar a los lectores a comprender el caso más general?