Jak opravit chybu „Git Push Rejected: Non-FastForward“ bez ztráty změn

Odmítnutí bez možnosti rychlého přehrávání je způsobeno ochranou historie ze strany Gitu, nikoli smazáním vaší lokální práce. Obvykle to znamená, že vzdálená větev se po poslední synchronizaci vaší lokální větve přesunula vpřed, takže aktualizace vzdálené větve s vaší aktuální větví by zahodila commity, které tam již existují. Aktuální dokumentace GitHubu popisuje stejnou situaci: nejprve načtěte změny z upstreamu, integrujte je lokálně a poté je znovu odešlete.

Nejbezpečnější obecný pracovní postup je: chránit veškerou nepotvrzenou práci, načíst vzdálenou větev bez úpravy aktuální větve, zkontrolovat, jak se historie odchýlila, zvolit buď sloučení, nebo rebase, v případě potřeby vyřešit konflikty a znovu provést odeslání. Nezačínejte s nebo git push --forcejen git reset --hardproto, abyste chybu odstranili.

Mezi oficiální reference použité v této příručce patří dokumentace GitHubu: Řešení chyb, které nevedou k rychlému přetočení , Git: dokumentace k git-push , Git: dokumentace k git-fetch a Git: dokumentace k git-rebase .

Co vlastně znamená „nepřetáčení vpřed“?

Předpokládejme, že vaše lokální mainvětev obsahuje commit L, zatímco vzdálená větev origin/mainpostoupila na jiný commit R. Pokud ani jeden commit není předkem druhého, historie se rozdělily. Normální příkaz push nemůže jednoduše přesunout ukazatel vzdálené větve na , Laniž by Rzmizel z viditelné historie dané větve.

Aktualizace fast forward je jiná: nová větev je potomkem té staré, takže posunutí větve vpřed zachovává vše, co je z ní již dosažitelné. Oficiální git pushmanuál definuje toto pravidlo předků a varuje, že --forcedeaktivuje normální ochranu a může způsobit ztrátu vzdálených commitů.

Terminál zobrazující odmítnutí příkazu git push origin main s chybou neumožňující rychlé přetočení, protože vzdálený soubor obsahuje práci, která není lokálně přítomna.
Odmítnutí bez možnosti rychlého přetáčení znamená, že Git odmítá nahradit vzdálenou historii, kterou vaše lokální větev ještě neobsahuje.

Než cokoli podniknete: je vaše lokální práce bezpečně zaznamenána?

Běh:

git status

Pokud je pracovní strom čistý, vaše aktuální změny jsou již reprezentovány commity a před integrací vzdáleného serveru můžete vytvořit další bezpečnostní referenci:

git branch backup-before-sync

Tato větev odkazuje na aktuální commit, takže máte jednoduchý název pro stav před integrací.

Pokud jste upravili nebo nesledovali soubory, které nebyly potvrzeny, zvolte před stažením nebo změnou báze jeden z těchto přístupů:

  • Pokud je práce logicky připravena k potvrzení, potvrďte je .
  • Schovejte je, pokud je práce nedokončená git stash push -u -m "before non-fast-forward fix":.

Tato -umožnost zahrnuje i nesledované soubory. Oficiální dokumentace git-stash vysvětluje, že stash zaznamenává stav pracovního adresáře a indexu a obnovuje čistý pracovní strom. Ignorované soubory nejsou zahrnuty pomocí -u; -aby zahrnovalo i ignorované soubory, ale to je pro tento problém zřídka nutné.

Důležité: Pokud git statuszobrazuje soubory, o které si nemůžete dovolit přijít, nespouštějte git reset --hard. Tento příkaz může zahodit nepotvrzené změny pracovního stromu.

Krok 1: Měli byste použít git pullokamžitě?

Můžete, ale načítání dat je snazší . Dokumenty GitHubu git fetchstahují vzdálenou práci a aktualizují větve pro vzdálené sledování, aniž by tyto změny slučovaly do vaší aktuální větve. Díky tomu je to užitečný diagnostický krok, protože můžete situaci prozkoumat před změnou lokální historie.

git fetch origin
git status -sb
git log --oneline --graph --decorate --left-right HEAD...origin/main

Po načtení origin/mainpředstavuje větev remote-tracking právě načtený vzdálený stav. Příkaz log umožňuje zobrazit commity dostupné pouze z vaší lokální a pouze ze vzdálené strany.

