Tento článek patří do seriálu Jak na git. Ostatní články seriálu:
- Jak na git díl 0 - Co, proč, jak?
- Jak na git - díl 1. - git init, remote, config, clone, add, commit, push
- Jak na git - díl 2. - git status, log, checkout, reset
- Jak na git - díl 3. - git revert, stash, diff, clean
- Jak na git - díl 4. - git pull, git fetch, git branch, git merge
- Jak na git - díl 5. - git tag, git cherry-pick a opravy rozbitého gitu
- Jak na git - díl 6. - git rebase a interaktivní rebase
- Git - přidávání částí souborů do commitu
- Git - tutoriály a návody
Staging area podruhé
Již bylo řečeno, že pomocí git add
se přidávají do staging area soubory, které poté budou součástí commitu. Co když ale je potřeba soubor ze staging area odebrat? Příkaz git status
, nějakou jednoduchou nápovědu vypíše přímo, viz následující obrázek.
git status # Vypíše seznam podobný jako na obrázku git status --short # Výstupem je jednořádkový výpis git status --ignored # Do výpisu zahrne i ignorované soubory
Přidávání, odebírání a rušení změn
Přidávání je popsáno v minulém článku, jen doplnění, že před verzí Gitu 2.x příkaz git add
nepřidal do staging area soubory, které se mazaly. Nyní už se to řešit naštěstí nemusí.
Na příkaz git checkout
i git reset
je potřeba si dávat velký pozor, protože dělají velké množství úloh a některé dosti destruktivní. Protože větve budou někdy příště, v posledním příkazu místo vetev stačí napsat master, protože tak se nyní hlavní větev jmenuje.
# Viz minulý díl, přidává jak "untracked" tak "not staged" soubory git add soubor # Odstraní soubory pouze ze staged area, místo jména souboru # lze napsat i . pro všechny, podobně jako u git add git reset HEAD soubor # Zruší úpravy souborů pouze v non-staged area, soubory přidané # do staging area a "untracked" ponechá # POZOR na tečku, zruší v non-staged vše, viz git add apod git checkout . git checkout soubor # Zruší úpravy souborů jak v non-staged, tak v staging area # Pouze ale soubory již trackované gitem. Nové soubory ponechá git checkout vetev soubor
git log - výpis předchozích commitů
Příkaz git log
, jak název napovídá, zobrazí historii commitů. Každý commit je identifikován unikátním kódem, který je vygenerován SHA1 algoritmem. Tímto kódem se dá odkazovat na jednotlivé commity. Naštěstí se nemusí psát celý 40-místný kód, ale většinou stačí prvních 6-8 znaků.
# Vypíše informace o commitech, včetně data, zprávy i autora git log # Následující přepínače se dají kombinovat # Poslendí 2 commity, jednořádkový výpis git log -n 2 --oneline # Zobrazí reference na HEAD a větve u jednotlivých commitů git log --decorate # Zobrazí všechny větve a zobrazí ve stromě git log --all --graph # Různé omezení na výpis, # robrazí jen commity splňující 1 a více kritérií git log path/to/file.txt git log --author="pattern" git log --grep="pattern zprávy commitu" --regexp-ignore-case git log --since="YYYY-mm-dd" # nebo --after="YYYY-mm-dd" git log --until="YYYY-mm-dd" # nebo --before="YYYY-mm-dd" # Výpis v rozsahu, lze kombinovat s větvemi, tagy, commity, HEAD... # Všechny následující vypíšou příkazy commity 1364cf a b54afd git log 55aa66..b54afd git log 55aa66..HEAD git log 55aa66..master
git checkout a HEAD reference
Pomocí git log
se dají zjistit informace o starých commitech. Pomocí git checkout
se tyto commity dají prohlížet. Důležité je prvně vysvětlit co je HEAD reference. HEAD je ukazatel na určitý commit většinou však větev, a všechny soubory jsou ve stavu tohoto commitu. Na větev ukazuje proto, že při novém commitu se posouvá automaticky, nemusí se přesouvat. Při vytvoření nového commitu je jeho rodič ten, kam ukazoval HEAD.
Pokud tedy pomocí git checkout se HEAD přesune do staršího commitu, soubory se změní, aby odpovídaly commitu kde je HEAD. Stav, kdy HEAD ukazuje na commit místo na větev se nazývá detached head.
# HEAD se přesune se o 2 commity dozadu vůči aktuálnímu commitu git checkout HEAD~2 # HEAD se přesune se na commit, s kódem 55aa66 git checkout 55aa66 # Pro návrat zpět do původního stavu, tj ukazuje na větev # Dokud nejsou vysvětleny větve, vetev stačí nahradit za master git checkout vetev
Detached HEAD stav po git checkout
checkout jednotlivých souborů
Nemusí se vždy měnit všechny soubory z commitu na starší verzi. Git dokáže vrátit pouze jednotlivé soubory. Při tomto řešení HEAD zůstane na původním místě. Nyní se může klidně vytvořit ze souboru nový commit. Git totiž verzi souboru z minulého commitu umístí přímo do staging area.
# HEAD zůstane, ale původní verze souboru se vloží do stagign area git checkout 55aa66 index.html # Stejná situace jako výše, git checkout vrátí soubor do verze # jako je v master větvi git checkout master index.html
git reset
Příkaz git reset
odebírá soubory ze staging area. Pokud je ale specifikován commit do kterého má být vše resetováno, zruší posledních n commitů. Tato operace není vhodná, pokud již commity jsou pushnuté, protože poté nebude sedět posloupnost a vzniknou konflikty apod. Podle módu (--mixed, --soft, --hard), může git reset přepsat i aktuální úpravy, na to velký pozor, ať se omylem nepřepíší veškeré změny.
# Commity zruší a soubory vloží do "unstaged" stavu # --mixed je defaultní, místo čísla commitu lze použít HEAD~2 apod git reset 55aa66 git reset --mixed 55aa66 # Zruší commit a soubory ponechá ve staging area git reset --soft 55aa66 # Zruší commit a všechny soubory vrátí do původní verze git reset --hard 55a66
Stav po git reset, commity další jsou smazány
Garbage collecting
Při provedení git reset
nejsou staré commity ihned smazány, ale pouze označené ke smazání. Lze je tedy obnovit, ale pouze do doby, než git vyčistí vše a smaže je i fyzicky. K těmto na první pohled ztraceným commitům se dá dostat pomocí příkazu git reflog
. Více v pátém díle.
Podobný scénář nastane při vytvoření commitů v detached HEAD stavu. Nové commity budou v nové větvi, ta ale nemá ale žádnou referenci. Při spuštění garbare collectingu se také smažou. Viz obrázek a ukázka příkazů:
# Zrušení posledních commitů, git je ve stavu viz obrázek výše git reset --hard 55aa66 # Pokud je známo číslo commitu, lze se do něj vrátit git reset b54afd # Vytvoření commitu v detached HEAD stavu git checkout 55aa66 # Nyní jsou vytvořeny/upraveny/smazány nějaké soubory # git commit -a přidá všechny soubory, ušetří příkaz git add . git commit -a -m "This commit will be removed by garbage collector" git checkout master
Následující obrázek není úplně přesný. Pokud přesuneme HEAD zpět na commit b54afd tak git log nám commit dd7216 již neukáže. Pokud by ale na něj ukazovala HEAD, a použijeme přepínač --all tak uvidíme graf podobný tomu na obrázku.
Commit dd7216 vytvořen z detached HEAD stavu,
při dalším spuštění garbage collectingu bude smazán.
Podělte se v komentářích o zkušenosti s Gitem, nebo přidejte tipy k příkazům do dalších článků o gitu.
K tomuto článku již není možné přidávat další komentáře