10 Bežné problémy so Gitom a ako ich vyriešiť

Pôvodne som tento článok napísal pre Codementor v októbri 2014. Mal by mať niečo pre každého, od pomerne nových používateľov git až po skúsených vývojárov.

1. Zahoďte lokálne úpravy súborov

Najlepším spôsobom, ako získať pocit z problému, je niekedy ponoriť sa a hrať sa s kódom. Bohužiaľ, zmeny vykonané v tomto procese sa niekedy ukážu ako menej optimálne, v takom prípade môže byť najrýchlejším a najjednoduchším riešením vrátenie súboru do pôvodného stavu:

git checkout - Gemfile # reset zadanej cesty
git checkout - lib bin # funguje tiež s viacerými argumentmi

V prípade, že vás zaujíma, dvojitá pomlčka (-) predstavuje bežný spôsob, ako obslužné programy príkazového riadku označia koniec možností príkazu.

2. Zrušenie miestnych záväzkov

Bohužiaľ, niekedy nám to trvá trochu dlhšie, kým si uvedomíme, že sme na nesprávnej ceste, a dovtedy sa už mohla vykonať jedna alebo viac zmien na miestnej úrovni. V takom prípade je užitočné resetovať git:

git reset HEAD ~ 2 # vrátiť posledné dva potvrdenia, zachovať zmeny
git reset --hard HEAD ~ 2 # vrátiť posledné dva potvrdenia, zmeny zahodiť

Pri voľbe --hard buďte opatrní! Vynuluje váš pracovný strom a index, takže všetky vaše zmeny sa stratia navždy.

3. Vyberte súbor z gitu bez jeho odstránenia zo systému súborov

Ak si počas pridávania git nebudete dávať pozor, môžete nakoniec pridať súbory, ktoré ste nechceli prijať. Program git rm ho však odstráni z pracovnej oblasti, ako aj zo systému súborov, čo nemusí byť to, čo chcete. V takom prípade sa uistite, že ste odstránili iba etapovú verziu, a pridajte súbor do svojho .gitignore, aby ste sa vyhli opakovaniu tej istej chyby druhýkrát:

git resetuje názov súboru # alebo git rm - názov súboru s vyrovnávacou pamäťou
echo filename >> .gitignore # pridajte ho do .gitignore, aby ste sa vyhli jeho opätovnému pridaniu

4. Upravte správu potvrdenia

K preklepom dôjde, ale našťastie v prípade odovzdania správ je ich ľahké opraviť:

git commit --amend # start $ EDITOR na úpravu správy
git commit --amend -m "Nová správa" # nastaví novú správu priamo

Ale to nie je všetko, čo pre vás môže urobiť git-zmena. Zabudli ste pridať súbor? Stačí ho pridať a zmeniť predchádzajúci záväzok!

pridať zabudnuté_file

Nezabúdajte, že - v skutočnosti bude vytvorený nový záväzok, ktorý nahradí predchádzajúci, preto ho nepoužívajte na úpravu záväzkov, ktoré už boli presunuté do centrálneho úložiska. Výnimku z tohto pravidla je možné urobiť, ak ste si úplne istí, že žiadny iný vývojár už nezaregistroval predchádzajúcu verziu a na nej založil svoju vlastnú prácu. V takom prípade môže byť nútený tlak (git push - force) stále v poriadku. Voľba --force je tu nevyhnutná, pretože história stromu bola lokálne upravená, čo znamená, že vzdialený server bude tlačenie zamietnuté, pretože nie je možné rýchle zlučovanie dopredu.

5. Pred tlačením očistite miestne potvrdenia

Aj keď --amend je veľmi užitočný, nepomôže, ak záväzok, ktorý chcete preformulovať, nie je posledný. V takom prípade sa hodí interaktívna rebáza:

git rebase --interactive
#, ak ste pre túto vetvu nezadali žiadne informácie o sledovaní
# budete musieť pridať predchádzajúce a vzdialené informácie o vetve:
vetva git rebase - interaktívny pôvod

Tým sa otvorí váš nakonfigurovaný editor a zobrazí sa vám nasledujúce menu:

vyberte verziu 8a20121 Upgrade Ruby na 2.1.3
pick 22dcc45 Pridajte nejakú vymyslenú knižnicu
# Rebase fcb7d7c..22dcc45 na fcb7d7c
#
# Príkazy: # p, pick = use commit
# r, reword = use commit, ale upravte správu potvrdenia
# e, edit = use commit, ale zastavte pre zmeny
# s, squash = use commit, ale spája sa s predchádzajúcim commitom
# f, fixup = ako "squash", ale zahoďte túto správu do denníka
# x, exec = run príkaz (zvyšok riadku) pomocou shellu
#
# Tieto riadky je možné objednať znova; vykonávajú sa zhora nadol.
#
# Ak tu odstránite riadok, ŽE ZÁVÄZOK ZÍSKE.
#
# Ak však všetko odstránite, rebase bude prerušená.
#
# Všimnite si, že prázdne potvrdenia sú komentované

V hornej časti uvidíte zoznam miestnych potvrdení, po ktorých nasleduje vysvetlenie dostupných príkazov. Stačí si vybrať potvrdenia, ktoré chcete aktualizovať, zmeniť výber preložiť (alebo skrátene r) a dostanete sa na nové zobrazenie, kde môžete správu upraviť.

Ako je však zrejmé z vyššie uvedeného zoznamu, interaktívne rebázy ponúkajú oveľa viac než len jednoduchú úpravu správy o odovzdaní: môžete ich úplne odstrániť odstránením zo zoznamu, ako aj ich upraviť, zmeniť poradie a potlačiť. Squashing vám umožní zlúčiť niekoľko odovzdaní do jedného, ​​čo je niečo, čo by som rád robil na vetviach funkcií pred ich tlačením na diaľkové ovládanie. Už nikdy sa nezaznamenávajú žiadne ďalšie príkazy „Pridať zabudnutý súbor“ a „Opraviť preklep“ na celú večnosť!

6. Spätná väzba na vrátenie

Napriek opravám uvedeným v predchádzajúcich tipoch sa chybné odovzdania občas dostanú do centrálneho úložiska. Stále to nie je dôvod na zúfalstvo, pretože git ponúka jednoduchý spôsob, ako vrátiť jedno alebo viac záväzkov:

git revert c761f5c # vráti odovzdanie so zadaným id
git revert HEAD ^ # vráti druhý až posledný záväzok
git revert develop ~ 4..develop ~ 2 # vráti celý rad záväzkov

V prípade, že nechcete vytvárať ďalšie spätné potvrdenia, ale vo svojom pracovnom strome použijete iba potrebné zmeny, môžete použiť voľbu --no-commit / -n.

# zruší posledné odovzdanie, ale nevytvorí spätné odovzdanie
git revert -n HEAD

Manuálna stránka na stránke man git-revert obsahuje ďalšie možnosti a uvádza niekoľko ďalších príkladov.

7. Vyhnite sa opakovaným konfliktom zlúčenia

Ako každý vývojár vie, riešenie konfliktov zlúčenia môže byť únavné, ale riešenie toho istého konfliktu opakovane (napr. V dlhodobých vetvách funkcií) je úplne nepríjemné. Ak ste v minulosti týmto problémom trpeli, radi sa dozviete viac o funkcii rozlíšenia zaznamenaného pri opakovanom použití. Pridajte ju do svojej globálnej konfigurácie a povolte ju pre všetky projekty:

git config --global rerere.enabled true

Prípadne ju môžete povoliť pre jednotlivé projekty manuálnym vytvorením adresára .git / rr-cache.

Táto istota nie je funkciou pre všetkých, ale pre ľudí, ktorí ju potrebujú, môže to byť šetrič v reálnom čase. Predstavte si, že váš tím pracuje na rôznych odvetviach súčasne. Teraz ich chcete zlúčiť do jednej testovateľnej vetvy pred vydaním. Podľa očakávania existuje niekoľko zlúčení konfliktov, ktoré vyriešite. Bohužiaľ sa ukazuje, že jedna z vetiev ešte nie je celkom, takže sa rozhodnete znova ju zlúčiť. O niekoľko dní (alebo týždňov) neskôr, keď je pobočka konečne pripravená, ju znova zlúčite, ale vďaka zaznamenaným riešeniam už nebudete musieť rovnaké konflikty zlúčenia znova riešiť.

