Přeskočit na hlavní obsah

Pokročilá manipulace s commity

Pomocí „magického“ příkazu git rebase -i lze pořádat, přepisovat, spojovat, dělit nebo mazat commity. Vše, co je níže, přepisuje historii – používejte ideálně jen na vlastní větvi před odesláním na server.

Pozor na přepis historie

Už odeslané commity na server přepisujte jen výjimečně a po domluvě s týmem. Pokud už musíte, používejte git push --force-with-lease (bezpečnější varianta než --force).


Změna pořadí commitů

Cíl: Prohodit pořadí posledních 3 commitů na větvi main.

Postup

git log --oneline --decorate --graph -n 5
* e5e5e5e (HEAD -> main) fix: drobná oprava
* d4d4d4d refactor: úklid kódu
* c3c3c3c feat: přidány utils
* b2b2b2b docs: README
* a1a1a1a init
git rebase -i HEAD~3

Editor otevře todo seznam, kde přeuspořádejte řádky (jen je přemístěte):

Soubor: rebase-todo (před)
pick e5e5e5e fix: drobná oprava
pick d4d4d4d refactor: úklid kódu
pick c3c3c3c feat: přidány utils
Soubor: rebase-todo (po)
pick e5e5e5e fix: drobná oprava
pick c3c3c3c feat: přidány utils
pick d4d4d4d refactor: úklid kódu
Výstup po dokončení rebase
Successfully rebased and updated refs/heads/main.

Ověření:

git log --oneline --decorate --graph -n 5
* e5e5e5e (HEAD -> main) fix: drobná oprava
* c3c3c3c feat: přidány utils
* d4d4d4d refactor: úklid kódu
* b2b2b2b docs: README
* a1a1a1a init

Přepsat commit message

Cíl: Opravit text zprávy u posledního commitu, nebo libovolného z nedávné historie.

Varianta A – poslední commit

git commit --amend -m "fix: opravena chyba s načítáním konfigurace"
[main e5e5e5e] fix: opravena chyba s načítáním konfigurace
Date: Tue Nov 11 10:15:00 2025 +0100
1 file changed, 2 insertions(+), 1 deletion(-)

Varianta B – starší commit přes rebase

git rebase -i HEAD~3

V souboru rebase-todo změňte pick na reword u commitu, jehož zprávu chcete přepsat:

rebase-todo (příklad)
pick e5e5e5e fix: drobná oprava
reword d4d4d4d refactor: úklid kódu
pick c3c3c3c feat: přidány utils

Po uložení se editor zastaví a vyzve k přepsání message. Upravte text, uložte a pokračujte:

git rebase --continue
Successfully rebased and updated refs/heads/main.

Spojit více commitů do jednoho

Cíl: Zkomprimovat několik menších commitů (např. „oprava typo“, „drobná úprava“) do jednoho čistého commitu.

Postup (squash/fixup)

git rebase -i HEAD~3

V rebase-todo nastavte první z vybraných commitů jako pick a ostatní jako squash (sloučit se zachováním zpráv) nebo fixup (sloučit bez jejich zpráv):

rebase-todo (příklad)
pick  c3c3c3c feat: přidány utils
squash d4d4d4d fix: typo
fixup e5e5e5e style: drobnosti

Pokud použijete squash, Git otevře editor pro slučování zpráv. Upravte výslednou message a pokračujte:

git rebase --continue
Successfully rebased and updated refs/heads/main.

Rozdělit commit na více commitů

Cíl: Velký commit rozřezat na několik logických commitů.

Postup (edit + reset + postupné commitování)

git rebase -i HEAD~3

V rebase-todo nastavte u daného commitu edit:

rebase-todo (příklad)
pick  b2b2b2b docs: README
edit c3c3c3c feat: přidány utils (velké změny)
pick d4d4d4d refactor: úklid

Rebase se zastaví na vybraném commitu. Nyní „rozbalíme“ změny zpět do pracovního adresáře:

git reset HEAD^
Unstaged changes after reset:
M src/utils.py
M src/helpers.py

Teď přidávejte změny po částech (např. po souborech nebo konkrétních řádcích) a commitujte:

git add -p src/utils.py
git commit -m "feat(utils): přidán parser konfigurace"

git add -p src/helpers.py
git commit -m "feat(helpers): validace vstupů"

Pak rebase dokončete:

git rebase --continue
Successfully rebased and updated refs/heads/main.

Odstranit commit z historie

Cíl: Vyhodit nežádoucí commit (např. přidaný dočasný soubor).

Varianta A – přes drop v interactive rebase

git rebase -i HEAD~3

V rebase-todo změňte řádek s nežádoucím commitem na drop (nebo ho smažte):

rebase-todo (příklad)
pick a1a1a1a init
drop b2b2b2b chore: dočasný soubor
pick c3c3c3c feat: přidány utils
Výstup po dokončení
Successfully rebased and updated refs/heads/main.

Varianta B – rebase --onto (přeskočení konkrétního commitu)

Řekněme, že chcete odstranit commit BAD uprostřed:

Najděte commit ID před BAD (říkejme mu A), a následně:

git rebase --onto A BAD D

Tím vezmete rozsah (BAD..D] a „přepíšete“ ho na A bez commitu BAD.

Upravit obsah commitu

Cíl: Změnit soubory, které patří do existujícího (staršího) commitu.

Varianta A – poslední commit (amend)

Nejdříve upravte soubory, přidejte je do stacku pomocí git add a následně commitujte:

git commit --amend --no-edit
[main e5e5e5e] fix: opravena chyba s načítáním konfigurace
Date: Tue Nov 11 10:25:00 2025 +0100
1 file changed, 3 insertions(+)

Varianta B – starší commit (edit v rebase)

git rebase -i HEAD~5

V rebase-todo nastavte edit u commitu, jehož obsah chcete měnit. Po zastavení:

Příkazy
# proveďte úpravy souborů
git add -A
git commit --amend --no-edit
git rebase --continue
Výstup po dokončení
Successfully rebased and updated refs/heads/main.

Užitečné tipy
  • Bezpečná záchrana při potížích: kdykoliv můžete použít git rebase --abort a vrátit se do stavu před rebase.
  • Kontrola průběhu: git status během rebase jasně říká, v jaké fázi jste a co udělat dál.

Tabulka pro rebase -i

Akce v rebase-todoVýznam
pickPoužij commit beze změn
rewordZastav se a uprav zprávu commitu
editZastav se a nech měnit obsah commitu
squashSluč s předchozím a spoj zprávy
fixupSluč s předchozím, zahodí zprávu
dropVyhoď commit