10 uobičajenih problema s gitom i kako ih riješiti

Izvorno sam napisao ovaj članak za Codementor u listopadu 2014. Trebao bi sadržavati svakoga, od prilično novih git korisnika do iskusnih programera.

1. Odbacite lokalne modifikacije datoteka

Ponekad je najbolji način da osjetite problem ronjenje i igranje s šifrom. Nažalost, promjene u tijeku ponekad se ispostave da su manje nego optimalne, pa je vraćanje datoteke u prvobitno stanje najbrže i najlakše rješenje:

git checkout - Gemfile # resetiranje navedenog puta
git checkout - lib bin # također radi s više argumenata

U slučaju da se pitate, dvostruka crtica (-) uobičajen je način da uslužni programi naredbenog retka označavaju kraj opcija naredbe.

2. Poništavanje lokalnih obaveza

Jao, ponekad nam treba malo više da shvatimo da smo na pogrešnom putu i do tada je jedna ili više promjena možda već počinjeno lokalno. Ovo je kada je korisno resetiranje gita:

git reset HEAD ~ 2 # poništi posljednje dvije obveze, zadrži promjene
git reset --hard HEAD ~ 2 # poništi posljednje dvije naredbe, odbaci promjene

Budite oprezni s opcijom --hard! Resetira vaše radno stablo kao i indeks, tako da će sve vaše modifikacije zauvijek biti izgubljene.

3. Uklonite datoteku iz gita bez uklanjanja iz vašeg datotečnog sustava

Ako niste oprezni tijekom git dodavanja, možete dodati datoteke koje niste htjeli počiniti. Međutim, git rm će ga ukloniti iz prostora za postavljanje, kao i iz vašeg datotečnog sustava, koji možda nije ono što želite. U tom slučaju obavezno uklonite samo postupnu verziju i dodajte datoteku u .gitignore kako ne biste drugi put napravili istu pogrešku:

git reset naziv datoteke # ili git rm --cached naziv datoteke
echo ime datoteke >> .gitignore # dodajte ga u .gitignore kako biste izbjegli njegovo ponovno dodavanje

4. Uredite poruku o obvezi

Pogreške se događaju, ali srećom, u slučaju poruka koje počinju, popraviti ih je vrlo jednostavno:

git commit --amend # start $ EDITOR za uređivanje poruke
git commit --amend -m "Nova poruka" # postavi novu poruku izravno

Ali to nije sve git-amandman za vas. Jeste li zaboravili dodati datoteku? Samo ga dodajte i izmijenite prethodnu obvezu!

git dodaj zaboravljeno_file git počiniti --amend

Imajte na umu da će --amend zapravo stvoriti novu obvezu koja zamjenjuje prethodnu, pa je ne upotrebljavajte za izmjenu obveza koje su već prebačene u središnje spremište. Izuzetak od ovog pravila može se napraviti ako ste apsolutno sigurni da nijedan drugi programer već nije provjerio prethodnu verziju i na njoj temeljio svoj vlastiti rad, u kojem slučaju prisilni pritisak (git push --force) i dalje može biti u redu. Ovdje je potrebna opcija --force s obzirom da je povijest stabla lokalno izmijenjena, što znači da će daljinski poslužitelj odbiti guranje jer nije moguće brzo spajanje naprijed.

5. Prije guranja očistite lokalne obveze

Iako je --amend vrlo koristan, ne pomaže ako obveza koju želite preformulirati nije posljednja. U tom slučaju je korisna interaktivna baza podataka:

git rebase - interaktivni
# ako niste naveli nikakve podatke za praćenje za ovu granu
# morat ćete dodati podatke uzvodne i udaljene podružnice:
git rebase - grana interaktivnog podrijetla

Ovo će otvoriti vaš konfigurirani uređivač i predstaviti vam sljedeći izbornik:

odaberite 8a20121 Upgrade Ruby inačicu na 2.1.3
pick 22dcc45 Dodajte fancy knjižnicu
# Rebase fcb7d7c..22dcc45 na fcb7d7c
#
# Naredbe: # p, pick = koristi počinjenje
# r, reword = koristi počinjenje, ali uredite poruku počinjenja
# e, uredite = upotrijebite počinjenje, ali zaustavite se s izmjenama
# s, squash = upotrebi počinite, ali uklopite se na prethodni počinak
# f, fixup = poput "squash", ali odbacite poruku dnevnika ove obveze
# x, exec = naredba za pokretanje (ostatak retka) koristeći shell
#
# Ovi se redovi mogu preurediti; izvode se odozgo prema dolje.
#
# Ako ovdje uklonite crtu KOJU SE OBAVEZ ĆE GUBITI.
#
# Međutim, ako uklonite sve, ponovno pokretanje baze će se prekinuti.
#
# Imajte na umu da su prazni komentari komentirani

Povrh ćete vidjeti popis lokalnih stavki, a potom objašnjenje dostupnih naredbi. Samo odaberite obveze koje želite ažurirati, promijenite odabir u riječ (ili ukratko r) i bit ćete preusmjereni na novi prikaz u kojem možete urediti poruku.

No, kao što je vidljivo iz gornjeg popisa, interaktivni raboti nude puno više od jednostavnog uređivanja poruka o obvezama: obveze možete u potpunosti ukloniti tako da ih izbrišete s popisa, kao i da ih uredite, preuredite i smanjite. Skvošing vam omogućuje spajanje nekoliko dijelova u jedan, što ja volim raditi na granama značajki prije nego što ih gurnete na daljinac. Nema više dodavanja zaboravljene datoteke i „Popravi pogrešku pribora“ zabilježenih u vječnost!

6. Vraćanje potisnutih obaveza

Unatoč ispravkama pokazanim u prethodnim savjetima, neispravni se poslovi povremeno pretvaraju u središnje spremište. Ipak to nije razlog očajavanju, jer git nudi jednostavan način vraćanja pojedinačnih ili višestrukih preuzimanja:

git revert c761f5c # vraća naredbu s navedenim idom
git revert HEAD ^ # vraća drugu zadnju obvezu
git revert razvijati ~ 4..develop ~ 2 # vraća cijeli niz počinjenja

U slučaju da ne želite stvoriti dodatne obrate vraćanja, nego samo primijeniti potrebne promjene na vašem radnom stablu, možete upotrijebiti opciju --no-počinite / -n.

# poništite posljednju obvezu, ali ne stvarajte vraćanje
git revert -n GLAVA

Stranica s priručnikom na man 1 git-return popisu dodatne mogućnosti i nudi neke dodatne primjere.

7. Izbjegavajte ponavljane sukobe spajanja

Kao što svaki programer zna, popravljanje sukoba spajanja može biti zamorno, ali rješavanje istog sukoba više puta (npr. U dugotrajnim granama značajki) izravno je neugodno. Ako ste od toga patili u prošlosti, rado ćete saznati više o neiskorištenoj značajci ponovne upotrebe snimljenih razlučivosti. Dodajte ga u svoj globalni config kako biste ga omogućili za sve projekte:

git config --global rerere.enabled true

Alternativno, možete ga omogućiti na projektu, ručno kreirajući direktorij .git / rr-cache.

Ovo sigurno nije značajka za sve, ali za ljude kojima je to potrebno, to može biti ušteda u stvarnom vremenu. Zamislite da vaš tim radi na raznim granama značajki istovremeno. Sada ih želite spojiti u jednu podružnicu za testiranje prije testiranja. Kao što se očekivalo, postoji nekoliko sukoba spajanja koje vi rješavate. Nažalost, ispostavilo se da jedna od grana još nije tamo, pa je odlučite ponovo ukloniti. Nekoliko dana (ili tjedana) kasnije kad je grana napokon spremna ponovo je spojite, ali zahvaljujući snimljenim rješenjima više nećete morati rješavati iste sukobe spajanja.

