Perkelkite paskutinį (-ius) įvykį (-us) į naują filialą su „Git“

Norėčiau perkelti paskutinius kelis įsipareigojimus, kuriuos aš padariau, kad galėčiau užimti naują filialą, ir grąžinti kapitoną prieš tai, kai buvo įvykdyti šie įsipareigojimai. Deja, mano git -fu vis dar nėra pakankamai stipri, bet kokia pagalba?

t.y. Kaip aš galiu eiti iš to

 master A - B - C - D - E 

tai?

 newbranch C - D - E / master A - B 
3467
27 окт. Nustatė Mark A. Nicolosi 27 spalis 2009-10-27 06:07 '09, 06:07 am. 2009-10-27 06:07
@ 8 atsakymai

Eikite į naują filialą

Jei nėra kitų aplinkybių, tai gali būti lengvai padaryta padalinus ir nustojus veikti atgal.

 git reset --hard a1b2c3d4 

* 1 tik „praranda“ pagrindinio filialo įsipareigojimą, tačiau nesijaudinkite, tai turėsite įsipareigoti naujojoje šakoje!

ĮSPĖJIMAS: jei naudojate Git 2.0 versiją ir vėlesnę versiją, jei vėliau git rebase naujas filialas į pradinį filialą ( master ), pertraukos metu jums gali reikėti aiškios - --no-fork-point , kad neprarastumėte nešiojamų įsipareigojimų. branch.autosetuprebase always nustatomas branch.autosetuprebase always buvimas leidžia greičiau. Daugiau informacijos rasite John Mellor .

Eikite į esamą filialą

ĮSPĖJIMAS: aukščiau aprašytas metodas veikia, nes kuriate naują filialą su pirmąja komanda: git branch newbranch . Jei norite naudoti esamą filialą , prieš atlikdami git reset --hard HEAD~3 turite sujungti savo pakeitimus į esamą filialą . Jei pirmiausia neprisijungsite savo pakeitimų, jie bus prarasti. Taigi, jei dirbate su esamu filialu, tai atrodys taip:

4382
27 окт. atsakymas duotas sykora 27 okt. 2009-10-27 06:15 '09 6:15 am 2009-10-27 06:15

Tiems, kurie stebisi, kodėl jis veikia (kaip buvau pradžioje):

Jūs norite grįžti į C ir perkelti D ir E į naują filialą. Štai kaip tai atrodo pirmiausia:

 ABCDE (HEAD) ↑ master 

Po git branch newBranch :

border=0
  newBranch ↓ ABCDE (HEAD) ↑ master 

Po git reset --hard HEAD~2 :

  newBranch ↓ ABCDE (HEAD) ↑ master 

Kadangi filialas yra tik rodyklė, kapitonas nurodė paskutinį įvykį. Sukūrę naują filialą, jūs tiesiog padarėte naują rodiklį į paskutinį įvykį. Tada, naudodami git reset , pagrindinį rodiklį perkėlėte atgal į du. Bet kadangi jūs neperkėlėte naujo filialo, jis vis dar nurodo, kad jis buvo padarytas.

801
23 июля '11 в 1:37 2011-07-23 01:37 atsakymą pateikė Ryan Lundy, liepos 23 d., 11:37, 2011-07-23 01:37

Apskritai ...

Šiuo atveju geriausias variantas yra atviras sykoros metodas. Tačiau kartais tai nėra paprasčiausias ir labiausiai paplitęs metodas. Dėl bendro metodo naudokite git cherry-pick:

Norint pasiekti norimą OP, tai yra dviejų pakopų procesas:

1 žingsnis - pastaba, kuria nustatomas reikalingas kapitonas newbranch

Vykdyti

 git checkout master git log 

Atkreipkite dėmesį, kad maišos (pvz., 3) prisiima jus prie newbranch . Čia aš naudosiu:
C įsipareigojimas: 9aa1233
D įsipareigojimas: 453ac3d
E įsipareigojimas: 612ecb3

Pastaba . Galite naudoti pirmuosius septynis simbolius arba visą įvykio maišą.

2 žingsnis. Įdėkite juos į newbranch

 git checkout newbranch git cherry-pick 612ecb3 git cherry-pick 453ac3d git cherry-pick 9aa1233 

ARBA (1.7.2+ pav., Naudokite intervalus)

 git checkout newbranch git cherry-pick 612ecb3~1..9aa1233 

„git cherry-pick“ taiko šiuos tris įsipareigojimus naujokai.

315
07 февр. Atsakyti Ivan 07 Feb. 2012-02-07 19:58 '12, 19:58, 2012-02-07 19:58

Kitas būdas tai padaryti yra tik 2 komandos. Taip pat saugo jūsų dabartinį darbo medį.

 git checkout -b newbranch # switch to a new branch git push . +HEAD~3:master # make master point to some older commit 

Galimybė push . - tai geras triukas.

