Kako selektivno združiti ali izbrati spremembe iz druge veje v sistemu Git?
Uporabljam sistem git pri novem projektu, ki ima dve vzporedni - vendar trenutno eksperimentalni - razvojni veji:
master
: uvoz obstoječe baze kode in nekaj modifikacij, o katerih sem na splošno prepričanexp1
: eksperimentalna veja #1exp2
: eksperimentalna veja #2
exp1
in exp2
predstavljata dva zelo različna arhitekturna pristopa. Dokler ne pridem še dlje, ne morem vedeti, kateri (če sploh kateri) bo deloval. Ko napredujem v eni veji, včasih imam popravke, ki bi bili uporabni v drugi veji, in bi rad združil le te.
**Kateri je najboljši način za združitev izbranih sprememb iz ene razvojne veje v drugo, pri čemer ostane vse drugo?
Pristopi, o katerih sem razmišljal:
-
git merge --no-commit
, ki mu sledi ročno odstranjevanje velikega števila sprememb, za katere ne želim, da bi bile skupne med vejami. -
Ročno kopiranje skupnih datotek v začasni imenik, ki mu sledi
git checkout
za premik v drugo vejo, nato pa še eno ročno kopiranje iz začasnega imenika v delovno drevo. -
Različica zgornjega načina. Za zdaj opustite veje
exp
in uporabite dve dodatni lokalni shrambi za eksperimentiranje. Tako je ročno kopiranje datotek veliko bolj preprosto.
Vsi trije pristopi se zdijo zamudni in nagnjeni k napakam. Upam, da obstaja boljši pristop; nekaj podobnega parametru poti za filtriranje, ki bi naredil git-merge
bolj selektiven.
Z ukazom cherry-pick pridobite posamezne revizije iz ene veje.
Če želene spremembe niso v posameznih revizijah, uporabite tukaj prikazano metodo razdelitev revizije na posamezne revizije. V grobem uporabite
git rebase -i
, da dobite prvotno oddajo za urejanje, natogit reset HEAD^
za selektivno vračanje sprememb, natogit commit
za oddajo tega dela kot nove oddaje v zgodovino.Tu je še ena lepa metoda v Red Hat Magazine, kjer uporabljajo
git add --patch
ali mordagit add --interactive
, ki omogoča dodajanje samo delov hunka, če želite razdeliti različne spremembe na posamezno datoteko (na tej strani poiščite "split").Ko ste razdelili spremembe, lahko zdaj izberete le tiste, ki jih želite.
Zgornji pristopi mi niso všeč. Uporaba cherry-pick je odlična za izbiro ene spremembe, vendar je boleča, če želite vnesti vse spremembe, razen nekaterih slabih. Tukaj je moj pristop.
Ni argumenta `--interaktivno´, ki bi ga lahko posredovali programu git merge.
Tukaj je alternativa:
imate nekaj sprememb v veji 'feature' in želite nekatere, vendar ne vse, prenesti v vejo 'master' na način, ki ne bi bil površen (tj. ne želite izbrati in oddati vsake od njih).
Zato to preprosto zapakirajte v lupinsko skripto, spremenite master v $to in spremenite feature v $from in lahko začnete:
1800 INFORMACIJA'odgovor je popolnoma pravilen. Kot git noob pa "use git cherry-pick" ni bilo dovolj, da bi to ugotovil brez malo več brskanja po internetu, zato sem mislil, da bom objavil podrobnejši vodnik, če je še kdo v podobni situaciji.
Moj primer uporabe je bil, da sem želel selektivno prenesti spremembe iz neke druge veje githuba v svojo vejo. Če že imate lokalno vejo s spremembami, morate opraviti le korake 2 in 5-7.
Ustvarite (če še niste ustvarili) lokalno vejo s spremembami, ki jih želite vnesti.
$ git branch mybranch
Preklopite vanjo.
$ git checkout mybranch
Z računa druge osebe prenesite želene spremembe. Če jih še niste dodali, jih dodajte kot oddaljene.
$ git remote add repos-w-changes
Iz njihove veje prenesite vse, kar potrebujete.
$ git pull repos-w-changes branch-i-want
Oglejte si dnevnike sprememb in ugotovite, katere spremembe želite:
$ git log
Preklopite nazaj na vejo, v katero želite prenesti spremembe.
$ git checkout originalbranch
Svoje spremembe po vrsti izberite s pomočjo hashev.
$ git cherry-pick -x hash-of-commit
Nasvet: http://www.sourcemage.org/Git_Guide