Saltemos --ontopor el momento. upstreamy branchson bastante básicos, y en realidad son una especie de imitación checkouty 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>
(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 branchque 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 entender qué rebasehace 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--B--F--G master
\
C--D--E feature
A git merge masterresulta en esto:
A--B--F-----G master
\ \
C--D--E--H feature
Mientras que un git rebase master(¡mientras está en la rama feature!) Da como resultado esto:
A--B--F--G master
\
C'--D'--E' feature
En ambos casos, featureahora contiene código de ambos mastery feature. Si no está activado feature, el segundo argumento se puede usar para cambiar a él como un acceso directo: git rebase master featurehará 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é --ontoespecíficamente, esto resultaría en lo mismo:
git rebase --onto master master
git rebase --onto master master feature
(No uso --ontosin especificar <end>simplemente porque es más fácil analizar mentalmente, incluso si esos dos son iguales si ya están activados feature).
Para ver por qué --ontoes útil, aquí hay un ejemplo diferente. Digamos que estaba encendido featurey noté un error, que luego comencé a solucionar, pero que se bifurcó en featurelugar de masterpor error:
A--B--F--G master
\
C--D--E feature
\
H--I bugfix
Lo que quiero es "mover" estas confirmaciones para bugfixque ya no dependan de ellas feature. Tal como está, cualquier tipo de fusión o rebase que se muestra arriba en esta respuesta tomará los tres featurecommits junto con los dos bugfixcommits.
Por ejemplo, git rebase master bugfixestá mal. La gama <start>de <end>pasa a incluir todas las confirmaciones de featureque se reproducen en la parte superior de master:
A--B--F--G master
\ \
\ C'--D'--E'--H'--I' bugfix
\
C--D--E feature
Lo que realmente queremos es el rango de confirmaciones de featureque bugfixpara que se reproduzca en la parte superior de master. Para eso --ontoestá: especificar un objetivo de "repetició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