Pokud vaše lokální pobočka nemá žádné unikátní commity a jednoduše je pozadu, můžete ji často přetočit dopředu:

git merge --ff-only origin/main

Pak není co slaďovat; vaše větev se jednoduše posouvá kupředu.

Krok 2: Sloučení nebo rebase – co si vybrat?

Oba mohou zachovat vaše změny. Rozdíl je ve tvaru výsledné historie.

Situace Obvykle si vybírají Proč
Sdílená větev, například maintam, kde vaše lokální commity mohou být již známy ostatním Spojit Zachovává existující identity commitů a nepřepisuje vaše lokální commity.
Vaše commity jsou lokální/soukromé a chcete lineární historii. Znovu vypočítat Znovu přehraje vaše lokální commity přes aktualizovanou vzdálenou větev.
Nejste si jisti a chcete co nejméně přepisovat historii Spojit Je to snadněji vysvětlitelné a bezpečnější pro sdílenou historii.

Sloučit trasu

git fetch origin
git merge origin/main

Pokud nedojde k žádným konfliktům, Git dokončí integraci. Pokud se větve skutečně rozdělily, může výsledkem být commit sloučení.

Znovu vypočítat trasu

git fetch origin
git rebase origin/main

Rebase vezme commity, které jsou jedinečné pro vaši aktuální větev, a znovu je aplikuje na origin/main. Dokumentace k rebase v Gitu to popisuje jako přenesení série commits na jiný výchozí bod. Protože tyto commity obdrží nová ID commitu, je rebase nejlépe použitelný pro lokální práci, která ještě nebyla sdílena jako veřejná historie.

Pokud dáváte přednost zkratce, git pull --rebase origin mainprovede načtení následované rebase, zatímco git pull --no-rebase origin mainexplicitně zvolí chování sloučení. Pro situaci obnovy jsou příkazy separate fetcha merge/ rebasečasto přehlednější, protože si můžete nejprve prohlédnout vzdálený stav.

Terminál zobrazující příkaz git pull origin main, který načítá vzdálené objekty a aktualizuje větev o vzdálené změny.
Po načtení vzdálených změn je záměrně integrujte – sloučením nebo rebase – namísto jejich přepsání.

Krok 3: Co dělat, když Git nahlásí konflikt?

Konflikt neznamená, že vaše změny jsou pryč. Znamená to, že Git nemůže automaticky rozhodnout, jak kombinovat změny stejného obsahu.

Nejprve zkontrolujte stav:

git status

Otevřete každý konfliktní soubor, rozhodněte se, jaký by měl být konečný obsah, odstraňte značky konfliktu a poté připravte vyřešený soubor:

git add path/to/file

Pokud zvolíte sloučení, dokončete sloučení po vyřešení všech konfliktů:

git commit

Pokud jste zvolili rebase, pokračujte v přehrávání commitů:

git rebase --continue

Pokud rebase probíhá špatně a chcete vrátit větev do stavu před rebase, použijte:

git rebase --abort

Aktuální manuál k rebaseování Gitu dokumentuje konkrétně ` --continuea` --abortpro tento účel. Nepoužívejte git rebase --skip`pouhé odstranění konfliktu`, pokud skutečně nemáte v úmyslu vynechat přehrávaný commit.

Terminál zobrazující odbočnou hlavní větev, konflikt sloučení app.js a příkazy, které připravují vyřešený soubor a vytvářejí commit pro řešení konfliktu.
Nejprve vyřešte obsah, připravte opravený soubor a poté dokončete sloučení nebo pokračujte v rebase.

Krok 4: Kdy je bezpečné znovu tlačit?

Před odesláním ověřte pracovní strom a nedávnou historii:

git status
git log --oneline --graph --decorate -n 12

Pak normálně stiskněte:

git push origin main

Pokud jste sloučili vzdálenou větev nebo přebazovali pouze commity, které nikdy předtím nebyly odeslány, normální odeslání by obvykle mělo být správnou operací, protože nový vzdálený tip bude předkem vašeho lokálního tipu.

Terminál zobrazující úspěšné dokončení příkazu git push origin main po integraci vzdálených změn.
Jakmile vaše větev obsahuje jak vzdálenou práci, tak i zamýšlené lokální změny, může normální odeslání (push) bezpečně přesunout vzdálenou práci.

Kdy byste měli použít --force-with-lease?

