Pieņemsim, ka mums ir šāda situācija sistēmā Git:
Izveidots repozitorijs:
mkdir GitTest2
cd GitTest2
git init
Tiek veiktas dažas izmaiņas galvenajā datubāzē, un tās tiek nodotas.
echo "On Master" > > fails
git commit -a -m "Sākotnējais commit"
Feature1 atdalīta no master un ir paveikts zināms darbs:
git filiāle feature1
git checkout feature1
echo "Feature1" > featureFile
git commit -a -m "Commit for feature1"
Tikmēr galvenajā kodā tiek atklāta kļūda, un tiek izveidots hotfix-branch.
git checkout master
git atzars hotfix1
git checkout hotfix1
Kļūda tiek labota hotfix filiālē un atkal apvienota ar master (iespējams, pēc pull pieprasījuma/kodeksa pārskatīšanas):
echo "Bugfix" > bugfixFile
git commit -a -m "Bugfix Commit"
git checkout master
git merge --no-ff hotfix1
Turpinās feature1 izstrāde:
turpināt turpināt darbu: git checkout feature1
Pieņemsim, ka man ir nepieciešams labojums savā feature atzarā, varbūt tāpēc, ka kļūda parādās arī tur. Kā es varu to panākt, nedublējot labojumus savā funkciju atzarā?
Es gribu novērst, ka manā funkciju atzarā parādās divas jaunas izmaiņas, kurām nav nekāda sakara ar funkciju ieviešanu. Tas man šķiet īpaši svarīgi, ja es izmantoju pull pieprasījumus: Visas šīs izmaiņas arī tiks iekļautas pull pieprasījumā, un tās būs jāpārskata, lai gan tas jau ir izdarīts (jo hotfix jau ir master).
Es nevaru veikt git merge master --ff-only
: "fatal: Not possible to fast-forward, aborting.", bet es neesmu pārliecināts, vai tas man palīdzēja.
Kā mēs varam apvienot galveno zaru ar funkciju zaru? Viegli:
git checkout feature1
git merge master
Šeit nav jēgas uzspiest ātru apvienošanu, jo to nav iespējams izdarīt. Jūs veicāt gan funkciju atzarā, gan galvenajā atzarā. Ātrā pāreja uz priekšu tagad nav iespējama.
Paskatieties GitFlow. Tas ir atzarojuma modelis git, kuru var ievērot, un jūs to neapzināti jau izdarījāt. Tas ir arī Git paplašinājums, kas pievieno dažas komandas jauniem darba plūsmas soļiem, kas automātiski veic lietas, kuras citādi būtu jādara manuāli.
Tātad, ko jūs savā darbplūsmā darījāt pareizi? Jums ir divas filiāles, ar kurām strādāt, jūsu filiāle feature1 būtībā ir "develop" filiāle GitFlow modelī.
Jūs izveidojāt hotfix zaru no master un apvienojāt to atpakaļ. Un tagad esat iestrēdzis.
GitFlow modelis pieprasa, lai jūs arī hotfix apvienotu ar attīstības zaru, kas jūsu gadījumā ir "feature1".
Tātad īstā atbilde būtu šāda:
git checkout feature1
git merge --no-ff hotfix1
Tas pievieno visas izmaiņas, kas tika veiktas karstajā labojumā, funkciju atzaram, bet tikai šīs izmaiņas. Tās var konfliktēt ar citām izstrādes izmaiņām šajā atzarā, bet tās nekonfliktēs ar galveno atzaru, ja pēc kāda laika atkal apvienosiet šo atzaru ar galveno.
Esiet ļoti uzmanīgi ar pārdalīšanu. Pārbāzējiet tikai tad, ja veiktās izmaiņas ir palikušas jūsu repozitorijā, piemēram, jūs neesat pārvietojis nevienu zaru uz kādu citu repozitoriju. Pārpublicēšana ir lielisks rīks, lai jūs varētu sakārtot lokālās izmaiņas noderīgā secībā pirms to izvietošanas pasaulē, taču pārpublicēšana pēc tam radīs haosu tādiem git iesācējiem kā jūs.
Jums vajadzētu būt iespējai pārbāzēt savu atzaru uz master:
git checkout feature1
git rebase master
Pārvaldiet visus radušos konfliktus. Kad jūs nonāksiet pie saistībām ar kļūdu labojumiem (kas jau ir master), Git paziņos, ka izmaiņu nav un ka tās varbūt jau ir piemērotas. Tad turpiniet pārbāzi (izlaižot master jau esošos kopijas), izmantojot
git rebase --skip
Ja veicat git log
uz sava funkciju atzara, jūs redzēsiet, ka kļūdu labojuma nodošana parādās tikai vienu reizi, turklāt master daļā.
Sīkāku informāciju var atrast Git grāmatas dokumentācijā par git rebase
(https://git-scm.com/docs/git-rebase), kurā aprakstīts tieši šis izmantošanas gadījums.
================ Rediģēt, lai iegūtu papildu kontekstu ====================
Šī atbilde tika sniegta īpaši uz @theomega uzdoto jautājumu, ņemot vērā viņa konkrēto situāciju. Pievērsiet uzmanību šai daļai:
Es gribu novērst [...] nodevumus savā funkcijas atzarā, kuriem nav nekāda sakara ar funkcijas īstenošanu.
Viņa privātā atzara atjaunošana uz master ir tieši tas, kas dos šādu rezultātu. Turpretī, apvienojot master viņa atzarā, tiktu izdarīts tieši tas, ko viņš īpaši nevēlas, lai notiktu: tiktu pievienotas izmaiņas, kas nav saistītas ar funkcijas īstenošanu, pie kuras viņš strādā savā atzarā.
Lai uzrunātu lietotājus, kuri izlasa jautājuma virsrakstu, izlaiž jautājuma faktisko saturu un kontekstu un pēc tam tikai akli izlasa augšējo atbildi, pieņemot, ka tā vienmēr attieksies uz viņu (atšķirīgo) lietošanas gadījumu, ļaujiet man paskaidrot sīkāk:
git merge master
, kā minēts @Sven'atbildē).Visbeidzot, ja jūs'esat neapmierināts ar to, ka šī atbilde nav vispiemērotākā jūsu situācijai, lai gan tā bija domāta @theomega, komentāra pievienošana zemāk nebūs īpaši noderīga: Es nekontrolēju, kura atbilde tiks izvēlēta, to dara tikai @theomega.
Iespējams, jūs varēsiet veikt "cherry-pick", lai ievilktu *pareizo(-ās) apņemšanos(-as), kas jums nepieciešama(-as), savā funkciju atzarā.
Veiciet git checkout hotfix1
, lai iekļūtu hotfix1 atzarā. Pēc tam veiciet git log
, lai iegūtu attiecīgās atkāpes SHA-1 hash (liela izlases burtu un ciparu virkne, kas unikāli identificē atkāpi). Nokopējiet šo kopiju (vai aptuveni pirmās 10 zīmes).
Pēc tam veiciet git checkout feature1
, lai atgrieztos savā funkciju atzarā.
Tad git cherry-pick <SHA-1 hash, ko tikko nokopējāt>
Tas ievilks šo un tikai šo nodevumu jūsu funkciju atzarā. Šī izmaiņa būs zarā - jūs to tikko "cherry-picked" ievācāt. Pēc tam atsāciet darbu, rediģējiet, apstipriniet, virziet utt. pēc sirds patikas.
Kad galu galā jūs veiksiet citu apvienošanu no vienas filiāles uz savu funkciju filiāli (vai otrādi), Git atpazīs, ka jūs jau esat apvienojis *to konkrēto izmaiņu, zinās, ka tā nav jāveic vēlreiz, un to vienkārši "izlaidīs".