Stranica man (man git-rerere) sadrži više informacija o slučajevima daljnjeg korištenja i naredbama (status git rerere, git rerere diff itd.).

8. Pronađite vezu koja je nešto prekinula nakon spajanja

Praćenje počinjenja kojim je uvela programska pogreška nakon velikog spajanja može dugotrajno. Srećom git nudi sjajno binarno pretraživanje u obliku git-bisect-a. Prvo morate izvršiti početnu postavku:

git bisect start # započinje sesiju dijeljenja
git bisect bad # označava trenutnu reviziju kao lošu
git bisect dobra revizija # označava posljednju poznatu dobru reviziju

Nakon ovog gita automatski će izvršiti reviziju na pola puta između poznatih verzija "dobra" i "loša". Sada možete ponovo pokrenuti svoje specifikacije i označiti počinjanje kao „dobar“ ili „loš“ u skladu s tim.

git bisect good # ili git bisec bad

Taj se postupak nastavlja sve dok ne dođete do počinitelja koji su uveli bugu.

9. Izbjegavajte česte pogreške sa git kukama

Neke se pogreške ponavljaju, ali lako bi ih bilo izbjeći pokretanjem određenih provjera ili zadataka čišćenja u definiranoj fazi tijeka rada Git. Upravo je to scenarij za koji su kuke bile dizajnirane. Da biste stvorili novu udicu, dodajte izvršnu datoteku u .git / hooks. Naziv skripte mora odgovarati jednoj od dostupnih kuka, čiji je potpuni popis dostupan na stranici s uputama (man githooks). Također možete definirati globalne udice koje će se koristiti u svim vašim projektima tako što ćete stvoriti direktorij predložaka koji će git koristiti prilikom inicijalizacije novog spremišta (za dodatne informacije pogledajte man git-init). Evo kako izgledaju relevantni unosi u ~ / .gitconfig i katalog primjera predloška:

[u tome]
    templatedir = ~ / .git_template
  
→ stablo .git_template
  .git_template
  └── kuke
      └── prije počinjenja

Kada inicijalizirate novo spremište, datoteke u direktoriju predložaka kopirat će se na odgovarajuće mjesto u .git direktoriju vašeg projekta.

Ono što slijedi je pomalo zamišljeni primjer kuke msg msg, koji će osigurati da svaka poruka o preuzimanju referencira broj ulaznice poput "# 123".

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

osim ako je poruka = ​​~ / \ s * # \ d + /
  stavlja "[POLITIKA] Vaša se poruka nije odnosila na kartu."
  izlaz 1
kraj

10. Kad sve drugo ne uspije

Do sada smo pokrili dosta terena o tome kako popraviti uobičajene pogreške pri radu s gitom. Većina ih ima dovoljno jednostavna rješenja, ali postoje slučajevi kada treba izvaditi velike puške i prepisati povijest cijele podružnice. Jedan uobičajeni slučaj za to je uklanjanje osjetljivih podataka (npr. Vjerodajnice za prijavu za proizvodne sustave) koji su predani javnom spremištu:

git filter-grana --force --index-filter \
  'git rm --cached --ignore-unmatch secrets.txt' \
  --prune-empty --tag-ime-filter mačka - --all

Ovo će ukloniti datoteku secrets.txt iz svake grane i oznake. Također će ukloniti sve obveze koje bi bile prazne kao rezultat gore navedene operacije. Imajte na umu da će ovo napisati cjelokupnu povijest vašeg projekta, što može biti vrlo razarajuće u distribuiranom tijeku rada. Iako je predmetna datoteka sada uklonjena, vjerodajnice u njoj i dalje se trebaju smatrati ugroženima!

GitHub ima vrlo dobar tutorial o uklanjanju osjetljivih podataka, a man git-filter-branch ima sve detalje o različitim dostupnim filtrima i njihovim mogućnostima.

Izvorno objavljeno na gist.github.com.