Použijte ho pouze tehdy, když jste úmyslně přepsali historii, která již na vzdáleném serveru existuje – například jste přepracovali větev funkcí, kterou jste dříve odeslali, a nyní potřebujete nahradit starou sekvenci commitů této větve.

git push --force-with-lease origin feature-branch

Oficiální git pushdokumentace vysvětluje, proč je to bezpečnější než prostý způsob --force: pronájem kontroluje, zda má vzdálený odkaz stále očekávanou hodnotu. Pokud jiná osoba odeslala novou práci po stavu, na kterém jste založili svůj přepis, vynucená aktualizace je odmítnuta, místo aby se její commity slepě přepsaly.

Tato ochrana není důvodem k rutinnímu používání vynuceného odesílání. Vyhněte se vynucenému odesílání sdílených větví, pokud mainváš tým explicitně nepovolí přepisování historie. Ochrana větví na straně serveru může také odmítnout vynucené odesílání bez ohledu na váš lokální příkaz.

Toto nenahrazujte:

git push --force origin main

Plain --forcezakáže normální bezpečnostní kontrolu bez přetáčení vpřed a může přepsat vzdálené commity. Dokumentace Gitu varuje, že to může způsobit ztrátu commitů ve vzdáleném repozitáři.

Co když jste již spustili špatný příkaz?

Git má často stále dostatek lokální historie k obnovení předchozí pozice větve. Spusťte:

git reflog

Reflogy zaznamenávají nedávné aktualizace lokálních referencí, včetně předchozích hodnot HEAD. Pokud najdete commit, který reprezentoval vaši větev před chybným resetem nebo rebase, vytvořte záchrannou větev namísto okamžitého mainopětovného přesunu:

git branch rescue-work <commit-id>

Nyní prohlédněte rescue-worka obnovte potřebné commity. Oficiální dokumentace git-reflog popisuje reflogy jako záznamy o tom, kam dříve odkazovaly tipy na větve a další odkazy.

Proč se git pullněkdy vytvářel commit sloučení?

git pullnejprve načte a poté integruje vybranou větev z upstreamu. V závislosti na možnostech a konfiguraci repozitáře může být tato integrace sloučením nebo rebase. Pokud chcete předvídatelné chování při opravě odmítnutí, které neumožňuje rychlé přetočení, explicitně uveďte svůj záměr:

# Preserve branch history with a merge
git pull --no-rebase origin main

# Replay private local commits on top
git pull --rebase origin main

Pro co nejlepší viditelnost použijte git fetch originnejprve a poté spusťte git merge origin/main, nebo je použijte git rebase origin/mainsamostatně.

Co když je vzdálený commit nežádoucí?

Nepředpokládejte, že „nežádoucí“ znamená, že je bezpečné jej smazat. Nejprve jej zkontrolujte:

git fetch origin
git log --oneline --decorate HEAD..origin/main
git show origin/main

Pokud commit patří jinému vývojáři, botovi, aktualizátoru závislostí nebo se jedná o změnu provedenou ve webovém rozhraní, integrujte jej nebo jej vraťte zpět pomocí normální historie. Pokud se váš tým záměrně dohodl na nahrazení vzdálené historie, pak může být vhodné chráněné vynucené nahrání – ale to je rozhodnutí týkající se historie repozitáře, nikoli standardní oprava chyby, která neumožňuje rychlé přetočení.

Kontrolní seznam pro bezpečné rozhodování

  • Nepřijaté soubory? Před integrací je přijatelné nebo uložené.
  • Potřebujete bezpečnostní bod? Vytvořte záložní větev v aktuálním commitu.
  • Změnil se dálkový ovladač? Spusťte to git fetch origin, než se rozhodnete, co dělat.
  • Sdílená historie? Pokud se chcete vyhnout přepisování commitů, preferujete sloučení.
  • Soukromé lokální commity? Rebase může udržet historii lineární.
  • Konflikt? Vyřešte soubor, připravte ho a poté dokončete sloučení nebo pokračujte v rebase.
  • Normální integrace dokončena? Použijte normální git push.
  • Již publikovaná historie záměrně přepracovaná? Zvažte --force-with-lease, ne prostý --force.

Sečteno a podtrženo

Zpráva o nepřetáčení vpřed je bezpečnostní bariéra, která vám říká, že vzdálená větev obsahuje historii, kterou vámi navrhovaný push neuchovává. Oprava nespočívá v překonání této bariéry. Chraňte svou lokální práci, načtěte vzdálenou větev, prozkoumejte divergenci, integrujte ji pomocí sloučení nebo rebase, záměrně vyřešte konflikty a push znovu.