Manová stránka (man git-rerere) obsahuje viac informácií o ďalších prípadoch použitia a príkazoch (stav git rerere, rozdiel git rerere atď.).

8. Nájdite záväzok, ktorý po zlúčení niečo zlomil

Sledovanie zmien, ktoré spôsobili chybu po veľkom zlúčení, môže byť dosť náročné na čas. Našťastie git ponúka skvelé binárne vyhľadávacie zariadenie vo forme git-bisect. Najprv musíte vykonať počiatočné nastavenie:

git bisect start # spustí stretnutie
git bisect bad # označí aktuálnu revíziu ako zlú
dobrá revízia git bisect # označuje poslednú známu dobrú revíziu

Potom tento git automaticky skontroluje revíziu na polceste medzi známou „dobrou“ a „zlou“ verziou. Teraz môžete znova spustiť svoje špecifikácie a podľa toho označiť odovzdanie ako „dobré“ alebo „zlé“.

git bisect good # alebo git bisec bad

Tento proces pokračuje, až kým sa nedostanete k potvrdeniu, ktoré zaviedlo chybu.

9. Vyhnite sa častým chybám s háčikmi na git

Niektoré chyby sa vyskytujú opakovane, ale dá sa ľahko vyhnúť vykonaním určitých kontrol alebo čistiacich úloh v definovanej fáze pracovného postupu git. To je presne ten scenár, pre ktorý boli háčiky navrhnuté. Ak chcete vytvoriť nový hák, pridajte spustiteľný súbor do .git / hooks. Názov skriptu musí zodpovedať jednému z dostupných háčikov, ktorých úplný zoznam je k dispozícii na stránke manuálu (man githooks). Môžete tiež definovať globálne háčiky, ktoré sa majú použiť vo všetkých vašich projektoch, vytvorením adresára šablón, ktorý git použije pri inicializácii nového archívu (ďalšie informácie nájdete v časti man git-init). Takto vyzerá relevantná položka v ~ / .gitconfig a príklad adresára šablóny:

[Init]
    templatedir = ~ / .git_template
  
→ strom .git_template
  .git_template
  └── háčiky
      └── predbežne sa zaviazať

Keď inicializujete nové úložisko, súbory v adresári šablón sa skopírujú na príslušné miesto v adresári .git vášho projektu.

Nasleduje mierne vynútený príklad háčku commit-msg, ktorý zabezpečí, že každá správa o odovzdaní bude odkazovať na číslo lístka, napríklad „# 123“.

#! / usr / bin / env ruby
message = File.read (ARGV [0])

pokiaľ správa = ~ / \ s * # \ d + /
  vloží „[POLITIKA] Vaša správa neodkazovala na lístok.“
  výstup 1
koniec

10. Keď všetko ostatné zlyhá

Doposiaľ sme sa zaoberali pomerne mnohými dôvodmi, ako opraviť bežné chyby pri práci s git. Väčšina z nich má dosť ľahké riešenia, ale niekedy sú situácie, keď sa človek musí dostať z veľkých zbraní a prepísať históriu celej vetvy. Jedným z bežných prípadov použitia je odstránenie citlivých údajov (napr. Prihlasovacích údajov pre výrobné systémy), ktoré boli odovzdané do verejného archívu:

git filter-branch --force --index-filter \
  'git rm - cached --ignore-unmatch secrets.txt' \
  --prune-empty --tag-name-filter cat - --all

Týmto sa odstráni súbor secrets.txt zo všetkých vetiev a značiek. Odstráni tiež všetky záväzky, ktoré by boli v dôsledku vyššie uvedenej operácie prázdne. Nezabúdajte, že týmto sa prepíše celá história vášho projektu, čo môže byť v distribuovanom pracovnom postupe veľmi rušivé. Aj keď bol príslušný súbor teraz odstránený, poverenia, ktoré obsahuje, by sa mali stále považovať za ohrozené!

GitHub má veľmi dobrý návod na odstraňovanie citlivých údajov a vetva git-filter-man má všetky podrobnosti o rôznych dostupných filtroch a ich možnostiach.

Pôvodne uverejnené na stránke gist.github.com.