Sākums
» Pamatzināšanas
»
Kā novērst kļūdu “Git Push noraidīts: nepārtīšana uz priekšu”, nezaudējot izmaiņas
Kā novērst kļūdu “Git Push noraidīts: nepārtīšana uz priekšu”, nezaudējot izmaiņas
Noraidījums bez ātrās pārtīšanas uz priekšu ir Git vēstures aizsardzība, nevis jūsu lokālā darba dzēšana. Tas parasti nozīmē, ka attālā filiāle ir pārvietojusies uz priekšu pēc jūsu lokālās filiāles pēdējās sinhronizācijas, tāpēc, atjauninot attālo filiāli ar jūsu pašreizējo filiāli, tiktu atmesti tur jau esošie grozījumi. GitHub pašreizējā dokumentācijā ir aprakstīta tā pati situācija: vispirms izgūstiet augšupējās izmaiņas, integrējiet tās lokāli un pēc tam veiciet atkārtotu izmaiņu izdarīšanu.
Drošākā vispārējā darbplūsma ir šāda: aizsargāt jebkuru neizpildīto darbu, ielādēt attālo atzaru, nemodificējot pašreizējo atzaru, pārbaudīt, kā atšķīrās vēstures, izvēlēties apvienošanu vai atkārtotu bāzi, nepieciešamības gadījumā atrisināt konfliktus un vēlreiz ielādēt. Nesākt ar vai git push --forcetikai git reset --hardtāpēc, lai kļūda pazustu.
Pieņemsim, ka jūsu lokālajā mainatzarā ir commit L, bet attālajā atzarā origin/mainir pārejot uz citu commit R. Ja neviens no commit failiem nav otra priekštecis, vēstures ir atšķīrušās. Parasta pārvietošana nevar vienkārši pārvietot attālā atzara rādītāju uz , Lnepazūdot Rno šīs atzara redzamās vēstures.
Ātri veikts atjauninājums ir citādāks: jaunā atzara gals ir vecā pēctecis, tāpēc, pārvietojot atzaru uz priekšu, tiek saglabāts viss, kas no tā jau ir sasniedzams. Oficiālajā git pushrokasgrāmatā ir definēts šis izcelsmes noteikums un brīdināts, ka --forcetas atspējo parasto aizsardzību un var izraisīt attālinātu izmaiņu zudumu.
Noraidījums bez ātrās pārtīšanas nozīmē, ka Git atsakās aizstāt attālo vēsturi, kuras jūsu lokālajā filiālē vēl nav.
Pirms jebkādu darbību veikšanas: vai jūsu lokālais darbs ir droši reģistrēts?
Palaist:
git status
Ja darba koks ir tīrs, jūsu pašreizējās izmaiņas jau ir attēlotas ar grozījumiem, un pirms tālvadības integrēšanas varat izveidot papildu drošības atsauci:
git branch backup-before-sync
Šī filiāle norāda uz pašreizējo izmaiņu, tāpēc jums ir vienkāršs nosaukums pirms integrācijas stāvoklim.
Ja jums ir modificēti vai izsekoti faili, kas nav apstiprināti, pirms datu ieguves vai bāzes maiņas izvēlieties vienu no šīm metodēm:
Ievietojiet tos komandā, ja darbs ir loģiski gatavs komandā ievietošanai.
Noglabājiet tos, ja darbs ir nepabeigts git stash push -u -m "before non-fast-forward fix":.
Šī -uopcija ietver neizsekotus failus. Oficiālajā git-stash dokumentācijā ir paskaidrots, ka krātuve reģistrē darba direktoriju un indeksa stāvokli un atjauno tīru darba koku. Ignorētie faili netiek iekļauti ar -u; -aiekļautu arī ignorētos failus, taču tas reti ir nepieciešams šīs problēmas risināšanai.
Svarīgi: ja git statustiek parādīti faili, kurus nevarat atļauties pazaudēt, neizpildiet git reset --hard. Šī komanda var atmest neapstiprinātās darba koka izmaiņas.
1. darbība. Vai jums vajadzētu lietot git pullnekavējoties?
Varat, bet “fetch first” ir vieglāk izskaidrot . GitHub dokumenti, kas git fetchlejupielādē attālināto darbu un atjaunina attālinātās izsekošanas zarus, neapvienojot šīs izmaiņas ar pašreizējo zaru. Tas padara to par noderīgu diagnostikas soli, jo varat pārbaudīt situāciju pirms lokālās vēstures maiņas.
Pēc ielādes attālās izsekošanas atzars origin/mainattēlo tikko izgūto attālo stāvokli. Log komanda ļauj redzēt izmaiņas, kas sasniedzamas tikai no lokālās puses un tikai no attālās puses.
Ja jūsu lokālajā filiālē nav unikālu izmaiņu un tā vienkārši atpaliek, bieži vien varat to ātri pārtīt uz priekšu:
git merge --ff-only origin/main
Tad nav nekā, ko saskaņot; jūsu atzars vienkārši virzās uz priekšu.
2. darbība. Apvienošana vai atkārtota bāzes izveide — kuru izvēlēties?
Abi var saglabāt jūsu veiktās izmaiņas. Atšķirība ir iegūtās vēstures formā.
Situācija
Parasti izvēlas
Kāpēc
Koplietota filiāle, piemēram, mainkur jūsu lokālie grozījumi jau var būt zināmi citiem
Apvienot
Saglabā esošās izmaiņu identitātes un nepārraksta jūsu lokālos izmaiņu ierakstus.
Jūsu izdarītie grozījumi ir lokāli/privāti, un jūs vēlaties lineāru vēsturi.
Pārbāzēt
Atkārtoti atskaņo jūsu lokālos izmaiņu ierakstus (commits) atjauninātajā attālajā atzarā.
Jūs neesat pārliecināts un vēlaties pēc iespējas mazāk pārrakstīt vēsturi
Apvienot
Tas ir vieglāk izskaidrojams un drošāks kopīgai vēsturei.
Apvienot maršrutu
git fetch origin
git merge origin/main
Ja nav konfliktu, Git pabeidz integrāciju. Ja zari patiešām atšķīrās, rezultātā var tikt veikta apvienošanas komanda.
Pārbāzēt maršrutu
git fetch origin
git rebase origin/main
Funkcija Rebase ņem jūsu pašreizējai filiālei unikālos izmaiņu ierakstus (commit) un atkārtoti piemēro tos origin/main. Git pārbāzes dokumentācijā tā ir aprakstīta kā virknes izmaiņu ierakstu (commit) pārstādīšana uz citu sākuma punktu. Tā kā šīm izmaiņām tiek piešķirti jauni izmaiņu ID, funkciju Rebase vislabāk izmantot lokālam darbam, kas vēl nav koplietots kā publiska vēsture.
Ja vēlaties saīsni, git pull --rebase origin mainveic ielādi, kam seko atkārtota bāzes izveide, savukārt git pull --no-rebase origin mainskaidri izvēlas apvienošanas darbību. Atkopšanas situācijā atsevišķas fetchun merge/ rebasekomandas bieži vien ir skaidrākas, jo vispirms varat pārbaudīt attālo stāvokli.
Pēc attālo izmaiņu izgūšanas tās apzināti integrējiet — apvienojot vai pārveidojot —, nevis pārrakstot.
3. darbība. Kā rīkoties, ja Git ziņo par konfliktu?
Konflikts nenozīmē, ka jūsu izmaiņas ir pazudušas. Tas nozīmē, ka Git nevar automātiski izlemt, kā apvienot izmaiņas vienā un tajā pašā saturā.
Vispirms pārbaudiet valsti:
git status
Atveriet katru konfliktējošo failu, izlemiet, kādam jābūt galīgajam saturam, noņemiet konflikta marķierus un pēc tam izveidojiet atrisinātā faila stadiju:
git add path/to/file
Ja izvēlējāties apvienošanu, pabeidziet apvienošanu pēc visu konfliktu iesākšanas:
git commit
Ja izvēlējāties atkārtotu bāzi, turpiniet atkārtot savus izmaiņu ierakstus:
git rebase --continue
Ja atkārtota bāzes izveide norit slikti un vēlaties atgriezt filiāli tās pirms atkārtotas bāzes izveides stāvoklī, izmantojiet:
git rebase --abort
Pašreizējā Git pārbāzes rokasgrāmata īpaši dokumentē --continueun --abortšim nolūkam. Neizmantojiet git rebase --skiptikai konflikta novēršanai, ja vien jūs patiešām neplānojat izlaist atkārtotu izmaiņu veikšanu.
Vispirms atrisiniet saturu, izveidojiet laboto failu un pēc tam pabeidziet apvienošanu vai turpiniet atkārtotu bāzi.
4. solis: Kad ir droši atkal stumt?
Pirms spiešanas pārbaudiet darba koku un neseno vēsturi:
git status
git log --oneline --graph --decorate -n 12
Pēc tam spiediet normāli:
git push origin main
Ja apvienojāt attālo atzaru vai no jauna bāzējāt tikai tos grozījumus, kas nekad iepriekš nav tikuši nosūtīti, parasta nosūtīšana parasti ir pareizā darbība, jo jaunais attālais padoms būs jūsu lokālā padoma priekštecis.
Kad jūsu filiālē ir gan attālinātais darbs, gan paredzētās lokālās izmaiņas, attālināto darbu var droši pārslēgt ar parastu stumšanas funkciju.
Kad jums vajadzētu lietot --force-with-lease?
Izmantojiet to tikai tad, ja apzināti pārrakstījāt vēsturi, kas jau pastāv attālajā ierīcē — piemēram, esat no jauna bāzējis iepriekš ievietotu funkciju atzaru un tagad ir jāaizstāj šī atzara vecā apstiprināšanas secība.
git push --force-with-lease origin feature-branch
Oficiālā git pushdokumentācija paskaidro, kāpēc tas ir drošāk nekā vienkārši --force: noma pārbauda, vai attālinātajai atsaucei joprojām ir jūsu gaidītā vērtība. Ja cita persona pēc stāvokļa, uz kura balstījāt savu pārrakstīšanu, ievieto jaunu darbu, piespiedu atjauninājums tiek noraidīts, nevis akli pārrakstīts viņu izmaiņu kopums.
Šī aizsardzība nav iemesls regulārai piespiedu sūtīšanai. Izvairieties no koplietoto zaru piespiedu sūtīšanas, mainja vien jūsu komanda nepārprotami neatļauj pārrakstīt vēsturi. Servera puses zaru aizsardzība var arī noraidīt piespiedu sūtīšanu neatkarīgi no jūsu lokālās komandas.
Neaizstājiet šo:
git push --force origin main
Vienkāršs variants --forceatspējo parasto drošības pārbaudi bez ātrās pārtīšanas un var pārrakstīt attālinātos izmaiņu ierakstus (commit). Git dokumentācija brīdina, ka tas var izraisīt attālā repozitorija izmaiņu ierakstu zaudēšanu.
Ko darīt, ja jau esat palaidis nepareizu komandu?
Git bieži vien joprojām ir pietiekami daudz lokālās vēstures, lai atgūtu iepriekšējo filiāles pozīciju. Palaist:
git reflog
Reblogi reģistrē jaunākos lokālo atsauču atjauninājumus, tostarp iepriekšējās vērtības HEAD. Ja atrodat commit, kas pārstāvēja jūsu atzaru pirms kļūdainas atiestatīšanas vai atkārtotas bāzes izveides, izveidojiet glābšanas atzaru, nevis nekavējoties pārvietojieties mainvēlreiz:
git branch rescue-work <commit-id>
Tagad pārbaudiet rescue-workun atkopiet nepieciešamos izmaiņu ierakstus (commit). Oficiālajā git-reflog dokumentācijā izmaiņu ieraksti ir aprakstīti kā ieraksti par to, kur iepriekš norādīja atzaru padomi un citas atsauces.
Kāpēc git pulldažreiz tika izveidots apvienošanas commit?
git pullvispirms ielādē un pēc tam integrē atlasīto augšupējo atzaru. Atkarībā no opcijām un repozitorija konfigurācijas šī integrācija var būt apvienošana vai atkārtota bāzes izveide. Ja vēlaties paredzamu darbību, labojot noraidījumu, kas netiek pārsūtīts uz priekšu, skaidri norādiet savu nodomu:
# Preserve branch history with a merge
git pull --no-rebase origin main
# Replay private local commits on top
git pull --rebase origin main
Lai nodrošinātu vislabāko redzamību, izmantojiet git fetch originvispirms un palaidiet git merge origin/mainvai git rebase origin/mainatsevišķi.
Ko darīt, ja attālinātā pievienošana nav vēlama?
Nepieņemiet, ka “nevēlams” nozīmē, ka to ir droši dzēst. Vispirms pārbaudiet to:
Ja izmaiņu izmaiņas pieder citam izstrādātājam, robotam, atkarību atjauninātājam vai tīmekļa saskarnē veiktām izmaiņām, integrējiet vai atjaunojiet to, izmantojot parasto vēsturi. Ja jūsu komanda ir apzināti vienojusies aizstāt attālo vēsturi, tad var būt piemērota aizsargāta piespiedu pārsūtīšana, taču tas ir repozitorija vēstures lēmums, nevis standarta risinājums kļūdai, kas nav saistīta ar ātro pārtīšanu.
Drošu lēmumu kontrolsaraksts
Neapstiprināti faili? Apstiprināt vai noglabāt tos pirms integrācijas.
Vai nepieciešams drošības punkts? Izveidojiet rezerves atzaru pašreizējā komitā.
Vai tālvadības pults ir nomainīta? Skrien, git fetch originpirms izlemjat, ko darīt.
Koplietota vēsture? Ja vēlaties izvairīties no izmaiņu izmaiņu pārrakstīšanas, izvēlieties apvienošanu.
Privāti lokāli grozījumi? Rebase var saglabāt vēsturi lineāru.
Konflikts? Atrisiniet failu, izveidojiet tā stadijā esošo versiju un pēc tam pabeidziet apvienošanu vai turpiniet atkārtotu bāzes izveidi.
Vai parastā integrācija ir pabeigta? Izmantojiet parasto git push.
Vai jau publicēta vēsture ir apzināti pārveidota? Apsveriet --force-with-lease, nevis vienkāršu --force.
Apakšējā līnija
Ziņojums bez ātrās pārtīšanas ir drošības barjera, kas norāda, ka attālajā atzarā ir vēsture, ko jūsu ierosinātā pārvietošana nesaglabā. Risinājums nav šīs barjeras pārvarēšana. Aizsargājiet savu lokālo darbu, ielādējiet attālo atzaru, pārbaudiet atšķirības, integrējiet to ar apvienošanu vai atkārtotu bāzi, apzināti atrisiniet konfliktus un pārvietojiet vēlreiz.
Ja atceraties vienu noteikumu, padariet to šādu: ielādēt un saprast, pirms piespiedat . Tas saglabā gan jūsu izmaiņas, gan jau attālinātajā ierīcē veikto darbu un pārvērš biedējošu push noraidījumu par ikdienišķu Git sinhronizācijas problēmu.