Me gustaría cambiar la base a un commit específico, no a un HEAD de la otra rama:
A --- B --- C master
\
\-- D topic
a
A --- B --- C master
\
\-- D topic
en vez de
A --- B --- C master
\
\-- D topic
¿Cómo puedo lograr eso?
git
version-control
rebase
git-rebase
Ondra Žižka
fuente
fuente

git checkout Bantes de corrergit rebase?rebasecomando son lo que importa.Respuestas:
Puede evitar el uso del parámetro --onto haciendo una rama temporal en el commit que desee y luego use rebase en su forma simple:
fuente
git rebase temp(cuando está en grupo ) se da por vencido con "Los grupos de sucursales actuales están actualizados".git rebase --onto <target> <from> <to>para poder especificar <from> commit.Incluso puedes tomar un enfoque directo:
fuente
topicycommitB.It works by going to the common ancestor of the two branches (the one you’re on and the one you’re rebasing onto), getting the diff introduced by each commit of the branch you’re on, saving those diffs to temporary files, resetting the current branch to the same commit as the branch you are rebasing onto, and finally applying each change in turn.lo intenté de nuevo ahora y parecía funcionar bien.m > n.Use la opción "sobre":
fuente
DyD^sería hash de la última y próxima a la última confirmación de "tema"?git rebase --onto <new-parent> <old-parent>. Consulte Configuración del puntero padre git a un padre diferente . En su caso, <nueva-parent> es B, y <pasada de padres> es A.git rebase --onto <commit-ID> mastergit rebase --onto master <commit-ID-of-old-parent>y para OPgit rebase --onto B A.El comentario de jsz anterior me ahorró un montón de dolor, así que aquí hay una receta paso a paso basada en ella que he estado usando para cambiar la base / mover cualquier confirmación encima de cualquier otra confirmación:
git rebase --onto <new parent> <old parent>En el ejemplo anterior, es tan simple como:
fuente
git rebase --onto B master, vea mi respuesta para una explicación más completa.Solución de tema
El comando correcto para responder la pregunta publicada podría ser cualquiera de los siguientes (suponiendo que la rama
topicya esté desprotegida):Si
topicno está desprotegido, simplemente agreguetopicel comando (excepto el último) así:Alternativamente, revise la sucursal primero con:
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:
<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:Para mover toda la rama de la característica, no se puede seleccionar
X,Y,Zofeaturecomo 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 esC,Domaster. 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>deB,C,D, omasterse traducirán en cometerBservir 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 ingresarmaster.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:
git rebase --onto D A featureSe aplicará compromete
B,C,X,Y,Zpara cometerDy terminan saltandoByCdebido a que ya se han aplicado.git rebase --onto C X featureAplicará commits
YyZcommitC, eliminando efectivamente commitXfuente
Una solución más simple es
git rebase <SHA1 of B> topic. Esto funciona independientemente de dóndeHEADesté.Podemos confirmar este comportamiento desde git rebase doc
Quizás esté pensando qué sucederá si también menciono SHA1
topicen el comando anterior.git rebase <SHA1 of B> <SHA1 of topic>Esto también funcionará, pero el rebase no hará referencia
Topica una nueva rama así creada yHEADestará en estado separado. Entonces, desde aquí, debe eliminar manualmente la antiguaTopicy crear una nueva referencia de rama en la nueva rama creada por rebase.fuente
He usado una mezcla de soluciones descritas anteriormente:
Me resultó mucho más fácil de leer y entender. La solución aceptada me llevó a un conflicto de fusión (demasiado flojo para arreglarlo a mano):
fuente
Dado que el rebase es tan fundamental, aquí hay una expansión de la respuesta de Nestor Milyaev . La combinación de los comentarios de jsz y Simon South de la respuesta de Adam Dymitruk produce este comando que funciona en la
topicrama independientemente de si se ramifica desde elmastercommit de la ramaAoC:Tenga en cuenta que se requiere el último argumento (de lo contrario, rebobina su rama para confirmar
B).Ejemplos:
Entonces, el último comando es el que normalmente uso.
fuente
Hay otra forma de hacerlo o si desea volver a más de un solo commit.
Aquí hay un ejemplo para volver a
nnúmero de confirmaciones:En aras de esta pregunta, esto también se puede hacer:
El comando funciona perfectamente
git version 2.7.4. No lo he probado en ninguna otra versión.fuente