È necessario utilizzare git rebase --onto
qui e specificare un intervallo.
(vedi git rebase
man page:
trapianto di un ramo argomento basa su un ramo all'altro, far finta che si biforcuta il ramo argomento da quest'ultimo ramo, usando rebase --onto
.).
Ovviamente questo sposterebbe il ramo bug10
in cima al ramo legacy
, che non è quello che si desidera/necessario.
Quindi, una soluzione potrebbe essere quella di fare che REBASE in un repo clonato, quindi unire che 'rafforzata' legacy
ramo (quello nel repository clone, con i bug10
modifiche su di esso) al locale e corrente legacy
ramo (quello che si desidera modificare, lasciando solo bug10
).
Ora:
- questo comporta un repo supplementare (che può portare a limitazioni di spazio su disco)
- nel complesso, questo è abbastanza equivalente a definire un cerotto e applicarlo a
legacy
ramo, per cui la altre risposte (patch) sono valide (e più semplici).
- l'unico vantaggio che vedo in questo metodo è la possibilità di definire un ambiente legacy in cui si rebase ciò che si vuole (come i
bug10
commit), prima di spingere solo quel ramo legacy
al tuo repo originale (che non avrebbe spingere bug10
, poiché la sua storia sarebbe stata interamente riscritta!)
Volevo solo vedere se funziona, quindi ... Proviamo questo approccio.
(Git1.6.5.1, su un vecchio XP SP2, con una sessione di PowerShell 1.0 a causa del 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
mi piace come io non ho più per rendere la directory git repo per prima cosa, quindi digita git init
! Since 1.6.5:
"git init
" hanno imparato a mkdir
/chdir
in una directory quando dato un argomento in più (vale a dire "git init this
").
Questo è FANTASTICO!
Creiamo 3 file, per 3 diversi scopi.
(Per motivi di esempio, terrò il file modifiche separano per sportello: nessun conflitto durante unione o rebase qui.)
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
A questo punto, un git log --graph --oneline --branches
rendimenti:
* b68c1f5 first evol, for making 1.0
* 93f9f7c first commit
Costruiamo un ramo 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"
torniamo al padrone, fare un altro commit, che verrà etichettare " 2.0" (! Un rilascio che avrà bisogno di un po 'di bug-fixing)
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
Abbiamo:
* 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
Ora facciamo un bug10
bug-fixing ramo:
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"
Aggiungiamo un commit finale sul ramo principale
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"
stato finale della nostra repo principale:
* 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
In questa fase, non farà alcuna ulteriore manipolazione in mainRepo. Lo clonerò solo per fare alcuni test. Se falliscono, posso sempre tornare a questo repo e clonarlo di nuovo.
Il primo clone è in realtà obbligatorio, al fine di eseguire il nostro git rebase --onto
PS D:\git\tests\mainRepo> cd ..
PS D:\git\tests> git clone mainRepo rebaseRepo
PS D:\git\tests> cd rebaseRepo
Abbiamo bisogno di due dei rami mainRepo nella nostra repo clonato:
PS D:\git\tests\rebaseRepo> git co -b bug10 origin/bug10
PS D:\git\tests\rebaseRepo> git co -b legacy origin/legacy
Diamo REBASE solo bug10 (che è tutto impegna dopo il tag 2.0
fino a HEAD
della filiale bug10
):
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
A questo punto bug10
è stato riprodotto in cima legacy
senza tutte le altre commit intermedi.
Ora è possibile inoltrare rapidamente HEAD
di legacy
nella parte superiore del ramo ripetuto bug10
.
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(-)
Il contenuto segui ciò che abbiamo bisogno:
- Noi abbiamo tutti i contenuti legacy:
PS D:\git\tests\rebaseRepo> type legacy.txt
legacyContent
aFirstLegacyEvol
- il contenuto del ramo
main
c'è solo fino 1.0
tag (root per legacy
ramo), e non ulteriormente.
PS D:\git\tests\rebaseRepo> type mainFile.txt
mainFile
firstMainEvol
- ei
bug10
correzioni sono qui:
PS D:\git\tests\rebaseRepo> type toBeFixedFile.txt
contentToBeFixed
aFirstBug10Fix
aSecondBug10Fix
Questo è tutto.
L'idea è quella di tirare che 'rafforzata' legacy
filiale nella vostra repo originale, che avrà ancora il suo bug10
immutato (vale a dire ancora a partire dal tag 2.0
, e non riprodotti ovunque come abbiamo fatto sul rebaseRepo
.
In questo repo clonato, rintraccio il ramo origin/legacy
, al fine di unire su di esso il ramo legacy
di un'altra fonte remota: il 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
In questo repository originale (Ho solo clonarono che per evitare di perdere lo stato del mainRepo, nel caso avevo alcuni altri esperimenti da fare), dichiarerò rebaseRepo
come un telecomando, e recuperare i suoi rami.
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
Ora possiamo aggiornare legacy
senza toccare 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(-)
È possibile ripetere la procedura tutte le volte che vuoi, ogni volta nuove bug10
commit devono essere riprodotti in cima ad un vecchio legacy
filiale, senza includere tutti i commit intermedi.
@Priyank: Sono d'accordo, la patch è più semplice. Ma il metodo che descrivo non è complesso. Illustra anche la facilità con cui è possibile clonare un repository e realizzare qualsiasi operazione Git che si desidera, a condizione che non si stia spingendo da lì. – VonC