Pokud si pamatujete jedno pravidlo, zkuste ho: nejprve načtěte a pochopte změny, než je vynutíte . Tím se zachovají jak vaše změny, tak i práce, která již byla na vzdáleném serveru – a děsivé odmítnutí odeslaných změn se změní v rutinní problém se synchronizací Gitu.

Zanechat komentář

Jak opravit chybu „Oprávnění odepřeno (veřejný klíč)“ v GitHub SSH

Jak opravit chybu „Oprávnění odepřeno (veřejný klíč)“ v GitHub SSH

Opravte chybu „Oprávnění GitHub SSH odepřeno (veřejný klíč)“ kontrolou hostitele, aktivního klíče SSH, účtu GitHub, autorizace SSO, vzdálené adresy URL a přístupu na port 22.

Jak opravit chybu „Git Push Rejected: Non-FastForward“ bez ztráty změn

Jak opravit chybu „Git Push Rejected: Non-FastForward“ bez ztráty změn

Bezpečně opravte push chybu v Gitu, která neumožňuje rychlé přehrávání. Chraňte lokální práci, načítejte vzdálené commity, vyberte sloučení nebo rebase, vyřešte konflikty a pushujte bez ztráty změn.

Jak opravit chybu „Nginx 502 Bad Gateway“ při proxyování k Node.js

Jak opravit chybu „Nginx 502 Bad Gateway“ při proxyování k Node.js

Opravte chyby Nginx 502 Bad Gateway s upstreamem Node.js kontrolou portu aplikace, protokolů NGINX, adresy proxy_pass, sítě kontejnerů, časových limitů a opětovného načtení.

Jak opravit chybu „Typ 'null' nelze přiřadit typu“ v TypeScriptu

Jak opravit chybu „Typ 'null' nelze přiřadit typu“ v TypeScriptu

Oprava chyby „Typ 'null' nelze přiřadit typu“ v TypeScriptu u sjednocovacích typů, zúžení, výchozích hodnot a bezpečných asercí v rámci strictNullChecks.

Jak opravit chybu „Prisma Client Has Not Been Generated Yet“

Jak opravit chybu „Prisma Client Has Not Been Generated Yet“

Opravte chybu nevygenerovaného Prisma Client kontrolou generátoru, schématu, výstupní cesty, importů, verzí, nastavení monorepa a kroků sestavení při nasazení.

Jak opravit chybu „ERR_MODULE_NOT_FOUND“ v importech Node.js ESM

Jak opravit chybu „ERR_MODULE_NOT_FOUND“ v importech Node.js ESM

Opravte chybu Node.js ERR_MODULE_NOT_FOUND v ESM kontrolou cest importu, přípon souborů, instalace balíčků, exportů, režimu ESM a čistých instalací.

Jak opravit problém se SSL certifikátem: Nelze získat lokální certifikát vydavatele v Gitu

Jak opravit problém se SSL certifikátem: Nelze získat lokální certifikát vydavatele v Gitu

Opravte chybu Gitu 'nelze získat lokální certifikát vydavatele' identifikací důvěryhodného backendu, instalací správného řetězce CA a ponecháním ověřování SSL zapnutého.

Jak opravit chybu časového limitu sítě MongoDB v připojení Mongoose

Jak opravit chybu časového limitu sítě MongoDB v připojení Mongoose

Opravte chyby časového limitu sítě MongoDB v Mongoose identifikací typu časového limitu, testováním dostupnosti Atlasu nebo TCP, opravou URI a laděním časových limitů pouze v odůvodněných případech.

Jak opravit chybu Execution Policy Restricted ve Windows PowerShell

Jak opravit chybu Execution Policy Restricted ve Windows PowerShell

Opravte chybu Execution Policy Restricted v PowerShellu kontrolou rozsahu a Skupinové politiky, poté zvolte RemoteSigned, Unblock-File nebo dočasnou možnost relace.

Jak opravit chybu npm ERR! code ERESOLVE: Konflikt peer dependencies

Jak opravit chybu npm ERR! code ERESOLVE: Konflikt peer dependencies

Opravte konflikty peer dependencies v npm identifikací nekompatibilního rozsahu balíčků, zarovnáním verzí, použitím příkazů npm explain a npm ls a používáním legacy-peer-deps nebo force pouze jako kontrolovaných záložních řešení.