Debe usar git rebase --onto
aquí y especifique un rango.
(ver git rebase
man page:
trasplante de una rama tema basa en una rama a otra, para pretender que la rama bifurcada tema de esta última rama, usando rebase --onto
.).
Por supuesto, esto movería su rama bug10
en la parte superior de la rama legacy
, que no es lo que quiere/necesita.
lo tanto, una solución sería hacer que rebase en un acuerdo de recompra clonado, luego la fusiona 'mejorada' legacy
rama (el que está en el repositorio clon, con los bug10
modificaciones en la parte superior de la misma) a lo local y la rama legacy
actual (la que desea modificar, dejando bug10
solo).
Ahora:
- esto implica una cesión temporal adicional (que puede conducir a la limitación de espacio en disco)
- todo en todos, esto es bastante equivalentes para definir un parche y aplicarlo a
legacy
rama, por lo que la otras respuestas (parche) son válidas (y más simples).
- la única ventaja que veo en este método es la oportunidad de definir un entorno heredado en el que rebase lo que desea (como las confirmaciones
bug10
), antes de enviar solo esa rama legacy
a su repositorio original (no presionaría bug10
, ya que su historia habría sido completamente reescrita!)
Solo quería ver si funciona, así que ... Pongamos a prueba ese enfoque.
(Git1.6.5.1, en un viejo XP SP2, con una sesión de PowerShell 1.0 debido a la Start-Transcript
command)
PS D:\> mkdir git
PS D:\> cd git
PS D:\git> mkdir tests
PS D:\git> cd tests
PS D:\git\tests> git init mainRepo
me gusta la forma en que no tengo más para hacer el directorio git repo primero, ¡entonces escríbalo git init
! Since 1.6.5:
"git init
" aprendieron a mkdir
/chdir
en un directorio cuando se le da un argumento extra (es decir, "git init this
").
¡Esto es GENIAL!
Creemos 3 archivos, para 3 propósitos diferentes.
(Por el bien de ejemplo, voy a mantener el archivo de modificaciones separan por sucursal: ningún conflicto durante la fusión o rebase aquí.)
PS D:\git\tests> cd mainRepo
PS D:\git\tests\mainRepo> echo mainFile > mainFile.txt
PS D:\git\tests\mainRepo> echo contentToBeFixed > toBeFixedFile.txt
PS D:\git\tests\mainRepo> echo legacyContent > legacy.txt
PS D:\git\tests\mainRepo> git add -A
PS D:\git\tests\mainRepo> git ci -m "first commit"
PS D:\git\tests\mainRepo> echo firstMainEvol >> mainFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "first evol, for making 1.0"
PS D:\git\tests\mainRepo> git tag -m "1.0 legacy content" 1.0
En este punto, un git log --graph --oneline --branches
rendimientos:
* b68c1f5 first evol, for making 1.0
* 93f9f7c first commit
vamos a construir una rama legacy
PS D:\git\tests\mainRepo> git co -b legacy
PS D:\git\tests\mainRepo> echo aFirstLegacyEvol >> legacy.txt
PS D:\git\tests\mainRepo> git ci -a -m "a first legacy evolution"
volvemos al maestro, haga otra confirmación, que vamos a etiquetar " 2.0" (! Un comunicado de que se necesita un poco de corrección de errores)
PS D:\git\tests\mainRepo> git co -b master
PS D:\git\tests\mainRepo> git co master
PS D:\git\tests\mainRepo> echo aMainEvol >> mainFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "a main evol"
PS D:\git\tests\mainRepo> echo aSecondMainEvolFor2.0 >> mainFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "a second evol for 2.0"
PS D:\git\tests\mainRepo> git tag -m "main 2.0 before bugfix" 2.0
Tenemos:
* e727105 a second evol for 2.0
* 473d44e a main evol
| * dbcc7aa a first legacy evolution
|/
* b68c1f5 first evol, for making 1.0
* 93f9f7c first commit
Ahora hacemos un bug10
corrección de errores rama:
PS D:\git\tests\mainRepo> git co -b bug10
PS D:\git\tests\mainRepo> echo aFirstBug10Fix >> toBeFixedFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "a first bug10 fix"
PS D:\git\tests\mainRepo> echo aSecondBug10Fix >> toBeFixedFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "a second bug10 fix"
Añadamos una confirmación final en la rama principal
PS D:\git\tests\mainRepo> git co master
PS D:\git\tests\mainRepo> echo anotherMainEvol >> mainFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "another main evol"
Estado final de nuestro repositorio principal:
* 55aac85 another main evol
| * 47e6ee1 a second bug10 fix
| * 8183707 a first bug10 fix
|/
* e727105 a second evol for 2.0
* 473d44e a main evol
| * dbcc7aa a first legacy evolution
|/
* b68c1f5 first evol, for making 1.0
* 93f9f7c first commit
En esta etapa, no hará ninguna manipulación adicional en mainRepo. Solo lo clonaré para hacer algunas pruebas. Si eso falla, siempre puedo volver a este repositorio y clonarlo nuevamente.
El primer clon en realidad es obligatoria, con el fin de llevar a cabo nuestra git rebase --onto
PS D:\git\tests\mainRepo> cd ..
PS D:\git\tests> git clone mainRepo rebaseRepo
PS D:\git\tests> cd rebaseRepo
Necesitamos dos de las ramas mainRepo en nuestro repositorio clonado:
PS D:\git\tests\rebaseRepo> git co -b bug10 origin/bug10
PS D:\git\tests\rebaseRepo> git co -b legacy origin/legacy
Vamos rebase solamente bug10 (que es todo confirma después de 2.0
etiqueta hasta HEAD
de bug10
rama):
PS D:\git\tests\rebaseRepo> git co bug10
PS D:\git\tests\rebaseRepo> git rebase --onto legacy 2.0
First, rewinding head to replay your work on top of it...
Applying: a first bug10 fix
Applying: a second bug10 fix
En este punto bug10
se ha repetido en la parte superior de legacy
sin todos los demás realiza poco.
Ahora podemos avanzar rápidamente HEAD
de legacy
a la parte superior de la rama bug10
reproducida.
PS D:\git\tests\rebaseRepo> git co legacy
Switched to branch 'legacy'
PS D:\git\tests\rebaseRepo> git merge bug10
Updating dbcc7aa..cf02bfc
Fast forward
toBeFixedFile.txt | Bin 38 -> 104 bytes
1 files changed, 0 insertions(+), 0 deletions(-)
El contenido sigue lo que necesitamos:
- Tenemos todo el contenido antiguo:
PS D:\git\tests\rebaseRepo> type legacy.txt
legacyContent
aFirstLegacyEvol
- el contenido de la rama
main
es no sólo hasta 1.0
etiqueta (raíz para legacy
rama), y no más lejos.
PS D:\git\tests\rebaseRepo> type mainFile.txt
mainFile
firstMainEvol
- y las correcciones son
bug10
aquí:
PS D:\git\tests\rebaseRepo> type toBeFixedFile.txt
contentToBeFixed
aFirstBug10Fix
aSecondBug10Fix
Eso es todo.
La idea es lograr eso 'mejorada' legacy
sucursal en tu repositorio original, que todavía tendrá su bug10
sin cambios (es decir, aún partiendo de la etiqueta 2.0
, y no reproducidos en cualquier lugar como lo hicimos en el rebaseRepo
.
En este repo clonado, sigo la rama origin/legacy
, para unirme a él la rama legacy
de otra fuente remota: rebaseRepo
.
PS D:\git\tests\rebaseRepo> cd ..
PS D:\git\tests> git clone mainRepo finalRepo
PS D:\git\tests> cd finalRepo
PS D:\git\tests\finalRepo> git co -b legacy origin/legacy
En este repo originales (que sólo se clonó a no meterse con el estado de la mainRepo, en caso de que tuviera algunos otros experimentos a realizar), Anunciaré rebaseRepo
como un control remoto, a buscar sus ramas.
PS D:\git\tests\finalRepo> git remote add rebasedRepo D:/git/tests/rebaseRepo
PS D:\git\tests\finalRepo> type D:\git\tests\finalRepo\.git\config
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = D:/git/tests/mainRepo
[branch "master"]
remote = origin
merge = refs/heads/master
[branch "legacy"]
remote = origin
merge = refs/heads/legacy
[remote "rebasedRepo"]
url = D:/git/tests/rebaseRepo
fetch = +refs/heads/*:refs/remotes/rebasedRepo/*
PS D:\git\tests\finalRepo> git fetch rebasedRepo
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 6 (delta 3), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From D:/git/tests/rebaseRepo
* [new branch] bug10 -> rebasedRepo/bug10
* [new branch] legacy -> rebasedRepo/legacy
* [new branch] master -> rebasedRepo/master
Ahora podemos actualizar legacy
sin tocar a bug10
:
PS D:\git\tests\finalRepo> git merge rebasedRepo/legacy
Updating dbcc7aa..4919b68
Fast forward
toBeFixedFile.txt | Bin 38 -> 104 bytes
1 files changed, 0 insertions(+), 0 deletions(-)
puede repetir el proceso tantas veces como desee, siempre nuevas bug10
compromete necesitan ser reproducido en la parte superior de un viejo legacy
rama, sin incluir todas las confirmaciones intermedias.
@Priyank: Estoy de acuerdo, el parche es más simple. Pero el método que describo no es complejo. También ilustra la facilidad con la que puedes clonar un repositorio y realizar cualquier operación de Git que desees, siempre que no estés presionando desde allí. – VonC