Vėliau redagavimas: dabar, kai žinau apie git branch -f , teisingas būdas tai padaryti yra:

 git checkout -b newbranch # switch to a new branch git branch -f master HEAD~3 # make master point to some older commit 

Tas pats, bet mažiau „magiškas“

235
26 марта '14 в 11:13 2014-03-26 11:13 atsakymas pateikiamas aragėlio kovo 26 d. 14 val. 11:13 2014-03-26 11:13

Dauguma ankstesnių atsakymų yra pavojingai klaidingi!

NENAUDOKITE:

 git reset --keep HEAD~3 git checkout -t -b newbranch git cherry-pick ..HEAD@{2} 
  • Pirma, jis išmeta paskutinius 3 įsipareigojimus (- --hard yra panašus į --hard , bet yra saugesnis, nes jis nepavyksta, o ne mesti nekomercinius pakeitimus).
  • Tada jis išjungia newbranch .
  • Tada jis vyšnios, kad šios trys sugrįžtų į newbranch . Kadangi jie nebėra nuorodos į šaką, tai daro su git reflog : HEAD@{2} yra pataisa, kurią HEAD naudoja norėdama nukreipti iki 2 operacijų atgal, t.y. prieš mes 1. patikrinome newbranch ir 2. naudojome git reset kad atsisakytumėte 3.

Įspėjimas: „reflog“ yra įjungtas pagal numatytuosius nustatymus, tačiau jei jį išjungėte rankiniu būdu (pvz., Naudojant „be git“ saugyklą), negalėsite gauti 3 git reset --keep HEAD~3 po to, kai paleisite „Git git reset --keep HEAD~3 .

Alternatyva, kuri nesiremia reflogu, yra:

 git branch -t newbranch git reset --hard HEAD~3 git checkout newbranch 

tai, kad jie palieka reflogą netinkamai. „ newbranch mato newbranch kaip šakotą šaką iki pat redagavimo, kuris apima 3 įsipareigojimus, tada reset --hard kad pašalintų ankstesnę istoriją, kad pašalintumėte įsipareigojimus, taigi kitą kartą paleidus git rebase jis sumažina juos kaip ir bet kurį kitą pašalinta iš viršaus.

Tačiau šiuo konkrečiu atveju norime, kad šios 3 fiksacijos būtų laikomos temos temos dalimi. Norint tai pasiekti, turime atsisakyti jo ankstesnėje versijoje, kurioje nėra 3 įsipareigojimų. Būtent tai daro mano siūlomi sprendimai, todėl jie abu palieka atspindį teisingai.

Išsamesnės informacijos rasite --fork-point apibrėžtyje git perkeliant ir git sujungimo bazėje .

179
07 апр. John Mellor atsakymas balandžio 07 d 2016-04-07 01:38 '16, 13:38 pm 2016-04-07 01:38

Tai ne „perkelia“ juos technine prasme, bet turi tą patį poveikį:

 A--B--C (branch-foo) \ ^-- I wanted them here! \ D--E--F--G (branch-bar) ^--^--^-- Opps wrong branch! While on branch-bar: $ git reset --hard D # remember the SHAs for E, F, G (or E and G for a range) A--B--C (branch-foo) \ \ D-(E--F--G) detached ^-- (branch-bar) Switch to branch-foo $ git cherry-pick E..G A--B--C--E'--F'--G' (branch-foo) \ E--F--G detached (This can be ignored) \ / D--H--I (branch-bar) Now you won't need to worry about the detached branch because it is basically like they are in the trash can waiting for the day it gets garbage collected. Eventually some time in the far future it will look like: A--B--C--E'--F'--G'--L--M--N--... (branch-foo) \ \ D--H--I--J--K--.... (branch-bar) 
26
19 окт. Atsakymą pateikė Sukima spalio 19 d. 2013-10-19 17:12 '13, 17:12, 2013-10-19 17:12

Norėdami tai padaryti be perrašymo istorijos (t. Y. Jei jau paspaudėte įsipareigojimus):

 git checkout master git revert <commitID(s)> git checkout -b new-branch git cherry-pick <commitID(s)> 

Abi šakos gali būti spaudžiamos be pastangų!

17
21 янв. atsakymas teh_senaus 21 sausis 2016-01-21 19:10 '16 at 19:10 2016-01-21 19:10

Jei tokia padėtis:

 Branch one: ABCDEFJLM \ (Merge) Branch two: GIKN 

Aš baigiau:

 git branch newbranch git reset --hard HEAD~8 git checkout newbranch 

Tikiuosi, kad pataisa bus HEAD, bet įsipareigoti L dabar ...

Jei norite nusileisti reikiamoje vietoje istorijoje, tai lengviau dirbti su pasišventimu.

 git branch newbranch git reset --hard ######### git checkout newbranch 
11
20 сент. atsakymas, kurį pateikė Darkglow 20 Sep 2013-09-20 13:17 '13, 13:17, 2013-09-20 13:17