Solución de tema
El comando correcto para responder la pregunta publicada podría ser cualquiera de los siguientes (suponiendo que la rama topic
ya esté desprotegida):
git rebase --onto B master
git rebase --onto master~1 master
git rebase --onto B A
git rebase --onto B C
git rebase --onto B
Si topic
no está desprotegido, simplemente agregue topic
el comando (excepto el último) así:
git rebase --onto B master topic
Alternativamente, revise la sucursal primero con:
git checkout topic
Rebase cualquier cadena de confirmaciones a una confirmación de destino
La forma básica del comando que necesitamos, basada en la documentación, es:
git rebase --onto <Target> [<Upstream> [<Branch>]]
<Branch>
es opcional y todo lo que hace es verificar la rama especificada antes de ejecutar el resto del comando. Si ya ha desprotegido la rama que desea cambiar, entonces no necesita esto. Tenga en cuenta que debe haber especificado <Upstream>
para especificar <Branch>
o git pensará que está especificando <Upstream>
.
<Target>
es la confirmación a la que adjuntaremos nuestra cadena de confirmaciones. Al proporcionar un nombre de sucursal, simplemente está especificando la confirmación principal de esa rama. <Target>
puede ser cualquier confirmación que no se incluirá en la cadena de confirmaciones que se mueven. Por ejemplo:
A --- B --- C --- D master
\
\-- X --- Y --- Z feature
Para mover toda la rama de la característica, no se puede seleccionar X
, Y
, Z
o feature
como el <Target>
ya que los todos son commits dentro del grupo que está siendo movido.
<Upstream>
es especial porque puede significar dos cosas diferentes. Si se trata de una confirmación que es un antepasado de la rama desprotegida, entonces sirve como punto de corte. En el ejemplo que he proporcionado, esto podría ser cualquier cosa que no es C
, D
o master
. Todos los commits posteriores <Upstream>
hasta el encabezado de la rama desprotegida son los que se moverán.
Sin embargo, si <Upstream>
no es un ancestro, entonces git realiza una copia de seguridad de la cadena desde el commit especificado hasta que encuentre un ancestro común con la rama desprotegida (y aborta si no puede encontrar uno). En nuestro caso, una <Upstream>
de B
, C
, D
, o master
se traducirán en cometer B
servir como punto de corte. <Upstream>
es en sí mismo un comando opcional y si no se especifica, entonces git mira al padre de la rama desprotegida que es el equivalente de ingresar master
.
Ahora que git ha seleccionado las confirmaciones que cortará y moverá, las aplicará para <Target>
omitir las que ya se hayan aplicado al objetivo.
Ejemplos y resultados interesantes
Usando este punto de partida:
A --- B --- C --- D --- E master
\
\-- X --- Y --- Z feature
git rebase --onto D A feature
Se aplicará compromete B
, C
, X
, Y
, Z
para cometer D
y terminan saltando B
y C
debido a que ya se han aplicado.
git rebase --onto C X feature
Aplicará commits Y
y Z
commit C
, eliminando efectivamente commitX
git checkout B
antes de corrergit rebase
?